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

JavaScript井字棋Draw函数问题:获胜时仍判定平局求助

解决井字棋最后一步获胜时同时触发平局判定的问题

问题根源

当前代码中,每次落子后会依次执行checkWin()和draw():

  • checkWin()仅修改页面提示文本,没有返回游戏是否结束的状态
  • 当最后一步同时满足"获胜"和"棋盘填满"两个条件时,draw()会无视已获胜的结果,依然输出平局

修复方案

  1. 让checkWin()返回布尔值,标记是否有玩家获胜
  2. 落子后先检查是否获胜,只有未获胜且棋盘填满时才判定平局
  3. 添加游戏结束状态锁,避免获胜/平局后继续落子

修改后的完整JavaScript代码

const clear = document.getElementById("clear");
const message = document.querySelector('h2');
const allDiv = document.querySelectorAll('#board div');
const squares = Array.from(allDiv);
let player = 'O';
let isGameOver = false; // 标记游戏是否结束

// 用数组存储所有获胜组合,简化判断逻辑
const winCombos = [
  [0,1,2], [3,4,5], [6,7,8], // 横向
  [0,3,6], [1,4,7], [2,5,8], // 纵向
  [0,4,8], [2,4,6] // 斜向
];

function board (){
    squares.forEach(function(e, i){
        squares[i].onclick = ()=>{
            // 游戏结束或格子已被占用时禁止落子
            if(isGameOver || squares[i].textContent !== '') return;
            
            // 切换玩家并落子
            player = player === 'O' ? 'X' : 'O';
            squares[i].textContent = player;
            // 更新回合提示
            message.textContent = `It's ${player === 'X' ? 'O' : 'X'}'s turn`;
            
            // 先检查是否获胜
            const hasWon = checkWin();
            if(hasWon){
                isGameOver = true;
                return;
            }
            // 未获胜时检查是否平局
            checkDraw();
        }
    });
}
board();

function checkWin(){
    // 遍历所有获胜组合
    for(const combo of winCombos){
        const [a,b,c] = combo;
        const val = squares[a].textContent;
        // 判断当前组合是否全部为同一个玩家且非空
        if(val !== '' && val === squares[b].textContent && val === squares[c].textContent){
            message.textContent = `${val} Wins`;
            return true;
        }
    }
    return false;
}

clear.onclick = ()=>{
    // 重置棋盘
    squares.forEach(function(e,i){
        squares[i].textContent = '';
        squares[i].style.color = '';
    });
    // 重置游戏状态
    isGameOver = false;
    player = 'O';
    message.textContent = "It's X's turn!";
};

function checkDraw(){
    // 检查所有格子是否已填满
    const isBoardFull = squares.every(square => square.textContent !== '');
    if(isBoardFull){
        message.textContent = 'Tie Game!';
        console.log('tie');
        isGameOver = true;
    }
}

关键修改说明

  1. 新增isGameOver状态变量:控制游戏结束后是否允许继续落子,避免无效操作
  2. 重构checkWin():
    • 用数组存储所有获胜组合,大幅减少重复代码
    • 返回布尔值表示是否有玩家获胜,让后续逻辑能根据结果分支执行
  3. 调整落子逻辑顺序:先判断获胜,只有未获胜时才检查平局
  4. 优化checkDraw():用Array.every()简化棋盘填满的判断逻辑
  5. 重置按钮补充状态重置:点击"Play Again"时重置游戏状态,确保新游戏能正常开始

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:12:04