这是我写出的第一道紫题。纪念一下。
我们用数字代表棋子。对于这个数字的个位,让 1
代表 car
,2
代表 horse
,3
代表 guard
,4
代表 elephant
,5
代表 captain
,6
代表 duck
,7
代表 soldier
。对于这个数字的十位,让 0
代表蓝方,让1
代表红方。
我们先写好判断棋子移动是否合法的函数,由于有 7 7 7 种棋子,所以就有 7 7 7 个函数:
bool movecar(int sx, int sy, int ex, int ey) {
if (sx != ex && sy != ey) return 0;
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (sx == ex) {
for (int i = sy + dir(ey - sy); i != ey; i += dir(ey - sy)) {
if (m[sx][i]) return 0;
}
return 1;
}
else {
for (int i = sx + dir(ex - sx); i != ex; i += dir(ex - sx)) {
if (m[i][sy]) return 0;
}
return 1;
}
return 0;
}
bool movecaptain(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(ex - sx) + abs(ey - sy) == 1) {
return 1;
}
return 0;
}
bool moveguard(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10) {
return 0;
}
if (abs(sx - ex) == 1 && abs(ey - sy) == 1) {
return 1;
}
return 0;
}
bool moveelephant(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(ex - sx) == 2 && abs(ey - sy) == 2) {
int dx = dir(ex - sx), dy = dir(ey - sy);
if (!m[sx + dx][sy + dy]) {
return 1;
}
}
return 0;
}
bool movehorse(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(sx - ex) && abs(sy - ey)
&& abs(sx - ex) + abs(sy - ey) == 3) {
int dx = abs(ex - sx) - 1,
dy = abs(ey - sy) - 1;
dx *= dir(ex - sx);
dy *= dir(ey - sy);
if (!m[sx + dx][sy + dy]) {
return 1;
}
}
return 0;
}
bool moveduck(int sx, int sy, int ex, int ey) {
int dx = dir(ex - sx), dy = dir(ey - sy);
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if ((abs(ex - sx) == 2 && abs(ey - sy) == 3)) {
if (!m[sx + dx][sy + dy * 2]) {
if (!m[sx][sy + dy]) {
return 1;
}
}
}
else if (abs(ex - sx) == 3 && abs(ey - sy) == 2){
if (!m[sx + dx * 2][sy + dy]) {
if (!m[sx + dx][sy]) {
return 1;
}
}
}
return 0;
}
bool movesoldier(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(sx - ex) <= 1 && abs(sy - ey) <= 1) {
return 1;
}
return 0;
}
写好这 7 7 7 个函数之后,我们判断输入的棋子是不是我们自己的,如果不是,就代表这个命令不合法。如果是,就判断棋子类型,把我们写的函数丢进去。如果合法,就执行移动步骤,然后就是判断将军。我用了一个很粗暴的方法:找到每一个captain
,然后枚举另一方的棋子,如果这个棋子移动到captain
位置是合法的,就代表将军了。
判断结束很简单,如果被移走的棋子是 captain
,就代表这个游戏结束了。
注意:移走棋子时要把原来的位置设为空白,xy 坐标不要搞反,我因为这个调了 3h。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int q;
map<int, string> m1, m2;
void init() {
m1[1] = "car", m1[2] = "horse";
m1[3] = "guard", m1[4] = "elephant";
m1[5] = "captain", m1[6] = "duck";
m1[7] = "soldier";
m2[0] = "blue", m2[1] = "red";
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> q;
}
int m[15][15] = {
{11, 12, 14, 13, 15, 13, 14, 12, 11},
{00, 00, 00, 00, 00, 00, 00, 00, 00},
{16, 00, 00, 00, 00, 00, 00, 00, 16},
{17, 00, 17, 00, 17, 00, 17, 00, 17},
{00, 00, 00, 00, 00, 00, 00, 00, 00},
{00, 00, 00, 00, 00, 00, 00, 00, 00},
{07, 00, 07, 00, 07, 00, 07, 00, 07},
{06, 00, 00, 00, 00, 00, 00, 00, 06},
{00, 00, 00, 00, 00, 00, 00, 00, 00},
{01, 02, 04, 03, 05, 03, 04, 02, 01},
};
int dir(int x) {return x > 0 ? 1 : -1;}
bool movecar(int sx, int sy, int ex, int ey) {
if (sx != ex && sy != ey) return 0;
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (sx == ex) {
for (int i = sy + dir(ey - sy); i != ey; i += dir(ey - sy)) {
if (m[sx][i]) return 0;
}
return 1;
}
else {
for (int i = sx + dir(ex - sx); i != ex; i += dir(ex - sx)) {
if (m[i][sy]) return 0;
}
return 1;
}
return 0;
}
bool movecaptain(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(ex - sx) + abs(ey - sy) == 1) {
return 1;
}
return 0;
}
bool moveguard(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10) {
return 0;
}
if (abs(sx - ex) == 1 && abs(ey - sy) == 1) {
return 1;
}
return 0;
}
bool moveelephant(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(ex - sx) == 2 && abs(ey - sy) == 2) {
int dx = dir(ex - sx), dy = dir(ey - sy);
if (!m[sx + dx][sy + dy]) {
return 1;
}
}
return 0;
}
bool movehorse(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(sx - ex) && abs(sy - ey)
&& abs(sx - ex) + abs(sy - ey) == 3) {
int dx = abs(ex - sx) - 1,
dy = abs(ey - sy) - 1;
dx *= dir(ex - sx);
dy *= dir(ey - sy);
if (!m[sx + dx][sy + dy]) {
return 1;
}
}
return 0;
}
bool moveduck(int sx, int sy, int ex, int ey) {
int dx = dir(ex - sx), dy = dir(ey - sy);
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if ((abs(ex - sx) == 2 && abs(ey - sy) == 3)) {
if (!m[sx + dx][sy + dy * 2]) {
if (!m[sx][sy + dy]) {
return 1;
}
}
}
else if (abs(ex - sx) == 3 && abs(ey - sy) == 2){
if (!m[sx + dx * 2][sy + dy]) {
if (!m[sx + dx][sy]) {
return 1;
}
}
}
return 0;
}
bool movesoldier(int sx, int sy, int ex, int ey) {
if (m[ex][ey] && m[sx][sy] / 10 == m[ex][ey] / 10)
return 0;
if (abs(sx - ex) <= 1 && abs(sy - ey) <= 1) {
return 1;
}
return 0;
}
int step = 1;
bool is_end = 0;
bool check(int i, int j) {
int now = m[i][j] / 10;
for (int x = 0; x < 10; x ++) {
for (int y = 0; y < 9; y ++) {
if (x == i && y == j) continue;
if (m[x][y] / 10 != now) {
if (m[x][y] % 10 == 1 && movecar(x, y, i, j)) return 1;
if (m[x][y] % 10 == 2 && movehorse(x, y, i, j)) return 1;
if (m[x][y] % 10 == 3 && moveguard(x, y, i, j)) return 1;
if (m[x][y] % 10 == 4 && moveelephant(x, y, i, j)) return 1;
if (m[x][y] % 10 == 5 && movecaptain(x, y, i, j)) return 1;
if (m[x][y] % 10 == 6 && moveduck(x, y, i, j)) return 1;
if (m[x][y] % 10 == 7 && movesoldier(x, y, i, j)) return 1;
}
}
}
return 0;
}
int main(){
init();
while (q --) {
int xs, ys, xt, yt;
cin >> xs >> ys >> xt >> yt;
int s = m[xs][ys], t = m[xt][yt];
// cout << s << '\n';
if (is_end || !s) {
cout << "Invalid command\n";
continue;
}
if (s / 10 != step % 2) {
cout << "Invalid command\n";
continue;
}
if (s % 10 == 1) {
if (!movecar(xs, ys, xt, yt)) {
cout << "Invalid command\n";
continue;
}
}
else if (s % 10 == 2) {
if (!movehorse(xs, ys, xt, yt)) {
cout << "Invalid command\n";
continue;
}
}
else if (s % 10 == 3) {
if (!moveguard(xs, ys, xt, yt)) {
cout << "Invalid command\n";
continue;
}
}
else if (s % 10 == 4) {
if (!moveelephant(xs, ys, xt, yt)) {
cout << "Invalid command\n";
continue;
}
}
else if (s % 10 == 5) {
if (!movecaptain(xs, ys, xt, yt)) {
cout << "Invalid command\n";
continue;
}
}
else if (s % 10 == 6) {
if (!moveduck(xs, ys, xt, yt)) {
cout << "Invalid command\n";
continue;
}
}
else if (s % 10 == 7) {
if (!movesoldier(xs, ys, xt, yt)) {
cout << "Invalid command\n";
continue;
}
}
m[xt][yt] = m[xs][ys];
m[xs][ys] = 0;
cout << m2[s / 10] << ' ' << m1[s % 10];
cout << ';';
if (t) {
cout << m2[t / 10] << ' ' << m1[t % 10];
}
else {
cout << "NA";
}
cout << ';';
if (t % 10 == 5) {
is_end = 1;
}
if (is_end) cout << "no";
else {
bool flag = 0;
for (int i = 0; i < 10; i ++) {
for (int j = 0; j < 9; j ++) {
if (m[i][j] % 10 == 5) {
if (check(i, j)) {
flag = 1;
break;
}
}
}
}
if (flag) cout << "yes";
else cout << "no";
}
cout << ';';
if (is_end) cout << "yes";
else cout << "no";
cout << '\n';
step++;
}
return 0;
}