放牧代码和思想
专注自然语言处理、机器学习算法

UVa Q10196: Check the Check

模拟类。没有任何难度,纯粹消遣。

Q10196: Check the Check

你的任务是写一个程式,读入一西洋棋盘的状态,然后回答是否有国王(king)正处於可以攻击(check)的状态。(像中国象棋的"将军")

 白方以大写字元来表达各个角色,黑方以小写字元来表达各个角色。棋赛一开始时白方在棋盘下方,黑方在棋盘上方。如果你对西洋棋不熟的话,以下是各棋子角色的说明:

  • Pawn(士兵,以p或P表示)一次只能往前走一步,但是攻击时却是往左前方或右前方一格攻击。

  • Knight(骑士,以n或N表示)走法比较特別,是走L形的,像中国象棋的马,参考下面的图。

  • Bishop(主教,以b或B表示)可以走对角线任意格。

  • Rook(城堡,以r或R表示)可以走直线任意格。

  • Queen(皇后,以q或Q表示)可以走对角线及直线任意格。像Bishop及Rook的综合体。

  • King(国王,以k或K表示)可以走前后左右及对角线一格。

下图就是各棋子的走法(*表示该棋子可以攻击的格子)

    Pawn
    
........
........
........
........
...p....
..*.*...
........
........

    Rook
    
...*....
...*....
...*....
...*....
***r****
...*....
...*....
...*....

    Bishop
    
.......*
*.....*.
.*...*..
..*.*...
...b....
..*.*...
.*...*..
*.....*.

    Queen
    
...*...*
*..*..*.
.*.*.*..
..***...
***q****
..***...
.*.*.*..
*..*..*.

    King
    
........
........
........
..***...
..*k*...
..***...
........
........

    Knight
    
........
........
..*.*...
.*...*..
...n....
.*...*..
..*.*...
........

Input记住:只有骑士可以跨过棋子攻击,而士兵的攻击是有方向性的(白士兵只能向左上、右上攻击,黑士兵只能向左下、右下攻击)

每组测试资料8列,每列有8个字元。'.' 代表空白格子而其他英文字元则代表上面说明的各角色。不会有不该出现的字元出现,而且我们也保证不会有黑白双方的国王均处於被check的状态。

测试资料间有一空白列。输入的最后一组测试资料内容全为'.',代表输入结束。(此组测试不需有输出)

Output

每组测试资料请输出下列3种其中之一:

Game #d: white king is in check.
Game #d: black king is in check.
Game #d: no king is in check.

这里d代表第几组测试资料,从1开始。

Sample input

..k.....
ppp.pppp
........
.R...B..
........
........
PPPPPPPP
K.......

rnbqkbnr
pppppppp
........
........
........
........
PPPPPPPP
RNBQKBNR

rnbqk.nr
ppp..ppp
....p...
...p....
.bPP....
.....N..
PP..PPPP
RNBQKB.R

........
........
........
........
........
........
........
........

Sample Output

Game #1: black king is in check.
Game #2: no king is in check.
Game #3: white king is in check.

简体中文由Lucky貓的 UVA(ACM)園地转换。

#ifndef ONLINE_JUDGE
#pragma warning(disable : 4996)
#endif
#include <iostream>
using namespace std;
char Map[8][8];

void dumpMap()
{
	for (int i = 0; i < 8; ++i)
	{
		for (int j = 0; j < 8; ++j)
		{
			cout << Map[i][j];
		}
		cout << endl;
	}
}

void blackWin()
{
	cout << " white king is in check." << endl;
}

void whiteWin()
{
	cout << " black king is in check." << endl;
}

void noOneCheck()
{
	cout << " no king is in check." << endl;
}

bool checkP(const int& i, const int& j, const char& k)
{
	switch (k)
	{
		case 'K':
			if (j + 1 < 8)
			{
				if (i - 1 >= 0)
				{
					if (Map[i - 1][j + 1] == k)
					{
						return true;
					}
				}
				if (i + 1 < 8)
				{
					if (Map[i + 1][j + 1] == k)
					{
						return true;
					}
				}
			}
			break;
		case 'k':
			if (j - 1 >= 0)
			{
				if (i + 1 < 8)
				{
					if (Map[i + 1][j - 1] == k)
					{
						return true;
					}
				}
				if (i - 1 < 8)
				{
					if (Map[i - 1][j - 1] == k)
					{
						return true;
					}
				}
			}
			break;
		default:
			break;
	}
	
	return false;
}

bool checkR(const int& i, const int& j, const char& k)
{
	for (int n = 1;; ++n)
	{
		int x = i - n;
		int y = j;
		if (x < 0)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}
	for (int n = 1;; ++n)
	{
		int x = i + n;
		int y = j;
		if (x >= 8)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}
	for (int n = 1;; ++n)
	{
		int x = i;
		int y = j - n;
		if (y < 0)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}
	for (int n = 1;; ++n)
	{
		int x = i;
		int y = j + n;
		if (y >= 8)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}
	return false;
}

