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

C++井字棋游戏问题:X获胜后仍允许O继续落子

解决井字棋游戏中获胜后仍允许落子的逻辑异常

嘿,我来帮你搞定这个井字棋的小bug!你遇到的问题核心是胜负校验的时机不对——玩家落子后没有立刻检查是否获胜,就直接切换到下一个玩家了,所以X赢了之后O还能多走一步。再加上你代码里的turn变量定义位置错了,每次循环都会重置,这也会影响玩家交替的逻辑。

问题根源拆解

从你贴的代码片段能看到:

  1. int turn = 0;是在do-while循环内部定义的,这意味着每次循环都会把turn重置为0,根本没法正确实现X和O的交替落子。
  2. 没有在玩家落子成功后立即校验胜负,导致就算有人赢了,程序还是会继续执行下一个玩家的输入逻辑。

具体修复方案

我给你整理了完整的修正代码,关键改动点都标出来了:

#include <iostream>
using namespace std;

// 定义棋盘
char board[3][3] = {{'*', '*', '*'}, {'*', '*', '*'}, {'*', '*', '*'}};

// 胜负校验函数:检查当前玩家是否获胜
bool checkWin(char player) {
    // 检查三行
    for (int i = 0; i < 3; i++) {
        if (board[i][0] == player && board[i][1] == player && board[i][2] == player)
            return true;
    }
    // 检查三列
    for (int i = 0; i < 3; i++) {
        if (board[0][i] == player && board[1][i] == player && board[2][i] == player)
            return true;
    }
    // 检查两条对角线
    if (board[0][0] == player && board[1][1] == player && board[2][2] == player)
        return true;
    if (board[0][2] == player && board[1][1] == player && board[2][0] == player)
        return true;
    return false;
}

// 打印棋盘
void printBoard() {
    cout << "\nCurrent Board:\n";
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << board[i][j] << " ";
        }
        cout << endl;
    }
}

int main() {
    int row, column;
    int turn = 0; // 把turn移到循环外,保证玩家交替正确
    bool gameOver = false;

    do {
        printBoard();
        if (turn % 2 == 0) {
            // X玩家落子逻辑
            cout << "\nPlayer X, enter Row and Column (1-3): ";
            cin >> row >> column;
            // 校验输入合法性(范围+位置是否为空)
            while (row < 1 || row > 3 || column < 1 || column > 3 || board[row-1][column-1] != '*') {
                cout << "Invalid move! Try again: ";
                cin >> row >> column;
            }
            board[row-1][column-1] = 'X';
            
            // 落子后立即检查胜负
            if (checkWin('X')) {
                printBoard();
                cout << "\nPlayer X wins! 🎉" << endl;
                gameOver = true;
                break; // 直接跳出循环,不让O继续操作
            }
        } else {
            // O玩家落子逻辑
            cout << "\nPlayer O, enter Row and Column (1-3): ";
            cin >> row >> column;
            while (row < 1 || row > 3 || column < 1 || column > 3 || board[row-1][column-1] != '*') {
                cout << "Invalid move! Try again: ";
                cin >> row >> column;
            }
            board[row-1][column-1] = 'O';
            
            if (checkWin('O')) {
                printBoard();
                cout << "\nPlayer O wins! 🎉" << endl;
                gameOver = true;
                break;
            }
        }
        turn++;
        
        // 检查平局(棋盘已满且无人获胜)
        bool isDraw = true;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == '*') {
                    isDraw = false;
                    break;
                }
            }
            if (!isDraw) break;
        }
        if (isDraw) {
            printBoard();
            cout << "\nIt's a draw! 🤝" << endl;
            gameOver = true;
        }
    } while (!gameOver);

    return 0;
}

关键修复点说明

  • 把turn变量移到循环外:这样每次循环turn会递增,正确实现X和O的交替落子。
  • 落子后立即校验胜负:一旦检测到当前玩家获胜,就设置gameOver为true并跳出循环,直接终止游戏,不让下一个玩家有操作机会。
  • 增加平局检测:避免棋盘满了之后程序还继续循环等待输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:58:21