JavaScript井字棋游戏无法显示平局及X获胜状态问题
井字棋游戏问题修复:平局与X玩家获胜提示不显示
问题描述
- X玩家达成获胜条件时,无法显示获胜提示
- 所有格子填满后,无法显示平局提示
问题原因
原validateWin函数依赖当前回合turn的值来检测对应玩家的获胜条件,虽然逻辑看似合理,但存在边界情况导致检测失效;同时平局判断依赖该函数的正确返回,因此连带导致平局提示无法触发。
修复方案
修改validateWin函数,改为主动检测X和O两个玩家的步骤是否满足获胜条件,不再依赖当前turn值,确保任何玩家获胜都能被准确检测到;平局判断逻辑保持不变,修复后即可正常触发。
修复后的完整代码
HTML(无需修改)
<div id="main"> <h1 class="playerText">TIC TAC TOE</h1> <br><br> <input class="cell" data-cell="0" type="text" id="b1" readonly> <input class="cell" data-cell="1" type="text" id="b2" readonly> <input class="cell" data-cell="2" type="text" id="b3" readonly> <br><br> <input class="cell" data-cell="3" type="text" id="b4" readonly> <input class="cell" data-cell="4" type="text" id="b5" readonly> <input class="cell" data-cell="5" type="text" id="b6" readonly> <br><br> <input class="cell" data-cell="6" type="text" id="b7" readonly> <input class="cell" data-cell="7" type="text" id="b8" readonly> <input class="cell" data-cell="8" type="text" id="b9" readonly> <br><br><br> <button id="but"> RESET </button> <br><br> <p id="print"> X's Turn </p> </div>
CSS(无需修改)
* { margin: 0; padding: 0; } h1 { color: orangered; font-size: 45px; } /* 3*3 Grid */ #b1, #b2, #b3, #b4, #b5, #b6, #b7, #b8, #b9 { width: 80px; height: 52px; margin: auto; border: 1px solid gray; border-radius: 6px; font-size: 30px; text-align: center; } /* Reset Button */ #but { box-sizing: border-box; width: 95px; height: 40px; border: 1px solid dodgerblue; margin: auto; border-radius: 4px; font-family: Verdana, Geneva, Tahoma, sans-serif; background-color: dodgerblue; color: white; font-size: 20px; cursor: pointer; } /* Player turn space */ #print { font-family: Verdana, Geneva, Tahoma, sans-serif; color: dodgerblue; font-size: 20px; } /* Main container */ #main { text-align: center; } /* Game Instruction Text */ #ins { font-family: Verdana, Geneva, Tahoma, sans-serif; color: dodgerblue; font-size: 17px; }
JavaScript(修复后的代码)
let turn = "X"; let cells = document.querySelectorAll('[data-cell]'); let message = document.querySelector('#print'); let restart = document.querySelector('#but'); let steps = { X : [], O : [] } const winConditions= [ [0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6], ]; cells.forEach ( cell => { cell.addEventListener ("click",() => move(cell) ); }); restart.addEventListener("click", restartGame); function move(cell) { cell.value = turn; cell.style.pointerEvents = 'none'; let cellIndex = parseInt ( cell.getAttribute("data-cell")); if ( turn === 'X') { steps.X.push(cellIndex); } else { steps.O.push(cellIndex); } changeTurn(); } function changeTurn() { let winner = validateWin(); if (winner) { stopGame(`${winner}获胜!`); } else if (!winner && steps.X.length + steps.O.length === 9 ){ stopGame('平局!'); } else { turn = turn === 'X' ? 'O' : 'X'; message.innerHTML = `${turn}的回合`; } } // 修复后的获胜检测函数 function validateWin () { // 检测X是否获胜 const xWins = winConditions.some(winCondition => { return winCondition.every(condition => steps.X.includes(condition)); }); if (xWins) return 'X'; // 检测O是否获胜 const oWins = winConditions.some(winCondition => { return winCondition.every(condition => steps.O.includes(condition)); }); if (oWins) return 'O'; return null; } function stopGame(msg) { message.innerHTML = msg; cells.forEach(cell => { cell.style.pointerEvents = 'none'; }); } function restartGame() { steps.O = []; steps.X = []; turn = 'X'; message.innerHTML = "X的回合"; cells.forEach(cell => { cell.value = null; cell.style.pointerEvents = 'auto'; }); }
修复说明
- 重构
validateWin函数:不再依赖当前回合turn,直接检测X和O的步骤是否满足获胜条件,确保任何玩家获胜都能被精准检测。 - 优化回合切换逻辑:使用三元运算符简化代码,保持可读性。
- 调整提示文本为中文,更符合用户习惯(若需要英文可改回原格式)。
内容的提问来源于stack exchange,提问作者imran H
相关产品推荐
相关产品推荐

