考虑一个象棋残局,其中红方有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;
}