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

HTML基础井字棋游戏仅首行获胜有效,其他判定失效求助

井字棋获胜/平局判定失效问题修复

问题现象

实现HTML版井字棋后,仅首行获胜的判定功能正常,其余获胜位置及平局判定均失效;X与O落子功能无异常,调整获胜组合顺序仅能改变可识别的获胜状态,无法解决所有情况;将解构变量由const改为var也未修复问题。

问题根源

  1. 循环逻辑错误:原代码在遍历获胜组合时,每检查一个组合未命中就立即判断平局并终止循环,导致后续获胜组合无法被检查,且存在平局误判的情况。
  2. 事件监听移除无效:移除监听时传入新的匿名函数,与原监听函数引用不一致,无法真正禁止后续落子。
  3. 模板字符串语法错误:插值表达式中$与{之间存在空格,导致变量无法正确解析。

修复后的完整代码

HTML

<div class="board">
  <div class="square" data-index="0"></div>
  <div class="square" data-index="1"></div>
  <div class="square" data-index="2"></div>
  <div class="square" data-index="3"></div>
  <div class="square" data-index="4"></div>
  <div class="square" data-index="5"></div>
  <div class="square" data-index="6"></div>
  <div class="square" data-index="7"></div>
  <div class="square" data-index="8"></div>
</div>

CSS

.board {
  display: flex;
  flex-wrap: wrap;
  width: 300px;
  height: 300px;
  border: 1px solid #000;
}

.square {
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  font-weight: bold;
  cursor: pointer;
}

.x {
  color: #f00;
}

.o {
  color: #00f;
}

JavaScript

const board = document.querySelector('.board');
let turn = 'X';

// 提取命名函数,方便移除监听
function handleSquareClick(e) {
  const square = e.target;

  if (square.innerText) {
    return; // 已落子,不处理
  }
  square.innerText = turn;
  if (turn === 'X') {
    square.classList.add('x');
    turn = 'O';
  } else {
    square.classList.add('o');
    turn = 'X';
  }
  checkWin(); // 每步后检查胜负
}

board.addEventListener('click', handleSquareClick);

function checkWin() {
  const squares = document.querySelectorAll('.square');
  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]  // 右上到左下对角线
  ];

  let winner = null;
  // 先遍历所有获胜组合,检查是否有赢家
  for (const combo of winningCombos) {
    const [a, b, c] = combo;
    const value = squares[a].innerText;
    if (value && value === squares[b].innerText && value === squares[c].innerText) {
      winner = value;
      break;
    }
  }

  if (winner) {
    alert(`Player ${winner} wins!`);
    board.removeEventListener('click', handleSquareClick); // 正确移除监听
    return;
  }

  // 无赢家时检查是否平局
  if (Array.from(squares).every(s => s.innerText)) {
    alert('It\'s a draw!');
    board.removeEventListener('click', handleSquareClick);
  }
}

修复说明

  1. 重构循环逻辑:先完整遍历所有获胜组合确认是否有赢家,无赢家时再检查平局,避免提前终止循环导致的判定遗漏。
  2. 命名事件处理函数:将点击事件的处理逻辑提取为handleSquareClick,确保移除监听时使用相同的函数引用,真正禁止后续落子。
  3. 修正模板字符串:移除$与{之间的空格,确保变量插值正常工作。

内容的提问来源于stack exchange,提问作者calebhk98

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:25:14