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

井字棋(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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:00:34