如何用JavaScript实现井字棋回合切换?Oden项目技术求助
井字棋回合切换问题修复方案
核心问题分析
你的代码存在几个关键问题导致回合切换失效:
- 每次点击重置控制器状态:在点击事件内重复调用
displayController()创建新实例,会将currentPlayer每次都重置为player1,永远无法切换到player2。 - 标记未关联当前玩家:固定设置单元格内容为"X",没有根据当前玩家动态切换标记。
- 单元格占用判断逻辑错误:混用
textContent和value判断单元格状态,逻辑不一致。 - 模块返回值冗余:
markBoard返回自身函数,无实际作用。
修正后的完整代码
// 定义玩家对象(根据你的实际需求调整) const player1 = { mark: "X", name: "玩家1" }; const player2 = { mark: "O", name: "玩家2" }; // 封装状态的displayController(单例模式) const displayController = (() => { let currentPlayer = player1; const switchTurn = () => { currentPlayer = currentPlayer === player1 ? player2 : player1; }; const getCurrentPlayer = () => currentPlayer; return { switchTurn, getCurrentPlayer }; })(); // 棋盘点击处理逻辑 const markBoard = (() => { const cells = document.querySelectorAll('.test'); cells.forEach(cell => { cell.addEventListener('click', (e) => { const targetCell = e.target; // 判断单元格是否为空(去除空格干扰) if (targetCell.textContent.trim() === "") { // 获取当前玩家并设置标记 const activePlayer = displayController.getCurrentPlayer(); targetCell.textContent = activePlayer.mark; // 切换回合 displayController.switchTurn(); // 提示下一回合玩家 alert(`${displayController.getCurrentPlayer().name}的回合`); } else { alert('请点击其他空格子'); } }); }); })();
关键修正说明
- 控制器状态持久化:用立即执行函数(IIFE)封装
displayController,确保currentPlayer只会初始化一次,不会被重复调用重置。 - 暴露必要方法:新增
getCurrentPlayer方法,让外部能获取当前玩家的标记和名称,实现动态标记和提示。 - 复用控制器实例:
markBoard中直接使用全局的displayController单例,不再每次点击创建新实例。 - 统一状态判断:用
textContent.trim()判断单元格是否为空,避免空格导致的误判。 - 动态标记与提示:根据当前玩家的标记设置单元格内容,提示信息也关联玩家名称,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Daniel Species
相关产品推荐
相关产品推荐

