C++井字棋游戏问题:X获胜后仍允许O继续落子
解决井字棋游戏中获胜后仍允许落子的逻辑异常
嘿,我来帮你搞定这个井字棋的小bug!你遇到的问题核心是胜负校验的时机不对——玩家落子后没有立刻检查是否获胜,就直接切换到下一个玩家了,所以X赢了之后O还能多走一步。再加上你代码里的turn变量定义位置错了,每次循环都会重置,这也会影响玩家交替的逻辑。
问题根源拆解
从你贴的代码片段能看到:
int turn = 0;是在do-while循环内部定义的,这意味着每次循环都会把turn重置为0,根本没法正确实现X和O的交替落子。- 没有在玩家落子成功后立即校验胜负,导致就算有人赢了,程序还是会继续执行下一个玩家的输入逻辑。
具体修复方案
我给你整理了完整的修正代码,关键改动点都标出来了:
#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
相关产品推荐
相关产品推荐

