You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:50:25