我对C和一般编程都很陌生。我已经实现了C,并且几乎完成了,但是检查一个片段是否受到攻击的函数似乎是错误的。如果有人能看一看,也许能发现一些我找不到的东西,我会很感激的:
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;
}非常转向,我有一个移动列表。只有在完成移动后,玩家的国王没有受到攻击,即isAttacked返回0时,移动才能添加到该列表中。为了检查玩家的国王是否受到攻击,我收到国王的坐标(i,j)然后,我去对角线,看看是否有敌人的棋子,主教,国王,或王后可以攻击国王。我对车的动作也是这样。后两个是错的.我想--一个例子
|-------------------------------|
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表示。我在检测主教/车检查时遇到了问题,但我似乎找不到错误的地方。任何帮助都将不胜感激!
发布于 2014-08-04 21:30:55
我认为问题可能在输入到例程的坐标内,也可能是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 正如你所看到的,你的例行公事正确地发现了攻击主教,所以我怀疑问题在别处。
此外,就其价值而言,提供一个最小但完整的示例(如我提供的代码)可能会使其他人更容易帮助您。
发布于 2014-08-04 21:40:17
正如泰勒所指出的,您的代码有些不正确,但这并不是您的示例不起作用的原因。我使用您的函数实现了一个最小的工作示例,它在您的测试用例中运行得很好。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct game_s {
char board[8][8];
} game_t;
#define EMPTY 0x20
#define BLACK_N 'N'
#define BLACK_B 'B'
#define BLACK_R 'R'
#define BLACK_Q 'Q'
#define BLACK_K 'K'
#define BLACK_P 'P'
#define WHITE_N 'n'
#define WHITE_B 'b'
#define WHITE_R 'r'
#define WHITE_Q 'q'
#define WHITE_K 'k'
#define WHITE_P 'p'
void print_board(game_t *game) {
int i,j;
for(j=7;j>=0;j--) {
printf("|---------------|\n|");
for(i=0;i<8;i++) {
printf("%c|", game->board[i][j]);
}
printf("\n");
}
printf("|---------------|\n");
}
int ABS(int x) {
return (x > 0 ? x : x*-1);
}
int isValidCoords(int x, int y) {
return (x >= 0 && y>=0 && x<8 && y<8);
}
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)
{
printf("ATTACK from %s Bishop at %c%c\n", color ? "black" : "white", curX+'A', curY+'1');
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;
}
int main(int argc, char *argv[]) {
char my_board[8][8] = { {WHITE_R, WHITE_P, EMPTY, EMPTY, EMPTY, EMPTY, BLACK_P, BLACK_R},
{WHITE_N, WHITE_P, EMPTY, EMPTY, EMPTY, EMPTY, BLACK_P, BLACK_N},
{WHITE_B, WHITE_P, EMPTY, WHITE_B, EMPTY, EMPTY, BLACK_P, BLACK_B},
{EMPTY, WHITE_P, EMPTY, EMPTY, EMPTY, BLACK_Q, EMPTY, EMPTY},
{WHITE_K, EMPTY, EMPTY, BLACK_P, EMPTY, EMPTY, BLACK_P, EMPTY},
{EMPTY, WHITE_P, EMPTY, EMPTY, EMPTY, EMPTY, BLACK_K, BLACK_B},
{WHITE_N, WHITE_P, EMPTY, EMPTY, EMPTY, EMPTY, BLACK_P, BLACK_N},
{WHITE_R, WHITE_P, EMPTY, EMPTY, EMPTY, EMPTY, BLACK_P, BLACK_R}};
game_t my_game;
memcpy(my_game.board, my_board, 64);
isAttacked(&my_game, 5, 6, 0);
print_board(&my_game);
return 0;
}输出:
ATTACK from white Bishop at C4
|---------------|
|R|N|B| | |B|N|R|
|---------------|
|P|P|P| |P|K|P|P|
|---------------|
| | | |Q| | | | |
|---------------|
| | | | | | | | |
|---------------|
| | |b| |P| | | |
|---------------|
| | | | | | | | |
|---------------|
|p|p|p|p| |p|p|p|
|---------------|
|r|n|b| |k| |n|r|
|---------------|所以,你无法发现攻击主教的原因很可能是隐藏在周围的代码中。
您还应该将您的函数拆分为更小的函数,以方便调试。
编辑:爱德华击败了我,所以我同意他的观点。
发布于 2014-08-04 20:29:53
问题是如何处理以下循环中的退出条件:
while (isValidCoords(curX + i, curY + j) == 1)
如果isValidCoords返回false (0),则循环退出,该过程继续使用curX和curY的无效值。
换句话说,这个循环有两个可能的退出条件:(1)坐标不在板上,或者(2)坐标所表示的方格上有一块。你对待这两种情况的方式是一样的。解决此问题的一种方法是:
while ( true ){
if( isValidCoords(curX + i, curY + j) == 1 ) goto NextAttackCheck;
range++;
curX += i;
curY += j;
if( game->board[curX][curY] != EMPTY ) break;
}标签NextAttackCheck:应该位于j-循环的紧固支撑之前.
https://stackoverflow.com/questions/25126358
复制相似问题