C#开发井字棋while循环条件为真仍不退出的问题排查
C#井字棋while循环无法正常退出故障
问题背景
- 游戏核心逻辑位于包含2个分支的
switch语句中,通过Random.Next()随机选择分支执行 - 设计规则:循环终止判定满足任意一项即可退出,执行
winMessage()胜利提示:- 游戏结束标记变量
gameEnd为true - 棋盘占满检测函数
AllArrFilledEmptySpace()返回true - 检测函数内部已添加
gameEnd = true赋值作为兜底逻辑
- 游戏结束标记变量
- 初始化规则:游戏启动时声明
string[]类型board棋盘数组,所有元素填充空格避免null值;AllArrFilledEmptySpace()通过遍历检测数组元素是否为空格,判断9个棋盘位置是否全部被"X"或"O"占满 - 故障表现:即使手动调整过循环判断条件,且
gameEnd已被赋值为true,循环仍无法正常break跳出,无法进入后续胜利提示逻辑
故障相关代码
主运行逻辑
public static string[] board { get; set; } public static bool gameEnd { get; set; } public static void Run() { Clear(); makeArr(); gameEnd = false; ConsoleKey keyPressed; ConsoleKeyInfo keyInfo = ReadKey(true); keyPressed = keyInfo.Key; Random rOdd = new Random(); int odds = rOdd.Next(0, 2); do { switch (odds) { case 0: while (!gameEnd || !AllArrFilledEmptySpace(board)) { Clear(); printBoard(board); turnO(board); WriteLine($"\n\nAll Blocks filled: {AllArrFilledEmptySpace(board)}, GameEnd variable: {gameEnd}"); ReadKey(true); Clear(); printBoard(board); turnX(board); WriteLine($"\n\nAll Blocks filled: {AllArrFilledEmptySpace(board)}, GameEnd variable: {gameEnd}"); ReadKey(true); } break; case 1: while (!gameEnd || !AllArrFilledEmptySpace(board)) { Clear(); printBoard(board); turnO(board); WriteLine($"\n\nAll Blocks filled: {AllArrFilledEmptySpace(board)}, GameEnd variable: {gameEnd}"); ReadKey(true); Clear(); printBoard(board); turnX(board); WriteLine($"\n\nAll Blocks filled: {AllArrFilledEmptySpace(board)}, GameEnd variable: {gameEnd}"); ReadKey(true); } break; } } while (!gameEnd) ; winMessage(); ReadKey(true); }
工具函数逻辑
public static bool AllArrFilledEmptySpace(string[] board) { int count = 0; for (int i = 0; i < board.Length; i++) { if (!board[i].Equals(" ")) { count++; } } if (count == 9) { gameEnd = true; return true; } return false; } public static string[] makeArr() { board = new string[9]; for (int i = 0; i < board.Length; i++) { string q = " "; board[i] = q; } return board; }
根因分析
核心问题是内层while循环的条件逻辑运算符使用错误:
- 原循环条件为
!gameEnd || !AllArrFilledEmptySpace(board),使用逻辑或||的判定规则是:只要两个条件任意一个为真,就持续执行循环。也就是说哪怕gameEnd已经被设为true,只要棋盘还没被占满(!AllArrFilledEmptySpace()返回true),整个循环条件依然为真,循环不会终止,和设计预期完全相反。 - 预期的循环执行条件应该是:游戏未结束 且 棋盘未被占满,两个条件同时满足时才继续循环,只要任意一个不满足就退出。
额外冗余问题:
switch的两个分支代码完全重复,且随机值odds在do-while循环外赋值,进入循环后不会重新计算,分支选择没有实际作用- 外层嵌套的
do-while (!gameEnd)属于冗余逻辑,内层循环修正后退出时gameEnd必然为true,外层循环不会重复触发
修复方案
- 将内层两个
while循环的条件中逻辑或||替换为逻辑与&&,修正为while (!gameEnd && !AllArrFilledEmptySpace(board)) - 可移除冗余的外层do-while循环和重复的switch分支代码,简化逻辑
修复后的核心循环参考:
public static void Run() { Clear(); makeArr(); gameEnd = false; ReadKey(true); Random rOdd = new Random(); int odds = rOdd.Next(0, 2); while (!gameEnd && !AllArrFilledEmptySpace(board)) { Clear(); printBoard(board); if (odds == 0) turnO(board); else turnX(board); if (gameEnd) break; WriteLine($"\n\nAll Blocks filled: {AllArrFilledEmptySpace(board)}, GameEnd variable: {gameEnd}"); ReadKey(true); Clear(); printBoard(board); if (odds == 0) turnX(board); else turnO(board); WriteLine($"\n\nAll Blocks filled: {AllArrFilledEmptySpace(board)}, GameEnd variable: {gameEnd}"); ReadKey(true); } winMessage(); ReadKey(true); }
注:需要在
turnO和turnX方法内部的落子逻辑后增加胜负判定,及时将gameEnd设为true,避免出现一方获胜后依然要等另一方落子才会触发退出的问题。
内容的提问来源于stack exchange,提问作者Bogger
相关产品推荐
相关产品推荐

