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

井字棋重启后X需走两步才切换至O的问题排查

井字棋重启后落子切换异常问题修复

问题描述

给井字棋添加重启功能后,出现如下异常:X获胜后点击重启按钮,默认X为先手,但需要X连续走两步才会切换到O落子。通过DevTools能看到重启后board元素带有x类,但X走棋后并未切换至O回合。

相关代码:

const board = document.getElementById('board')
const cell = document.querySelectorAll('.cell')
const displayOutcome = document.getElementById('display-outcome')
const winningMessge = document.getElementById('winning-message')
const restart = document.getElementById('restart')
let nextTurn = 'x'
const winningCombos = [
  [0,1,2],
  [3,4,5],
  [6,7,8],
  [0,3,6],
  [1,4,7],
  [2,5,8],
  [0,4,8],
  [2,4,6]
]

restartGame()

board.addEventListener('click', (e) => {
  let icon = document.createElement('i')
  
  if (e.target.classList.contains('cell')) {

    if (board.classList.contains('x')) {
      icon.classList.add('fa-solid', 'fa-x')
      e.target.appendChild(icon)
      e.target.classList.add('x')
    }

    if (board.classList.contains('o')) {
      icon.classList.add('fa-solid', 'fa-o')
      e.target.appendChild(icon)
      e.target.classList.add('o')
    }
  }

  if (isDraw()) {
    winningMessge.innerText = 'Draw!'
    displayOutcome.classList.add('show')
  }

  if (checkWinner(nextTurn)) {
    winningMessge.innerText = `${nextTurn}'s Wins`
    displayOutcome.classList.add('show')
  }
  
  changeTurns()
  
  console.log(nextTurn)

})

function changeTurns() {
  if (nextTurn === 'x') {
    nextTurn = 'o'
    board.classList.replace('x', 'o')
  } else {
    nextTurn = 'x'
    board.classList.replace('o', 'x')
  }
}

function checkWinner (nextTurn) {
  return winningCombos.some(combo => {
    return combo.every(index => {
      return cell[index].classList.contains(nextTurn) 
    })
  })
}

function isDraw() {
  return [...cell].every(cell => {
    return cell.classList.contains('x') || cell.classList.contains('o')
  })
}

function restartGame() {
  cell.forEach(cell => {
    cell.innerHTML = ''
    displayOutcome.classList.remove('show')
    cell.classList.remove('o', 'x')
    board.classList.remove('o', 'x')
    board.classList.add('x')
  })
}


restart.addEventListener('click', restartGame)

问题原因

重启函数只重置了board的class属性,但没有同步更新全局变量nextTurn。上一局X获胜后,changeTurns()已经把nextTurn改成了'o',重启后nextTurn依然是'o'。此时X走棋后调用changeTurns(),会把nextTurn从'o'切回'x',导致需要X再走一步才会轮到O。

修复方案

在restartGame函数中添加对nextTurn的重置,让它和board的class保持一致,同时优化代码逻辑(把displayOutcome.classList.remove('show')移出循环,避免重复执行):

function restartGame() {
  // 清空所有单元格内容和标记
  cell.forEach(cell => {
    cell.innerHTML = ''
    cell.classList.remove('o', 'x')
  })
  // 隐藏结果弹窗
  displayOutcome.classList.remove('show')
  // 重置棋盘的先手标记
  board.classList.remove('o', 'x')
  board.classList.add('x')
  // 关键:同步重置先手变量
  nextTurn = 'x'
}

内容的提问来源于stack exchange,提问作者Joe.sexton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:45:05