C语言终极井字棋checkWin无法识别指定三连坐标获胜问题排查
问题根因
你将原3x3井字棋棋盘扩容为9x9后,未同步修改checkWin获胜判定函数,完全沿用了原3x3棋盘的判定范围,因此落子在(1,4)、(1,5)、(1,6)(对应数组下标tabu[0][3]、tabu[0][4]、tabu[0][5])时无法触发获胜判定。
具体错误点
- 行判定仅遍历前3行,且每行仅检查列下标0、1、2的三连,完全未覆盖列3-5、6-8段的三连,也未检查第4-9行的三连情况
- 列判定仅遍历前3列,且每列仅检查行下标0、1、2的三连,未覆盖列3-5、6-8段以及行3-5、6-8段的三连
- 对角线判定仅实现了左上角第一个3x3小棋盘的两条对角线校验,其余8个3x3小棋盘的对角线完全未覆盖
- 对角线判定代码错误嵌套在列遍历的for循环内部,会被无意义重复执行
- 所有判定逻辑未排除空字符:如果三个连续位置都是空格,会错误将空字符判定为获胜方
修正后的checkWin实现
以下代码先实现「9x9棋盘内任意3x3小棋盘内横/竖/斜三子连珠即获胜」的判定,后续如果要开发标准终极井字棋(小棋盘获胜占大棋盘格、最终大棋盘三子连珠获胜),可以在此基础上扩展规则:
char checkWin(){ // 校验所有横向三连 for(int i = 0; i < 9; i++){ // 每行三连的起始列偏移为0、3、6,对应界面上的1-3列、4-6列、7-9列 for(int j = 0; j <= 6; j += 3){ if(tabu[i][j] != ' ' && tabu[i][j] == tabu[i][j+1] && tabu[i][j] == tabu[i][j+2]){ return tabu[i][j]; } } } // 校验所有纵向三连 for(int j = 0; j < 9; j++){ // 每列三连的起始行偏移为0、3、6,对应界面上的1-3行、4-6行、7-9行 for(int i = 0; i <= 6; i += 3){ if(tabu[i][j] != ' ' && tabu[i][j] == tabu[i+1][j] && tabu[i][j] == tabu[i+2][j]){ return tabu[i][j]; } } } // 校验所有3x3小棋盘的两条对角线 // 9个小棋盘的左上角坐标分别为(0,0)(0,3)(0,6)(3,0)(3,3)(3,6)(6,0)(6,3)(6,6) for(int i = 0; i <= 6; i += 3){ for(int j = 0; j <= 6; j += 3){ // 左上到右下对角线 if(tabu[i][j] != ' ' && tabu[i][j] == tabu[i+1][j+1] && tabu[i][j] == tabu[i+2][j+2]){ return tabu[i][j]; } // 右上到左下对角线 if(tabu[i][j+2] != ' ' && tabu[i][j+2] == tabu[i+1][j+1] && tabu[i][j+2] == tabu[i+2][j]){ return tabu[i][j+2]; } } } // 无获胜方返回空字符 return ' '; }
其他待修复的逻辑bug
JogadaPC函数内的srand(time(0))会在每次电脑落子时重置随机数种子,会导致电脑落子重复度极高,建议将该语句移到main函数的游戏循环外,仅初始化一次随机数种子即可。
内容的提问来源于stack exchange,提问作者PPanda
相关产品推荐
相关产品推荐