bool checkB(const int& i, const int& j, const char& k)
{
	for (int n = 1; ; ++n)
	{
		int x = i - n;
		int y = j - n;
		if (x < 0 || y < 0)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}

	for (int n = 1;; ++n)
	{
		int x = i + n;
		int y = j - n;
		if (x >= 8 || y < 0)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}

	for (int n = 1;; ++n)
	{
		int x = i + n;
		int y = j + n;
		if (x >= 8 || y >= 8)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}

	for (int n = 1;; ++n)
	{
		int x = i - n;
		int y = j + n;
		if (x < 0 || y >= 8)
		{
			break;
		}
		if (Map[x][y] == k)
		{
			return true;
		}
		else if (Map[x][y] != '.')
		{
			break;
		}
	}

	return false;
}

bool checkQ(const int& i, const int& j, const char& k)
{
	if (checkB(i, j, k))
	{
		return true;
	}
	if (checkR(i, j, k))
	{
		return true;
	}
	return false;
}

bool checkK(const int& i, const int& j, const char& k)
{
	int x = i - 1;
	int y = j - 1;
	if (x >= 0)
	{
		if (y >= 0)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
		y = j;
		if (Map[x][y] == k)
		{
			return true;
		}
		y = j + 1;
		if (y < 8)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
	}
	x = i;
	y = j - 1;
	if (y >= 0)
	{
		if (Map[x][y] == k)
		{
			return true;
		}
	}
	y = j + 1;
	if (y < 8)
	{
		if (Map[x][y] == k)
		{
			return true;
		}
	}

	x = i + 1;
	if (x < 8)
	{
		y = j - 1;
		if (y >= 0)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
		y = j;
		if (Map[x][y] == k)
		{
			return true;
		}
		y = j + 1;
		if (y < 8)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
	}
	return false;
}

bool checkN(const int& i, const int& j, const char& k)
{
	int x, y;
	y = j - 2;
	if (y >= 0)
	{
		x = i - 1;
		if (x >= 0)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}

		x = i + 1;
		if (x < 8)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
	}

	y = j - 1;
	if (y >= 0)
	{
		x = i - 2;
		if (x >= 0)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}

		x = i + 2;
		if (x < 8)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
	}

	y = j + 2;
	if (y < 8)
	{
		x = i - 1;
		if (x >= 0)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}

		x = i + 1;
		if (x < 8)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
	}

	y = j + 1;
	if (y < 8)
	{
		x = i - 2;
		if (x >= 0)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}

		x = i + 2;
		if (x < 8)
		{
			if (Map[x][y] == k)
			{
				return true;
			}
		}
	}

	return false;
}
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	int nCase = 0;
	bool running = true;
	while (running)
	{
		++nCase;
		running = false;
		for (int j = 0; j < 8; ++j)
		{
			for (int i = 0; i < 8; ++i)
			{
				cin >> Map[i][j];
				if (!running && Map[i][j] != '.')
				{
					running = true;
				}
			}
		}
		if (running)
		{
			bool finished = false;
			cout << "Game #" << nCase << ":";
			for (int j = 0; (j < 8) && !finished; ++j)
			{
				for (int i = 0; (i < 8) && !finished; ++i)
				{
					switch (Map[i][j])
					{
						case 'p':
						{
									finished = checkP(i, j, 'K');
									if (finished)
									{
										blackWin();
									}
						}break;
						case 'P':
						{
									finished = checkP(i, j, 'k');
									if (finished)
									{
										whiteWin();
									}
						}break;
						case 'r':
						{
									finished = checkR(i, j, 'K');
									if (finished)
									{
										blackWin();
									}
						}break;
						case 'R':
						{
									finished = checkR(i, j, 'k');
									if (finished)
									{
										whiteWin();
									}
						}break;
						case 'b':
						{
									finished = checkB(i, j, 'K');
									if (finished)
									{
										blackWin();
									}
						}break;
						case 'B':
						{
									finished = checkB(i, j, 'k');
									if (finished)
									{
										whiteWin();
									}
						}break;
						case 'q':
						{
									finished = checkQ(i, j, 'K');
									if (finished)
									{
										blackWin();
									}
						}break;
						case 'Q':
						{
									finished = checkQ(i, j, 'k');
									if (finished)
									{
										whiteWin();
									}
						}break;
						case 'k':
						{
									finished = checkK(i, j, 'K');
									if (finished)
									{
										blackWin();
									}
						}break;
						case 'K':
						{
									finished = checkK(i, j, 'k');
									if (finished)
									{
										whiteWin();
									}
						}break;
						case 'n':
						{
									finished = checkN(i, j, 'K');
									if (finished)
									{
										blackWin();
									}
						}break;
						case 'N':
						{
									finished = checkN(i, j, 'k');
									if (finished)
									{
										whiteWin();
									}
						}break;
						default:
							break;
					}
				}
			}
			if (!finished)
			{
				noOneCheck();
			}
		}
	}
#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	system("out.txt");
#endif
	return 0;
}
///////////////////////////End Sub//////////////////////////////////

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » UVa Q10196: Check the Check

分享到:更多 ()

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的开源项目

HanLP自然语言处理包基于DoubleArrayTrie的Aho Corasick自动机