如何实现井字棋的三连检测与平局判定功能?
井字棋三连检测与平局判断实现方案
核心关注要点
- 固定获胜组合:井字棋的获胜线是固定的8种(3横、3竖、2斜),直接针对这些组合做检查是最高效的思路,无需让格子检测相邻元素,避免逻辑复杂和遗漏情况。
- 状态数据同步:确保每个格子的状态(是否被占用、当前符号)能被快速读取,你的
gameboard_field目前只记录了taken,需要补充存储当前格子的符号。 - 触发时机:每次玩家落子后立即执行胜负检测,确认无胜负后再切换玩家,避免无效操作。
可落地实现步骤
1. 完善格子状态存储
修改gameboard_field构造函数,新增sign属性记录当前格子的符号,同时调整落子逻辑,落子后先检测胜负再切换玩家:
function gameboard_field(field) { this.field = field; this.taken = false; this.sign = ''; // 新增:存储格子的符号 let self = this; this.field.onclick = function() { if (self.taken === false) { self.field.innerHTML = t; self.taken = true; self.sign = t; // 落子后同步符号 // 先检测胜负 if (checkWin()) { alert(`玩家${t}获胜!`); resetGame(); return; } if (checkDraw()) { alert('平局!'); resetGame(); return; } // 再切换玩家 t = t === player1.sign ? player2.sign : player1.sign; } }; };
2. 预定义所有获胜组合
根据gameboard数组的索引(0-8对应3x3格子的顺序),定义所有可能的获胜线:
const winCombos = [ [0,1,2], [3,4,5], [6,7,8], // 横向三连 [0,3,6], [1,4,7], [2,5,8], // 纵向三连 [0,4,8], [2,4,6] // 斜向三连 ];
3. 实现三连检测函数
遍历所有获胜组合,检查组合内的三个格子是否都被占用且符号一致:
function checkWin() { for (let combo of winCombos) { const [a, b, c] = combo; if (gameboard[a].taken && gameboard[b].taken && gameboard[c].taken) { if (gameboard[a].sign === gameboard[b].sign && gameboard[b].sign === gameboard[c].sign) { return true; } } } return false; }
4. 实现平局检测函数
检查所有格子是否都被占用(此时已确认无获胜情况,所以直接判断全满即可):
function checkDraw() { return gameboard.every(field => field.taken); }
5. 可选:添加游戏重置功能
方便胜负或平局后重新开始游戏:
function resetGame() { gameboard.forEach(field => { field.taken = false; field.sign = ''; field.field.innerHTML = ''; }); t = player1.sign; // 重置为玩家1先手 }
为什么不推荐邻居检测?
邻居检测需要处理横向、纵向、斜向的不同相邻逻辑,容易遗漏斜向的情况,且代码复杂度更高。而预定义获胜组合的方式逻辑清晰,执行效率高,完全覆盖所有可能的获胜场景。
内容的提问来源于stack exchange,提问作者Miloš Milosavljević
相关产品推荐
相关产品推荐

