C# WinForms程序中legalMove方法致程序冻结问题求助
问题分析与修复方案
1. 直接导致程序冻结的死循环:内层for循环条件错误
你写的内层for循环里,循环终止条件误用了i<=1,而非j<=1:
for (int j = -1; i<=1; j++)
这会让j从-1开始无限递增,永远触发不了循环终止条件,直接造成死循环——WinForms的UI线程被卡死,程序自然完全冻结。把条件改成j<=1就能解决这个核心问题:
for (int j = -1; j<=1; j++)
2. 数组索引混乱的逻辑错误
代码里数组索引的对应关系前后完全不一致:
- 开头判断
grid[x, y] != 0,说明grid的维度是[x坐标, y坐标] - 中间写了
grid[col,row] == -turn,这里col是y+j、row是x+i,相当于写成了[y, x],和初始索引逻辑相反 - 后续的
grid[row, col]又变回[x+i, y+j],索引逻辑彻底混乱,会导致判断错误,甚至可能触发数组越界(只是因为死循环,这个问题没暴露出来)
修正时要保持索引逻辑统一,比如全程用[row, col]对应[x, y]:
// 初始判断对应统一逻辑 if (grid[row, col] != 0) return false; // 后续所有grid访问都保持grid[row, col]的顺序
3. while循环的潜在死循环风险
即使修复了for循环,原while(true)也有隐患:如果沿着某个方向全是对方棋子,既没碰到己方棋子也没出界,会再次触发无限循环。可以给while循环加棋盘边界判断,或者限制循环次数(最多7次,因为棋盘是8x8):
// 替换while(true)为带边界判断的循环 while (row >= 0 && row < 8 && col >= 0 && col < 8) { row += i; col += j; if (row < 0 || row >= 8 || col < 0 || col >= 8 || grid[row, col] == 0) break; else if (grid[row, col] == turn) return true; } // 跳出循环说明出界,返回不合法 return false;
完整修复后的代码示例
public bool legalMove(int y, int x) { // 检查当前位置是否被占用 if (grid[x, y] != 0) return false; // 遍历周围8个方向 for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) { // 跳过当前位置自身 if (i == 0 && j == 0) continue; int row = x + i; int col = y + j; // 检查相邻位置是否是对方棋子,且在棋盘内 if (row >= 0 && row < 8 && col >= 0 && col < 8 && grid[row, col] == -turn) { // 沿着该方向继续检查是否能形成吃子 while (row >= 0 && row < 8 && col >= 0 && col < 8) { row += i; col += j; // 出界或遇到空位置,说明不能吃子 if (row < 0 || row >= 8 || col < 0 || col >= 8 || grid[row, col] == 0) break; // 遇到己方棋子,说明可以吃子,返回合法 else if (grid[row, col] == turn) return true; } } } // 所有方向都不满足,返回不合法 return false; }
内容的提问来源于stack exchange,提问作者Jasper
相关产品推荐
相关产品推荐

