UVa Problem 10196 Check the Check (将军)

来源:互联网 发布:谷歌搜索引擎优化 编辑:程序博客网 时间:2024/04/29 12:37
// 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;}