C - 需要帮助调试国际象棋功能

标签 c

<分区>

我是 C 和一般编程的新手。我已经实现了 C 并且快完成了,但是看起来检查一 block 是否被攻击的函数是错误的。如果有人能看一眼并发现一些我看不到的东西,我将不胜感激:

int isAttacked(game_t* game, int x, int y, int color)
{
    /*printf("entered IA");*/
    int i, j,m, curX, curY, range;
    int dx[] = { 0, 1, 0, -1 };
    int dy[] = { 1, 0, -1, 0 };
    char en = BLACK_N, eb = BLACK_B, er = BLACK_R, eq = BLACK_Q, ek = BLACK_K, ep = BLACK_P;
    if (!color)
    {
        en = WHITE_N;
        eb = WHITE_B;
        er = WHITE_R;
        eq = WHITE_Q;
        ek = WHITE_K;
        ep = WHITE_P;
    }

    for (i = -2; i <= 2; i++)  /* KNIGHT ATTACKING */
        for (j = -2; j <= 2; j++)
            if (ABS(i) + ABS(j) == 3 && isValidCoords(x + i, y + j) && game->board[x + i][y + j] == en)
                return 1;

    for (i = -1; i <= 1; i += 2)
    {
        for (j = -1; j <= 1; j += 2)
        {
            curX = x;
            curY = y;
            range = 0;
            while (isValidCoords(curX + i, curY + j) == 1)          
            {
                range++;
                curX += i;
                curY += j;
                if(game->board[curX][curY] != EMPTY)
                    break;
            }


            if (game->board[curX][curY] == eq) /*BISHOP OR QUEEN ATTACKING*/
                return 1;
            if(game->board[curX][curY] == eb)
            {
                return 1;
            }

            if (range == 1 && game->board[curX][curY] == ek) /*KING ATTACKING*/
                return 1;
            if (range == 1 && color && j == 1 && game->board[curX][curY] == ep)
            {
                return 1;
            }
            if (range == 1 && !color && j == -1 && game->board[curX][curY] == ep)
            {
                return 1;
            }


        }
    }

    for (m = 0; m<4; m++)
    {
        curX = x;
        curY = y;
        range = 0;
        while (isValidCoords(curX + dx[m], curY + dy[m]))
        {
            curX += dx[m];
            curY += dy[m];
            range++;
            if(game->board[curX][curY] != EMPTY)
                break;
        }

        if (game->board[curX][curY] == eq)
            return 1;
        if(game->board[curX][curY] == er) /*ROOK OR QUEEN ATTACKING*/
        {
            /*printf("x %d  y   %d\n",x,y);*/
            return 1;
        }
        if (range == 1 && game->board[curX][curY] == ek)
            return 1;


    }

    return 0;
}

非常转,我有一个 Action 列表。只有在移动完成后,玩家的国王没有受到攻击,即 isAttacked 返回 0,才能将移动添加到该列表中。为了检查玩家的国王是否受到攻击,我收到了国王的坐标 (i,j)[这些是从 0 到 7 的数字] 和颜色 [0 或 1]。然后我检查棋盘内是否有敌方骑士 (ek)(isValidCoords 检查 0<=x,y<=7)可以攻击国王。然后我去对角线检查是否有可以攻击国王的敌人棋子、主教、国王或王后。我对白嘴鸦的 Action 也这样做。后两个是错误的……我认为—— 检查未能检测到主教攻击国王的示例棋盘:

 |-------------------------------|
8| R | N | B |   |  | B | N | R |
 |-------------------------------|
7| P | P | P |   | P | K | P | P |
 |-------------------------------|
6|   |   |   | Q |   |   |   |   |
 |-------------------------------|
5|   |   |   |   |   |   |   | |
 |-------------------------------|
4|   |   | b |   | P |   |   |   |
 |-------------------------------|
3|   |   |   |   |   |   |   |   |
 |-------------------------------|
2| p | p | p | p |   | p | p | p |
 |-------------------------------|
1| r | n | b |   | k |   | n | r |
 |-------------------------------|

黑色部分大写,白色部分小写。

颜色由黑色 - 0 和白色 - 1 表示。我在检测象/车检查时遇到问题,但我似乎无法查明错误。任何帮助都将不胜感激!

最佳答案

我认为问题可能在于您输入例程的坐标或者您的 isValidCoords 例程的问题。为了测试您发布的代码,我提供了这个驱动程序:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    char board[8][8];
} game_t;

int isValidCoords(int x, int y)
{
    return (x >= 0) && (y >= 0) && (x < 8) && (y < 8);
}

enum pieces { EMPTY, 
              BLACK_N, BLACK_B, BLACK_R, BLACK_Q, BLACK_K, BLACK_P, 
              WHITE_N, WHITE_B, WHITE_R, WHITE_Q, WHITE_K, WHITE_P };

const char pieceabbrev[] = " NBRQKPnbrqkp";

