象棋 (ACM)

题目:考虑一个象棋藏局,其中红方有n(2<=n<=7)个棋子,黑方只有一个将。红方除了有一个帅(G)之外还有3种可能:车(R),马(H),炮(C),并且需要考虑 “蹩马脚” , 与将和帅不能照面的规则。

输入所有棋子的位置,保证局面合法并且红方已经将军。你的任务是判断红方是否已经把黑方将死。

#include<iostream>
using namespace std;

int n = 10, m = 9;
char map[11][10];  //记录棋子位置
int attack[11][10];//记录红棋的攻击范围

//设置 车 的攻击范围
void R(int x,int y) { 
	int tx, ty;

	tx = x;
	ty = y;
	while (--tx && map[tx][ty] == '.') attack[tx][ty] = 1;
	tx = x;
	while (++tx && map[tx][ty] == '.') attack[tx][ty] = 1;
	tx = x;
	while (--ty && map[tx][ty] == '.') attack[tx][ty] = 1;
	ty = y;
	while (++ty && map[tx][ty] == '.') attack[tx][ty] = 1;
}   
//设置 马 的攻击范围
void H(int x, int y) {
	int i, tx, ty;
	int nt[10][4] = { {0,0} ,{0,0} , {-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2} };  // 马 能行走的方向
	int orien[5][2] = { {0,0}, {-1,0},{0,1},{1,0},{ 0,-1 } }; // 马 的 上下左右 方向
	bool cantgo[8] = { 0 }; // 记录 蹩马脚 的位置,然后不能走

	for (i = 1; i <= 4; i++) {
		tx = x + orien[i][0];
		ty = y + orien[i][1];
		if (map[tx][ty] != '.') {  // 判断是否 蹩马脚
			cantgo[i * 2] = 1;
			cantgo[i * 2 + 1] = 1;
		}
	}
	for (i = 2; i < 10; i++) {
		if (cantgo[i])continue;  // 如果 蹩马脚 就不走
		tx = x + nt[i][0];
		ty = y + nt[i][1];
		attack[tx][ty] = 1;
	}

}
//设置 炮 的攻击范围
void C(int x, int y) {
	int tx, ty, flag = 0;
	tx = x;
	ty = y;

	while (tx--) {
		if (flag == 1) {
			if (tx < 1 || map[tx][ty] != '.')break;
			attack[tx][ty] = 1;
		}
		if (map[tx][ty] != '.')flag = 1;
	}
	flag = 0;
	tx = x;

	while (tx++) {
		if (flag == 1) {
			if (tx > n || map[tx][ty] != '.')break;
			attack[tx][ty] = 1;
		}
		if (map[tx][ty] != '.')flag = 1;
	}
	flag = 0;
	tx = x;

	while (ty--) {
		if (flag == 1) {
			if (ty < 1 || map[tx][ty] != '.')break;
			attack[tx][ty] = 1;
		}
		if (map[tx][ty] != '.')flag = 1;
	}
	flag = 0;
	ty = y;

	while (ty++) {
		if (flag == 1) {
			if (tx > m || map[tx][ty] != '.')break;
			attack[tx][ty] = 1;
		}
		if (map[tx][ty] != '.')flag = 1;
	}
}
//设置 帅 的攻击范围
void G(int x, int y) {
	int tx, ty;

	tx = x;
	ty = y;
	while (--tx && map[tx][ty] == '.') attack[tx][ty] = 1;
	tx = x;
	while (++tx && map[tx][ty] == '.') attack[tx][ty] = 1;
}


//判断“对将”
bool blackwin(int x,int y) {
	while (++x && x < 11)
		if (map[x][y] == 'G')  //判断“对将”
			return 1;
	return 0;
}

//判断输赢
bool judge(int x, int y) {
	int nt[4][2] = { { -1,0 },{ 0,1 },{ 1,0 },{ 0,-1 } };
	int tx, ty;
	for (int i = 0; i < 4; i++) {
		tx = x + nt[i][0];
		ty = y + nt[i][1];
		if (tx > 3 || tx < 1 || ty < 4 || ty>6)continue;
		if (attack[tx][ty] == 0)return 0; //将 有地方可走,则证明“将军”失败
	}
	return 1;
}

//选择需要设置攻击范围棋子
void skill(char f,int x,int y) {
	switch (f)
	{
	case 'R':
		R(x, y);
		break;

	case 'H':
		H(x, y);
		break;

	case 'C':
		C(x, y);
		break;

	case 'G':
		G(x, y);
		break;

	default:
		break;
	}
}

//判断 将 周围可以吃掉的棋子
void eat(int x,int y) { //判断 将 周围是否有棋可以吃
	int nt[4][2] = { { -1,0 },{ 0,1 },{ 1,0 },{ 0,-1 } };
	int tx, ty;
	for (int i = 0; i < 4; i++) {

		tx = x + nt[i][0];
		ty = y + nt[i][1];
		if (tx > 10 || tx < 1 || ty < 1 || ty>9)continue;

		if (map[tx][ty] != '.')	map[tx][ty] = '.'; // 吃掉 ,则改位置变成 ‘.’,则为没棋子
	}
}

int main() {
	int i, j;
	int jx, jy;
	int r[10], c[10], top = 0;

	for(i=1;i<=n;i++)
		for (j = 1; j <= m; j++) {
			cin >> map[i][j];
			if (map[i][j] == 'J') { // 记录 将 的位置
				jx = i;
				jy = j;
			}
		}

	if (blackwin(jx, jy)) { //判断黑棋是否一开始就已经 将死 红棋
		cout << "Black Win!";
		return 0;
	}

	eat(jx, jy); // “将”吃掉周围可以吃掉的棋

	for (i = 1; i <= n; i++)
		for (j = 1; j <= m; j++) {
			if (map[i][j] != '.') {
				skill(map[i][j], i, j); // 设置棋子的攻击范围
			}
		}

	if (judge(jx, jy))cout << "Red Win!";
	else cout << "Fail!";

	return 0;

}

如有错误,感谢大家指出~

猜你喜欢

转载自blog.csdn.net/qq742762377/article/details/81253793
ACM
今日推荐