You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重置汉诺塔游戏及优化JavaScript实现方案咨询

汉诺塔游戏重置方法与代码优化建议

一、重置游戏到初始状态的方法

要实现重置,首先得保存初始状态的独立副本(避免引用关联导致初始值被意外修改),然后编写单独的重置函数恢复盘面:

  • 先定义初始柱子模板:const initialTower = [5, 4, 3, 2, 1];
  • 重置时用展开运算符[...initialTower]创建新数组,确保和原模板无引用关联
  • 重置函数示例:
function resetGame() {
  board = [
    [...initialTower], // 第一个柱子恢复初始状态
    [],                // 第二个柱子清空
    []                 // 第三个柱子清空
  ];
  console.table(board);
}

二、代码优化细节

1. 拆分内部函数,避免重复创建

原arrMove内部的winAndReset、arrayEquals每次调用都会重新定义,将它们移到全局作用域,提升性能且结构更清晰:

// 全局复用的工具函数
function arrayEquals(a, b) {
  return Array.isArray(a) &&
         Array.isArray(b) &&
         a.length === b.length &&
         a.every((val, index) => val === b[index]);
}

function winAndReset() {
  alert("You have won");
  resetGame(); // 获胜后自动触发重置
}

2. 简化盘面拷贝逻辑

原来的嵌套map可以用展开运算符简化,代码更易读:

// 替代双层map的拷贝方式
const newBoard = board.map(tower => [...tower]);

3. 修正移动合法性判断逻辑

原代码在目标柱为空时,会取到undefined导致比较逻辑异常。优化后仅在目标柱有元素时判断大小:

const fromTower = newBoard[oldIndex];
const toTower = newBoard[newIndex];
const movingDisk = fromTower[fromTower.length - 1];

// 合法性校验:源柱不能为空,且目标柱为空/目标柱顶部圆盘更大
if (!movingDisk) {
  alert("Illegal Move: 源柱没有圆盘可移动");
} else if (toTower.length > 0 && movingDisk > toTower[toTower.length - 1]) {
  alert("Illegal Move: 不能把大圆盘放在小圆盘上");
} else {
  toTower.push(fromTower.pop());
}

4. 简化函数调用与命名

  • 将arrMove改名为makeMove,语义更明确
  • 由于board是全局变量,无需每次传参,调用时仅需传入源柱和目标柱索引(比如makeMove(0, 2)表示从第一个柱子移到第三个)

5. 合并获胜判断逻辑

把两个获胜条件合并,代码更简洁:

if (arrayEquals(newBoard[1], initialTower) || arrayEquals(newBoard[2], initialTower)) {
  winAndReset();
}

三、优化后的完整代码

// 初始盘面模板(保存独立副本)
const initialTower = [5, 4, 3, 2, 1];
// 初始化游戏盘面
let board = [
  [...initialTower],
  [],
  []
];

// 重置游戏函数
function resetGame() {
  board = [
    [...initialTower],
    [],
    []
  ];
  console.table(board);
}

// 判断两个数组是否相等的工具函数
function arrayEquals(a, b) {
  return Array.isArray(a) &&
         Array.isArray(b) &&
         a.length === b.length &&
         a.every((val, index) => val === b[index]);
}

// 获胜提示并重置
function winAndReset() {
  alert("You have won");
  resetGame();
}

// 执行移动操作的核心函数
function makeMove(fromIndex, toIndex) {
  // 创建盘面副本,避免直接修改原数组
  const newBoard = board.map(tower => [...tower]);
  const fromTower = newBoard[fromIndex];
  const toTower = newBoard[toIndex];
  const movingDisk = fromTower[fromTower.length - 1];

  // 合法性校验不通过则终止函数
  if (!movingDisk) {
    alert("Illegal Move: 源柱没有圆盘可移动");
    return;
  }
  if (toTower.length > 0 && movingDisk > toTower[toTower.length - 1]) {
    alert("Illegal Move: 不能把大圆盘放在小圆盘上");
    return;
  }

  // 执行合法移动
  toTower.push(fromTower.pop());

  // 检查是否获胜
  if (arrayEquals(newBoard[1], initialTower) || arrayEquals(newBoard[2], initialTower)) {
    winAndReset();
  }

  // 更新全局盘面
  board = newBoard;
  console.table(board);
}

使用说明

  • 重置游戏:直接调用resetGame()
  • 执行移动:比如从第一个柱子移到第三个,调用makeMove(0, 2)(柱子索引从0开始)

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:56:13