#define BLACK 0
#define WHITE 1

int ABS(int i)
{
    return i < 0 ? -i : i;
}
void showboard(game_t *game)
{
    const char hline[] ="\n |-------------------------------|";

    puts(hline);
    for (int y=7; y>=0; --y) {
        printf("%d|", y);
        for (int x=0; x < 8; ++x) {
            printf(" %c |", pieceabbrev[game->board[x][y]]);
        }   
        puts(hline);
    }   
    printf("  ");
    for (int x=0; x < 8; ++x) {
        printf(" %d  ", x);
    }
    printf("\n");
}

/*
Y
 |-------------------------------|
7| R | N | B |   |   | B | N | R |
 |-------------------------------|
6| P | P | P |   | P | K | P | P |
 |-------------------------------|
5|   |   |   | Q |   |   |   |   |
 |-------------------------------|
4|   |   |   |   |   |   |   |   |
 |-------------------------------|
3|   |   | b |   | P |   |   |   |
 |-------------------------------|
2|   |   |   |   |   |   |   |   |
 |-------------------------------|
1| p | p | p | p |   | p | p | p |
 |-------------------------------|
0| r | n | b |   | k |   | n | r |
 |-------------------------------|
   0   1   2   3   4   5   6   7     X
 lowercase is white
 Uppercase is Black
*/
int main()
{
    game_t game;
    for (int i=0; i < 8; ++i)
        for (int j=0; j < 8; ++j)
            game.board[i][j] = EMPTY;

    game.board[0][7] = BLACK_R;
    game.board[1][7] = BLACK_N;
    game.board[2][7] = BLACK_B;
    game.board[3][7] = EMPTY;
    game.board[4][7] = EMPTY;
    game.board[5][7] = BLACK_B;
    game.board[6][7] = BLACK_N;
    game.board[7][7] = BLACK_R;

    game.board[0][6] = BLACK_P;
    game.board[1][6] = BLACK_P;
    game.board[2][6] = BLACK_P;
    game.board[3][6] = EMPTY;
    game.board[4][6] = BLACK_P;
    game.board[5][6] = BLACK_K;
    game.board[6][6] = BLACK_P;
    game.board[7][6] = BLACK_P;

    game.board[3][5] = BLACK_Q;

    game.board[2][3] = WHITE_B;
    game.board[4][3] = WHITE_P;

    game.board[0][1] = WHITE_P;
    game.board[1][1] = WHITE_P;
    game.board[2][1] = WHITE_P;
    game.board[3][1] = WHITE_P;
    game.board[4][1] = EMPTY;
    game.board[5][1] = WHITE_P;
    game.board[6][1] = WHITE_P;
    game.board[7][1] = WHITE_P;

    game.board[0][0] = WHITE_R;
    game.board[1][0] = WHITE_N;
    game.board[2][0] = WHITE_B;
    game.board[3][0] = EMPTY;
    game.board[4][0] = WHITE_K;
    game.board[5][0] = EMPTY;
    game.board[6][0] = WHITE_N;
    game.board[7][0] = WHITE_R;

    printf("attacked = %d\n", isAttacked(&game, 5, 6, BLACK));

    showboard(&game);
}

然后我检测了您的代码。它原来有一个 return 1; 我把它改成这样:

{
    printf("%c is attacking from (%d,%d)\n", 
           pieceabbrev[game->board[curX][curY]], curX, curY);
    return 1;
}

程序输出:

b is attacking from (2,3)
attacked = 1

 |-------------------------------|
7| R | N | B |   |   | B | N | R |
 |-------------------------------|
6| P | P | P |   | P | K | P | P |
 |-------------------------------|
5|   |   |   | Q |   |   |   |   |
 |-------------------------------|
4|   |   |   |   |   |   |   |   |
 |-------------------------------|
3|   |   | b |   | p |   |   |   |
 |-------------------------------|
2|   |   |   |   |   |   |   |   |
 |-------------------------------|
1| p | p | p | p |   | p | p | p |
 |-------------------------------|
0| r | n | b |   | k |   | n | r |
 |-------------------------------|
   0   1   2   3   4   5   6   7  

如您所见,您的例程正确检测到攻击主教,所以我怀疑问题出在其他地方。

此外,尽管如此,提供一个最小但完整的示例(就像我提供的代码一样)可能会让其他人更容易帮助您。

关于C - 需要帮助调试国际象棋功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25126358/

相关文章:

objective-c - 如何在 C/Objective C 中实现位数组

c - 为什么这会产生段错误?

c - 此 C 代码仅获取 HTTP header ,但不是 html 文件

c - 图像大小调整程序输出扭曲的图像

c++ - size_t 是字长吗?

java - 即使在失去焦点后也能在 X11 中捕获事件

c - 无法理解 C 中 asprintf() 函数的参数之一

c++ - Valgrind 堆栈完全错过了一个函数

c - 指向数组的指针

c - 可能的堆栈损坏