问题:是一个中国象棋的模拟程序,在棋盘中黑方只有一个将,红方有若干的车马炮,需要检测在某个情况下黑将是否被将住,而红方取胜。
经验:开始写的时候很多都写在了main函数中,发现处理格子时越来越复杂,一定尽量将操作函数化;像这个题目中的棋子本身就是独立的,因此尽量的将棋子操作独立化来分别编写函数,即从顶向下的设计方法。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
typedef struct {
char name;
int r;
int c;
} Pos;
int redNum;
Pos blkGer;
vector<Pos> pvec;
vector<Pos> canMove;
bool checkPos(const Pos &p);
bool checkmate()
{
vector<Pos> canMove;
Pos temp;
temp.r = blkGer.r;
temp.c = blkGer.c;
canMove.push_back(temp);
if (blkGer.r > 1) {
temp.r = blkGer.r - 1;
temp.c = blkGer.c;
canMove.push_back(temp);
}
if (blkGer.r < 3) {
temp.r = blkGer.r + 1;
temp.c = blkGer.c;
canMove.push_back(temp);
}
if (blkGer.c > 4) {
temp.r = blkGer.r;
temp.c = blkGer.c - 1;
canMove.push_back(temp);
}
if (blkGer.c < 6) {
temp.r = blkGer.r;
temp.c = blkGer.c + 1;
canMove.push_back(temp);
}
//check each postion that can move to.
for (vector<Pos>::iterator iter = canMove.begin(); iter != canMove.end(); ++iter)
if (checkPos((*iter)))
return false;
return true;
}
inline bool between(int p, int p1, int p2)
{
int max, min;
if (p1 > p2) {
max = p1;
min = p2;
}
else {
max = p2;
min = p1;
}
if (p < max && p > min)
return true;
else
return false;
}
//if the black general can move to this postion, return ture
bool checkPos(const Pos &p)
{
for (vector<Pos>::iterator iter = pvec.begin(); iter != pvec.end(); ++iter) {
if (iter->r == p.r && iter->c == p.c)
continue;
bool can = false;
if (iter->name == 'G') {
if (iter->c == p.c) {
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r && iter2->c == p.c)
continue;
else if (p.c == iter2->c && between(iter2->r,p.r,iter->r)) {
can = true;
break;
}
if (can)
continue;
else
return false;
}//endif
}//endif name = G
if(iter->name == 'R'){
if (iter->c == p.c) {
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r && iter2->c == p.c)
continue;
else if (p.c == iter2->c && between(iter2->r, p.r, iter->r)) {
can = true;
break;
}
if (can)
continue;
else
return false;
}
else if (iter->r == p.r) {
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r && iter2->c == p.c)
continue;
else if (p.r == iter2->r && between(iter2->c, p.c, iter->c)) {
can = true;
break;
}
if (can)
continue;
else
return false;
}
}// endif name = R chariot;
if(iter->name == 'H'){
if (abs(iter->c - p.c) == 2 && abs(iter->r - p.r) == 1) {
if (iter->c > p.c) {
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r&& iter2->c == p.c)
continue;
else if (iter2->r == iter->r && iter2->c == iter->c - 1) {
can = true;
break;
}
if (can)
continue;
else
return false;
}
else if (iter->c < p.c) {
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r&& iter2->c == p.c)
continue;
else if (iter2->r == iter->r && iter2->c == iter->c + 1) {
can = true;
break;
}
if (can)
continue;
else
return false;
}
}else if(abs(iter->r - p.r) == 2 && abs(iter->c - p.c) == 1) {
if (iter->r > p.r) {
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r && iter2->c == p.c)
continue;
else if (iter2->c == iter->c && iter2->r == iter->r - 1) {
can = true;
break;
}
if (can)
continue;
else
return false;
}
else if (iter->r < p.r) {
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r && iter2->c == p.c)
continue;
else if (iter2->c == iter->c && iter2->r == iter->r + 1) {
can = true;
break;
}
if (can)
continue;
else
return false;
}
}
}// endif name = H
if(iter->name == 'C'){
if (iter->r == p.r) {
int cnt = 0;
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r && iter2->c == p.c)
continue;
else if (iter2->r == p.r && between(iter2->c, iter->c, p.c))
++cnt;
if (cnt == 1)
return false;
}
else if (iter->c == p.c) {
int cnt = 0;
for (vector<Pos>::iterator iter2 = pvec.begin(); iter2 != pvec.end(); ++iter2)
if (iter2->r == p.r && iter2->c == p.c)
continue;
else if (iter2->c == p.c && between(iter2->r, iter->r, p.r))
++cnt;
if (cnt == 1)
return false;
}
}// endif name = C
}//endfor iterator
return true;
}
int main()
{
#ifndef UVa
FILE *fp;
freopen_s(&fp, "data.in.txt", "r", stdin);
#endif
while (cin >> redNum >> blkGer.r >> blkGer.c) {
if (redNum == 0)
break;
pvec.clear();
for (int i = redNum; i > 0; --i) {
Pos tempP;
cin >> tempP.name >> tempP.r >> tempP.c;
pvec.push_back(tempP);
}
if (checkmate())
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}