原帖地址:http://blog.youkuaiyun.com/metaphysis/article/details/6432094
开始做《挑战编程》上的题目
主要是感觉自己编程能力和算法非常差
一看到这题,感觉不好动手,但之后看了别人的代码后,才恍然大悟
其实就是注意函数的使用
把判断每个棋子能否将军写成一个函数
再组织好就可以了
还有就是,原作者的编程风格值得自己学习,清晰明确
// Check the Check (将军)
// PC/UVa IDs: 110107/10196, Popularity: B, Success rate: average Level: 1
// Verdict: Accepted
// Submission Date: 2011-05-22
// UVa Run Time: 0.008s
//
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net
#include <iostream>
#include <cstdlib>
using namespace std;
char status[8][8]; // 表示国际象棋棋子的位置。
// 检查坐标为(kingX,kingY)的王是否在坐标为(x,y)的卒攻击范围内,注意进攻方向的不同。
bool checkP (int x, int y, int kingX, int kingY)
{
return (x - kingX) == 1 && abs(y - kingY) == 1;
}
// 检查坐标为(kingX,kingY)的王是否在坐标为(x,y)的马攻击范围内。
bool checkN (int x, int y, int kingX, int kingY)
{
return (abs(x - kingX) == 2 && abs(y - kingY) == 1) ||
(abs(x - kingX) == 1 && abs(y - kingY) == 2);
}
// 检查坐标为(kingX,kingY)的王是否在坐标为(x,y)的象攻击范围内。
bool checkB (int x, int y, int kingX, int kingY)
{
int step, currentX = x, currentY = y, directX, directY;
bool checked = false;
// 检查象与王是否处于对角线。
if (abs(x - kingX) == abs(y - kingY))
{
checked = true;
// 判断相对方位。
directX = (x < kingX) ? 1 : -1;
directY = (y < kingY) ? 1 : -1;
// 是否有棋子相隔。
step = abs (x - kingX);
while (step > 1)
{
currentX += directX;
currentY += directY;
if (status[currentX][currentY] != '.')
{
checked = false;
break;
}
step--;
}
}
return checked;
}
// 检查坐标为(kingX,kingY)的王是否在坐标为(x,y)的车攻击范围内。
bool checkR (int x, int y, int kingX, int kingY)
{
int step, currentX = x, currentY = y, directX = 0, directY = 0;
bool checked = false;
// 车与王是否在同一行或者同一列,车与王之间是否有棋子相隔。
if (x == kingX || y == kingY)
{
checked = true;
// 判断相对方位。
directX = (x == kingX) ? (0) : (x < kingX ? 1 : -1);
directY = (y == kingY) ? (0) : (y < kingY ? 1 : -1);
// 是否有棋子相隔。
step = (directX == 0) ? abs(y - kingY) : abs(x - kingX);
while (step > 1)
{
currentX += directX;
currentY += directY;
if (status[currentX][currentY] != '.')
{
checked = false;
break;
}
step--;
}
}
return checked;
}
// 检查坐标为(kingX,kingY)的王是否在坐标为(x,y)的王后攻击范围内。
bool checkQ (int x, int y, int kingX, int kingY)
{
return checkR(x, y, kingX, kingY) || checkB(x, y, kingX, kingY);
}
// 检查给定棋盘状态是否存在将军局面。
void check (int gameCount)
{
bool bChecked = false, wChecked = false;
int bKingX = -1, bKingY = -1, wKingX = -1, wKingY = -1;
int directX = 0, directY = 0, currentX = 0, currentY = 0, step = 0;
// 查找白棋和黑棋王的位置。
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
{
if (status[i][j] == 'k')
{
bKingX = i;
bKingY = j;
}
if (status[i][j] == 'K')
{
wKingX = i;
wKingY = j;
}
}
// 假如未找到王的坐标,表明为空棋盘。
if (bKingX == -1)
return;
cout << "Game #" << gameCount << ": ";
// 检查棋子与王的是否存在将军情况。
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
{
switch (status[i][j])
{
// 黑卒。
case 'p':
wChecked = checkP(wKingX, wKingY, i, j);
break;
// 白卒。
case 'P':
bChecked = checkP(i, j, bKingX, bKingY);
break;
// 黑马。
case 'n':
wChecked = checkN(i, j, wKingX, wKingY);
break;
// 白马。
case 'N':
bChecked = checkN(i, j, bKingX, bKingY);
break;
// 黑象。
case 'b':
wChecked = checkB(i, j, wKingX, wKingY);
break;
// 白象。
case 'B':
bChecked = checkB(i, j, bKingX, bKingY);
break;
// 黑车。
case 'r':
wChecked = checkR(i, j, wKingX, wKingY);
break;
// 白车。
case 'R':
bChecked = checkR(i, j, bKingX, bKingY);
break;
// 黑后。
case 'q':
wChecked = checkQ(i, j, wKingX, wKingY);
break;
// 白后。
case 'Q':
bChecked = checkQ(i, j, bKingX, bKingY);
break;
// 其他情况。
default:
break;
}
// 检查将军情况是否存在。
if (bChecked)
{
cout << "black king is in check." << endl;
return;
}
if (wChecked)
{
cout << "white king is in check." << endl;
return;
}
}
cout << "no king is in check." << endl;
}
int main (int ac, char *av[])
{
string line;
int gameCount = 1, temp = 0;
while (getline(cin, line))
{
if (line != "")
{
for (int i = 0; i < 8; i++)
status[temp][i] = line[i];
temp++;
}
else
{
check(gameCount);
gameCount++;
temp = 0;
}
}
return 0;
}