ACM/ICPC——象棋

 考虑一个象棋残局,其中红方有n(2<=n=<7)个棋子,黑方只一个将(A),红方除了有一个帅(G)之外还有3种可能的棋子:车(R),马(H),炮(C),并且需要考虑“蹩马脚”与将和帅不能照面(将、帅如果在同一条直线上,中间又不隔着任何棋子的情况下,走子的一方获胜)的规则。

输入所有棋子的情况,保证局面合法且红方已经将军。你的任务是判断红方是否已经把黑方将死。关于中国象棋的相关规则各位读者请自行百度。

分析题目:

①:要判断黑方是否被将死,就是判断将在走出一步后是否会被红方中的任意一个棋子将死。

②:首先要判断黑方是否可以直接将红方将死,这样就不需要在进行下一步了。

③:然后还要判断黑方是否可以吃红方棋子的情况,如果可以吃掉某个棋子,就把这个棋子变成黑方可以走的位置。

④:再然后用一个数组标志棋盘的位置黑方是否可以走。

#include<iostream>
#include<algorithm>
using namespace std;
char a[10][9];//棋盘,上方为黑
bool vis[10][9];//用来标志是否黑方是否可以走,标志为1则黑方不能走
int flag = 0;//标志黑方是否已经被红方将死
void setG(int x, int y)//帅所对的列,黑方不能走
{
	while (--x&&a[x][y] == '.'&&x <= 0)
		vis[x][y] = true;
}
void setR(int x, int y)//车行走规则所对应黑方不能走的位置
{
	int tx0 = x, ty0 = y;
	while (--tx0&&a[tx0][ty0] == '.'&&tx0 >= 0)
	{
		vis[tx0][ty0] = true;
	}
	int tx1 = x, ty1 = y;
	while (++tx1&&a[tx1][ty1] == '.'&&tx1<10)
	{
		vis[tx1][ty1] = true;
	}
	int tx2 = x, ty2 = y;
	while (--ty2&&a[tx2][ty2] == '.'&&ty2 >= 0)
	{
		vis[tx2][ty2] = true;
	}
	int tx3 = x, ty3 = y;
	while (++ty3&&a[tx3][ty3] == '.'&&ty3<9)
	{
		vis[tx3][ty3] = true;
	}
}
void setH(int x, int y)//马
{
	int next[10][2] = { { 0,0 },{ 0,0 },{ -2,-1 },{ -2,1 },{ -1,2 },{ 1,2 },{ 2,1 },{ 2,-1 },{ 1,-2 },{ -1,-2 } };//马走日字形的位置
	int book[5][2] = { {},{ -1,0 },{ 0,1 },{ 1,0 },{ 0,-1 } };//判断是否会蹩马脚
	int tx, ty;
	for (int i = 1; i <= 4; i++)
	{
		int xx, yy;
		xx = x + book[i][0];
		yy = y + book[i][1];
		for (int k = 0; k < 8; k++)
		{
			tx = x + next[k][0];
			ty = y + next[k][1];
			if (a[xx][yy] != '.' && (k == i * 2 || k == i * 2 + 1))
				continue;
			else
				vis[tx][ty] = true;
		}
	}
}
void setC(int x, int y)//炮
{
	int tx0 = x, ty0 = y;
	while (tx0 < 10)
	{
		tx0++;
		if (a[tx0][ty0] != '.')
		{
			tx0++;
			if (a[tx0][ty0] != '.')
				break;
			vis[tx0][ty0] = true;
		}
	}
	int tx1 = x, ty1 = y;
	while (tx1 >= 0)
	{
		tx1--;
		if (a[tx1][ty1] != '.')
		{
			tx1--;
			if (a[tx1][ty1] != '.')
				break;
			vis[tx1][ty1] = true;
		}
	}
	int tx2 = x, ty2 = y;
	while (ty2 < 9)
	{
		ty2++;
		if (a[tx2][ty2] != '.')
		{
			ty2++;
			if (a[tx2][ty2] != '.')
				break;
			vis[tx2][ty2] = true;

		}
	}
	int tx = x, ty = y;
	while (ty >= 0)
	{
		ty--;
		if (a[tx][ty] != '.')
		{
			ty--;
			if (a[tx][ty] != '.')
				break;
			vis[tx][ty] = true;
		}
	}
}
//判断黑方是否有位置可以走
void judge(int x, int y)
{


	int next[4][2] = { { 1,0 },{ 0,1 },{ -1,0 },{ 0,-1 } };
	int tx, ty;
	for (int i = 0; i < 4; i++)
	{
		tx = x + next[i][0];
		ty = y + next[i][1];
		if (!vis[tx][ty] && a[tx][ty] == '.')
		{
			cout << "黑方赢" << endl;
			flag = 1;
		}
	}
}
int main()
{
	int Ax, Ay;
	for (int i = 0; i < 10; i++)
		for (int j = 0; j < 9; j++)
			vis[i][j] = false;
	for (int i = 0; i < 10; i++)
		for (int j = 0; j < 9; j++)
			cin >> a[i][j];

	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			int next[4][2] = { { 1,0 },{ -1,0 },{ 0,1 },{ 0,-1 } };
			if (a[i][j] == 'A')
			{
				Ax = i;
				Ay = j;
				int x = i;
				int y = j;
				//判断黑方是否可以直接将红方将死
				while (++x&&x>10)
				{
					if (a[x][y] != '.'&&a[x][y] != 'G')
						break;
					else if (a[x][y] == 'G')//如果可以将死红方,则不需要走下一步了
					{
						cout << "黑方赢" << endl;
						return 0;
					}
				}
			}
			//判断黑方的将是否可以吃掉红方的棋子
			for (int i = 0; i < 4; i++)
			{
				int tx = Ax + next[i][0];
				int ty = Ay + next[i][0];
				if (a[tx][ty] != '.')
					a[tx][ty] = '.';
			}
			if (a[i][j] == 'G')
			{
				setG(i, j);
			}
			if (a[i][j] == 'R')
			{
				setR(i, j);
			}
			if (a[i][j] == 'H')
			{
				setH(i, j);
			}
			if (a[i][j] == 'C')
			{
				setC(i, j);
			}
		}
	}
	judge(Ax, Ay);
	if (!flag)
	{
		cout << "红方赢" << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41676901/article/details/81227991