NPuzzle Class(npuzzle.js)を使ったデモです。
steps: 0/0
inversion number: 19
Manhattan distance: 19
jQuery(function($) { const np = new NPuzzle(); const init = () => { $('#frame').empty(); for (let i = 0; i < np.length; i++) { if (i != 0 && i % np.w == 0) { $('#frame').append($('<br>')); } $('#frame').append($('<button>')); } update(); }; const update = () => { $('#frame button').each(function(i) { $(this).text(np.block[i]); $(this).css('visibility', i == np.blank ? 'hidden' : 'visible'); }); $('#p1').text(`inversion number: ${np.inv()}`); $('#p2').text(`Manhattan distance: ${np.heuristic(np.block)}`); }; $('#frame').on('click', 'button', function() { if (np.step(np.indexOf($(this).text() | 0))) { update(); } }); $('#shuff').on('click', () => { $('#p0').text('steps: 0/0'); np.shuffle(); update(); }); $('#solve').on('click', () => { if (!np.solvable()) { $('#p0').text('solver: unsolvable!'); return; } $('#sel,#shuff,#solve,#app').prop('disabled', true); np.easy_solver().then((p) => { const r = NPuzzle.get_actions(p); const t = r.length; NPuzzle.animate(r, 150, (a) => { np.step(a); update(); $('#p0').text(`steps: ${r.length}/${t}`); }, () => { $('#sel,#shuff,#solve,#app').prop('disabled', false); }); }); }); $('#app').on('click', () => { try { np.assign(JSON.parse($('#pat').val())); update(); } catch(e) { $('#p0').text(e.message); } }); $('#sel').on('change', () => { np.init(...JSON.parse($('#sel').val())); init(); }).trigger('change'); });