2009年3月3日 星期二

Q10196: Check the Check

/*
array 的 index 如果超出範圍記得要事先預防掉
不然會出錯

Run time: 0.000
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
const int SIZE = 8;
char str[SIZE][SIZE+1];
void run();
bool testwhite(int x, int y);
bool testblack(int x, int y);
bool knight(int x, int y, char ch);
bool bishop(int x, int y, char ch);
bool rook(int x, int y, char ch);
bool range(int x, int y);
void print(int n);

int main()
{
int i, j;
int eof;
char ch;

while (true)
{
eof = 0;
for ( i = 0; i < SIZE; i++)
{
scanf("%s", str[i]);

if (!strcmp(str[i], "........"))
eof++;
}

if (eof == SIZE)
break;

run();
}

return 0;
}

void run()
{
int i, j;
int state = 3;
bool s = true;

for ( i = 0; i < SIZE; i++)
{
for ( j = 0; j < SIZE; j++)
{
if (str[i][j] == 'K')
{
s = false;
if (testwhite(i, j))
{
state = 1; // 白色輸
print(state);
return;
}
}
}

if (!s) break;
}

s = true;

for ( i = 0; i < SIZE; i++)
{
for ( j = 0; j < SIZE; j++)
{
if (str[i][j] == 'k')
{
s = false;
if (testblack(i, j))
{
state = 2; // 黑色輸
print(state);
return;
}

}
}
if (!s) break;
}

print(state);
}

bool testwhite(int x, int y)
{
int i, j;
bool s = false;

// pwan
if ((range(x-1, y-1) && str[x-1][y-1] == 'p') || (range(x-1, y+1) && str[x-1][y+1] == 'p'))
return true;

if (knight(x, y, 'n'))
return true;

if (bishop(x, y, 'b'))
return true;

if (rook(x, y, 'r'))
return true;

// queen
if (bishop(x, y, 'q'))
return true;
if (rook(x, y, 'q'))
return true;

return false;

}

bool testblack(int x, int y)
{
int i, j;
bool s = false;

// pawn
if ((range(x+1, y-1) && str[x+1][y-1] == 'P') || (range(x+1, y+1) && str[x+1][y+1] == 'P'))
return true;

if (knight(x, y, 'N'))
return true;

if (bishop(x, y, 'B'))
return true;

if (rook(x, y, 'R'))
return true;

// Queen
if (bishop(x, y, 'Q'))
return true;
if (rook(x, y, 'Q'))
return true;

return false;
}

bool knight(int x, int y, char ch)
{
if (range(x-2, y+1) && str[x-2][y+1] == ch)
return true;
if (range(x-1, y+2) && str[x-1][y+2] == ch)
return true;
if (range(x+1, y+2) && str[x+1][y+2] == ch)
return true;
if (range(x+2, y+1) && str[x+2][y+1] == ch)
return true;
if (range(x+2, y-1) && str[x+2][y-1] == ch)
return true;
if (range(x+1, y-2) && str[x+1][y-2] == ch)
return true;
if (range(x-1, y-2) && str[x-1][y-2] == ch)
return true;
if (range(x-2, y-1) && str[x-2][y-1] == ch)
return true;

return false;
}

bool bishop(int x, int y, char ch)
{
bool s = false;
int i, j;

// 往右上角推
for ( i = x-1, j = y+1; i >= 0 && j < SIZE; i--, j++)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

// 往右下角推
for ( i = x+1, j = y+1; i < SIZE && j < SIZE; i++, j++)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

// 往左上角推
for ( i = x-1, j = y-1; i >= 0 && j >= 0; i--, j--)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

// 往左下角推
for ( i = x+1, j = y-1; i < SIZE && j >= 0; i++, j--)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

return false;
}

bool rook(int x, int y, char ch)
{
bool s = false;
int i, j;

// 往下推
for ( i = x+1, j = y; i < SIZE; i++)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

// 往上推
for ( i = x-1, j = y; i >= 0; i--)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

// 往左推
for ( i = x, j = y-1; j >= 0; j--)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

// 往右推
for ( i = x, j = y+1; j < SIZE; j++)
{
if (isalpha(str[i][j]) && str[i][j] != ch)
break;

if (str[i][j] == '.')
continue;

s = true;
}

if (s) return true;

return false;
}

bool range(int x, int y)
{
if (x >= 0 && x < SIZE && y >= 0 && y < SIZE)
return true;

return false;
}
void print(int n)
{
static int cnt = 0;

if (n == 1)
printf("Game #%d: white king is in check.\n", ++cnt);
else
if (n == 2)
printf("Game #%d: black king is in check.\n", ++cnt);
else
printf("Game #%d: no king is in check.\n", ++cnt);
}

沒有留言: