C++实现双人井字棋(TicTacToe)出现无限循环问题求助
Bug根因分析
- 局部变量未初始化
Choix()函数中定义的int a未初始化,C++栈上的局部非静态变量默认值为内存随机垃圾值,若随机值刚好落在1~9区间内,while(a<1||a>9)的循环条件直接不成立,函数不会等待用户输入就直接返回,主循环持续空转表现为无限循环。你添加system("pause")后强制每次循环暂停,刚好给了输入逻辑执行的机会,属于偶然生效的临时方案,没有解决核心问题。 - 无效输入逻辑错误
当用户输入的数字在1~9区间,但对应格子已经被X/O占用时,代码进入else分支输出错误提示后直接调用Tour()切换玩家,既没有重置a的值让循环继续等待用户重新输入,还错误切换了回合玩家,会导致后续逻辑完全混乱。 - 其他隐藏逻辑缺陷(不直接导致无限循环,但影响功能)
Win()函数中X玩家和O玩家获胜都返回1,主函数中判断O获胜的Win()==2分支永远不会触发,O胜利时会错误显示玩家1获胜。- 主循环逻辑顺序错误,落子后先切换玩家再判断胜负,会导致获胜玩家判定错位。
修复建议
1. 修复Choix函数的变量初始化和输入逻辑
void Choix() { int a = 0; // 初始化a为0,保证必然进入循环 while(a<1||a>9) { cout << "Choisis une case pour jouer: "; cin >> a; if (a==1 && jeu[0][0]!= 'X' && jeu[0][0]!= 'O') jeu[0][0]=joueur; else if (a==2 && jeu[0][1]!= 'X' && jeu[0][1]!= 'O') jeu[0][1]=joueur; else if (a==3 && jeu[0][2]!= 'X' && jeu[0][2]!= 'O') jeu[0][2]=joueur; else if (a==4 && jeu[1][0]!= 'X' && jeu[1][0]!= 'O') jeu[1][0]=joueur; else if (a==5 && jeu[1][1]!= 'X' && jeu[1][1]!= 'O') jeu[1][1]=joueur; else if (a==6 && jeu[1][2]!= 'X' && jeu[1][2]!= 'O') jeu[1][2]=joueur; else if (a==7 && jeu[2][0]!= 'X' && jeu[2][0]!= 'O') jeu[2][0]=joueur; else if (a==8 && jeu[2][1]!= 'X' && jeu[2][1]!= 'O') jeu[2][1]=joueur; else if (a==9 && jeu[2][2]!= 'X' && jeu[2][2]!= 'O') jeu[2][2]=joueur; else { cout<<"Invalide.\n"; a = 0; // 重置a为无效值,让循环继续等待输入 // 移除Tour()调用,输入错误不需要切换玩家 } } }
2. 修复Win函数的返回值
将所有O玩家获胜的分支返回值改为2即可:
// victoirejoueur2分支示例,其余O获胜分支同理修改 else if (jeu[0][0]==jeu[0][1]&&jeu[0][1]==jeu[0][2]&&jeu[0][0]=='O') return 2;
3. 调整主循环逻辑顺序
int main() { Terrain(); while(Win()==0&&egalite()==false) { Choix(); Terrain(); if(Win()!=0 || egalite()) break; // 落子后先判定胜负和平局,再切换玩家 Tour(); } if(egalite()==true) cout<<"Egalite !\n"; if(Win()==1) cout<<"Le joueur 1 a gagne !\n"; if(Win()==2) cout<<"Le joueur 2 a gagne !\n"; system("pause"); }
内容的提问来源于stack exchange,提问作者Zeoun
相关产品推荐
相关产品推荐

