数字华容道

移动数字,把 1 到 8 排回正确位置。每局从完成状态打乱,保证可解;记录本局步数。离线运行。

适配设备:Pro

作者:ccicc.icu

下载量:6 · 点赞:0

可信源码风险提示:保存或下载前请阅读源码和权限声明。
SHA-256a4554d142a747c301a9d343aad1bf3c8ec059dac2349a0cab10fa6787842acd1
const solved = [1, 2, 3, 4, 5, 6, 7, 8, 0];

function neighbors(index) {
  const row = Math.floor(index / 3);
  const col = index % 3;
  const result = [];
  if (row > 0) result.push(index - 3);
  if (row < 2) result.push(index + 3);
  if (col > 0) result.push(index - 1);
  if (col < 2) result.push(index + 1);
  return result;
}

function shuffled() {
  const board = solved.slice();
  let blank = 8;
  let previous = -1;
  for (let i = 0; i < 40; i++) {
    const choices = neighbors(blank).filter(index => index !== previous);
    const next = choices[Math.floor(Math.random() * choices.length)];
    board[blank] = board[next];
    board[next] = 0;
    previous = blank;
    blank = next;
  }
  if (board.every((value, index) => value === solved[index])) return shuffled();
  return { board, moves: 0, done: false };
}

const game = ui.signal(shuffled());
function move(index) {
  const old = game.get();
  if (old.done) return;
  const blank = old.board.indexOf(0);
  if (neighbors(blank).indexOf(index) < 0) return;
  const board = old.board.slice();
  board[blank] = board[index];
  board[index] = 0;
  game.set({ board, moves: old.moves + 1,
    done: board.every((value, position) => value === solved[position]) });
}

ui.showHeader(false);
ui.render(() => {
  const state = game.get();
  const rows = [];
  for (let row = 0; row < 3; row++) {
    const buttons = [];
    for (let col = 0; col < 3; col++) {
      const index = row * 3 + col;
      const number = state.board[index];
      buttons.push(ui.button(number ? String(number) : ' ', () => move(index), {
        id: 'tile-' + index, height: 76, size: 31, lines: 1,
        background: number ? '#1d6e91' : '#171b1e'
      }));
    }
    rows.push(ui.row(buttons, { id: 'row-' + row, gap: 6 }));
  }
  return ui.column([
    ui.heading('数字华容道', { id: 'title', size: 29, lines: 1 }),
    ui.text(state.done ? '完成!用了 ' + state.moves + ' 步' : '移动数字,还原 1 到 8',
      { id: 'status', size: 20, lines: 1, color: state.done ? '#6fd4a3' : '#c1cbd1' }),
    ui.column(rows, { id: 'board', gap: 6 }),
    ui.text('步数 ' + state.moves, { id: 'moves', size: 19, lines: 1, color: '#aebdc6' }),
    ui.row([
      ui.button('重新打乱', () => game.set(shuffled()),
        { id: 'restart', height: 54, lines: 1, background: '#16845b' }),
      ui.button('退出', () => script.exit(),
        { id: 'exit', height: 54, lines: 1, background: '#34373d' })
    ], { id: 'actions', gap: 8 })
  ], { id: 'game', gap: 9 });
});