如何在C语言中实现跳棋的走步验证功能?
跳棋程序棋子无法移动问题修复
我是编程新手,目前在开发跳棋程序,棋子始终无法在棋盘上移动,这让我十分困扰。我猜测问题出在走步验证的循环逻辑中,但一直没能解决。需求为:第一个用户输入需检测要移动棋子的坐标,通过validateMove()函数显示其可移动的目标位置。以下是我耗时几周编写的代码:
#include <stdio.h> char board[8][8] = { {' ', 'B', ' ', 'B', ' ', 'B', ' ', 'B'}, {'B', ' ', 'B', ' ', 'B', ' ', 'B', ' '}, {' ', 'B', ' ', 'B', ' ', 'B', ' ', 'B'}, {'*', ' ', '*', ' ', '*', ' ', '*', ' '}, {' ', '*', ' ', '*', ' ', '*', ' ', '*'}, {'W', ' ', 'W', ' ', 'W', ' ', 'W', ' '}, {' ', 'W', ' ', 'W', ' ', 'W', ' ', 'W'}, {'W', ' ', 'W', ' ', 'W', ' ', 'W', ' '}}; void printBoard() { int i , j , k ; printf("\n "); for(i=0;i<8;i++) printf(" %d", i+1 ); printf(" \n"); for(k=0;k<8;k++) { printf(" "); for(i=0;i<42;i++) { printf("-"); } printf(" \n"); printf(" %d ", k+1); for(j=0;j<8;j++) { printf("|| %c ", board[k][j]); } printf("|| \n"); } printf(" "); for(i=0;i<42;i++) { printf("-"); } printf(" \n"); } void validateMoveChecker(int x1, int y1, int af, int bf, int v) { int a, b; for(a=1, b=1; board[x1+ af * a][y1+ bf * b] == '*'; a++, b++) { if((x1+af*a) == -1 || (y1+bf*b)==v) return; printf("%d%d , ", x1+af*a , y1+bf*b); } } int validateMove(int x1 , int y1) { printf( "Available coordinates to send the piece are: \n" ); validateMoveChecker(x1, y1, -1, 1, 8); validateMoveChecker(x1, y1, 1, -1, -1); validateMoveChecker(x1, y1, 1, 1, 8); validateMoveChecker(x1, y1, -1, -1, -1); } int getChange(int x1 ,int y1 ,int x2 ,int y2 ) { char temp; temp = board[x1][y1]; board[x1][y1] = board[x2][y2]; board[x2][y2] = temp; } int check(int x, int y) { switch(board[x][y]) { case 'B': return 1; break; default: return 0; } } int main(){ int x1, y1, x2, y2, pos1, pos2, x, y; char board[8][8]; printBoard(); do { printf("\nEnter the position of the piece [X,Y]: "); scanf("%d", &pos1); y1 = pos1%10; x1 = pos1/10; switch(board[x1][y1]) { case 'B': validateMove(x1, y1); break; default: printf("Invalid Position. Please enter again!"); } }while(x1!=0 && y1!=0); printf("\nEnter the position on where to send the piece [X,Y]: "); scanf("%d", &pos2); y2 = pos2%10; x2 = pos2/10; getChange(x1 ,y1 ,x2 ,y2); if((x2-x1==y2-y1)!=0) { getChange(x1 ,y1 ,x2 ,y2); check(x,y); } }
核心问题及修复方案
全局棋盘被局部变量覆盖:main函数里声明了
char board[8][8];,直接覆盖了全局定义的棋盘数组,导致所有棋子位置读取都是随机垃圾值。删除这行代码即可。坐标索引未转换为0基:用户输入的是1-8的坐标,但数组索引是0-7,处理输入时需要减1:
x1 = (pos1 / 10) - 1; y1 = (pos1 % 10) - 1;目标位置x2、y2也要做同样转换。
走步验证的边界判断顺序错误:
validateMoveChecker中先判断棋盘内容再检查越界,会导致内存越界访问。调整循环逻辑,先检查边界再判断棋盘:void validateMoveChecker(int x1, int y1, int af, int bf) { int a = 1; while(1) { int newX = x1 + af * a; int newY = y1 + bf * a; // 先检查是否在棋盘范围内 if(newX < 0 || newX >=8 || newY <0 || newY >=8) { break; } // 不是空位置就停止 if(board[newX][newY] != '*') { break; } printf("%d%d , ", newX+1 , newY+1); // 输出给用户的是1基坐标 a++; } }同时修改
validateMove的调用,去掉多余的参数v。函数返回值不匹配:
validateMove和getChange声明为int类型但没有返回值,改成void类型:void validateMove(int x1 , int y1) { printf( "Available coordinates to send the piece are: \n" ); validateMoveChecker(x1, y1, -1, 1); validateMoveChecker(x1, y1, 1, -1); validateMoveChecker(x1, y1, 1, 1); validateMoveChecker(x1, y1, -1, -1); } void getChange(int x1 ,int y1 ,int x2 ,int y2 ) { char temp; temp = board[x1][y1]; board[x1][y1] = board[x2][y2]; board[x2][y2] = temp; }main循环逻辑错误:原do-while循环要输入00才退出,不符合需求。改为输入有效棋子位置后退出循环,同时增加坐标合法性检查:
do { printf("\nEnter the position of the piece [X,Y]: "); scanf("%d", &pos1); x1 = (pos1 / 10) - 1; y1 = (pos1 % 10) - 1; // 检查坐标是否在棋盘内 if(x1 <0 || x1 >=8 || y1 <0 || y1 >=8) { printf("Invalid Position. Please enter again!"); continue; } if(board[x1][y1] == 'B') { validateMove(x1, y1); break; // 选中有效棋子后退出循环 } else { printf("Invalid Position. Please enter again!"); } }while(1);移动验证逻辑混乱:原代码中
if((x2-x1==y2-y1)!=0)逻辑错误,跳棋的移动应该是斜向(x和y的变化量绝对值相等),且普通移动是变化量为±1,吃子是±2。需要重新梳理这部分逻辑,同时check(x,y)中x和y未初始化,属于无效调用,要修正或移除。
内容的提问来源于stack exchange,提问作者mei
相关产品推荐
相关产品推荐

