井字棋(Tic-Tac-Toe)游戏平局得分异常问题求助
井字棋平局得分异常修复
我开发了一款井字棋(Tic-Tac-Toe)游戏,用于记录游戏获胜及平局的得分。目前遇到一个问题:每当游戏出现平局时,平局得分会显示为2,而预期应为1。推测问题出在else语句中,该语句会执行两次,尝试多种方法仍未解决,请问该如何修复?
相关代码
JavaScript 代码
let button = document.querySelectorAll(".box"); let resetbtn = document.querySelector(".reset"); let textValue = "X"; let winMsg = document.querySelector(".msg"); let newbtn = document.querySelector(".new"); let moveCount = 0; let scoreX = 0; let scoreO = 0; let tie = 0; let scoreOfX = document.querySelector(".score-X"); let scoreOfO = document.querySelector(".score-O"); const tieResult = document.querySelector(".score-draw"); const winPatterns = [ [0,1,2], [0,3,6], [0,4,8], [1,4,7], [2,5,8], [2,4,6], [3,4,5], [6,7,8], ]; const resetgame = ()=>{ moveCount = 0; textValue = "X"; enableBox(); winMsg.innerText=""; newbtn.classList.add("hide"); }; button.forEach((box) =>{ box.addEventListener("click", ()=>{ if(textValue === "X"){ textValue = "O"; box.innerText ="X"; box.style.color="green"; winMsg.innerText = "Player(O) " ; newbtn.classList.add("hide"); }else{ textValue = "X"; box.innerText = "O"; box.style.color="red"; winMsg.innerText = "Player(X) " ; newbtn.classList.add("hide"); } box.disabled =true; moveCount++; console.log(moveCount, box.innerText ); checkWinner(); }); }); const disabledBox =()=>{ for(let box of button){ box.disabled=true; }}; const enableBox =()=>{ for(let box of button){ box.disabled=false; box.innerText=""; } } const showWinner = (winner)=>{ winMsg.innerText=`Congratulations Winner is ${winner}`; newbtn.classList.remove("hide"); if(winner === "X"){ scoreX ++; scoreOfX.innerText = scoreX; }else{ scoreO++; scoreOfO.innerText = scoreO; } disabledBox(); }; const checkDraw = (moveCount)=>{ winMsg.innerText="Game was Draw! Play Again"; newbtn.classList.remove("hide"); disabledBox(); } const checkWinner = ()=>{ for(let pattern of winPatterns){ let pos1 = button[pattern[0]].innerText; let pos2 = button[pattern[1]].innerText; let pos3 = button[pattern[2]].innerText; if(pos1!= "" && pos2!= "" && pos3!=""){ if(pos1 === pos2 && pos2 === pos3){ showWinner(pos1); }else{ if(pos1 !== pos2 && pos2 !== pos3 ){ if(moveCount === 9){ checkDraw(moveCount); tie ++; tieResult.innerText = tie; } } } } } }; newbtn.addEventListener("click",resetgame); resetbtn.addEventListener("click",()=>{ console.log("reset"); scoreO = 0 ; scoreOfO.innerText = scoreO; scoreX = 0 ; scoreOfX.innerText = scoreX; tie = 0; tieResult.innerText = tie; resetgame(); });
HTML 代码
<main> <h1>Tic Tac Toe </h1> <div> <p class="msg"></p> <button class="new hide"> New Game </button> </div> <div class="container"> <div class="game"> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> </div> </div> <div class="elements"> <div class="scores1"> <h3 class="score-X">0</h3> <h2 class="play-x">Player X</h2> </div> <div class="scores2"> <h3 class="score-O">0</h3> <h2 class="play-o">Player O</h2> </div> <div class="scores3"> <h3 class="score-draw">0</h3> <h2 class="play-draw">Tie</h2> </div> </div> <button class="reset">Reset Button</button> </main>
问题根源
问题出在checkWinner函数的循环逻辑中:当游戏平局(moveCount=9)时,代码会遍历所有8种获胜模式,只要某一组模式不满足获胜条件(即pos1 !== pos2 && pos2 !== pos3),就会执行一次tie++。平局场景下会有多个模式符合该条件,导致平局得分被多次累加,最终显示为2甚至更高。
修复方案
调整checkWinner函数的逻辑,将平局判断移到循环外部,确保只在确认没有获胜者且棋盘已满时,才执行一次平局得分累加:
const checkWinner = ()=>{ let hasWinner = false; // 先遍历所有获胜模式,检查是否有获胜者 for(let pattern of winPatterns){ let pos1 = button[pattern[0]].innerText; let pos2 = button[pattern[1]].innerText; let pos3 = button[pattern[2]].innerText; if(pos1!= "" && pos2!= "" && pos3!=""){ if(pos1 === pos2 && pos2 === pos3){ showWinner(pos1); hasWinner = true; break; // 找到获胜者后立即跳出循环,避免无效遍历 } } } // 循环结束后,确认无获胜者且棋盘已满时,处理平局 if(!hasWinner && moveCount === 9){ checkDraw(moveCount); tie ++; tieResult.innerText = tie; } };
关键修改点
- 新增
hasWinner变量标记是否出现获胜者 - 找到获胜者后立即跳出循环,减少不必要的遍历
- 将平局判断逻辑移到循环外部,确保平局得分只累加一次
内容的提问来源于stack exchange,提问作者Soumita Bandyo
相关产品推荐
相关产品推荐

