P5380 Code

题面

#include <bits/stdc++.h>
using namespace std;

enum chess //棋子种类
{
    NA,       //无(这个位置是空的)
    captain,  //王
    guard,    //士
    elephant, //象
    horse,    //马
    car,      //车
    duck,     //鸭
    soldier   //兵
};
enum belong_type //记录每颗棋子属于何方的类型
{
    RED,  //属于红方
    BLUE, //属于蓝方
    NOT   //不属于任何一方(即没有棋子)
};

const int walk_set[2] = {1, -1};               //移动中会使用到的集合
const string rank_string[2] = {"red", "blue"}; //输出棋子属于哪方时会用到的
const string chess_string[8] = {"NA", "captain", "guard", "elephant", "horse", "car", "duck", "soldier"};
//输出棋子名称时会用到的

chess board[10][9];             //棋盘,每一位上保存这一位的棋子种类
belong_type belong[10][9];      //保存棋盘上每一位上的棋子属于哪方
bool CHECK_MATE, GAME_OVER;     //将军局面,和游戏是否结束
int CAPTAIN_X[2], CAPTAIN_Y[2]; //存放双方的王的坐标

bool captian_move(int start_x, int start_y, int end_x, int end_y)
{
    for (int x = 0; x < 2; x++)
    {
        int to_x = start_x + walk_set[x], to_y = start_y;
        if (end_x == to_x && end_y == to_y)
        {
            CAPTAIN_X[belong[start_x][start_y]] = end_x;
            CAPTAIN_Y[belong[start_x][start_y]] = end_y;
            return true;
        }
    }
    for (int y = 0; y < 2; y++)
    {
        int to_x = start_x, to_y = start_y + walk_set[y];
        if (end_x == to_x && end_y == to_y)
        {
            CAPTAIN_X[belong[start_x][start_y]] = end_x;
            CAPTAIN_Y[belong[start_x][start_y]] = end_y;
            return true;
        }
    }
    return false;
}
bool guard_move(int start_x, int start_y, int end_x, int end_y)
{
    for (int x = 0; x < 2; x++)
    {
        int to_x = start_x + walk_set[x], to_y = start_y + walk_set[x];
        if (end_x == to_x && end_y == to_y)
            return true;
    }
    for (int x = 0; x < 2; x++)
    {
        int to_x = start_x + walk_set[x], to_y = start_y + walk_set[!x];
        if (end_x == to_x && end_y == to_y)
            return true;
    }
    return false;
}
bool elephant_move(int start_x, int start_y, int end_x, int end_y)
{
    for (int x = 0; x < 2; x++)
        for (int y = 0; y < 2; y++)
        {
            if (belong[start_x + walk_set[x]][start_y + walk_set[y]] != NOT)
                continue;
            int to_x = start_x + (walk_set[x] << 1), to_y = start_y + (walk_set[y] << 1);
            if (end_x == to_x && end_y == to_y)
                return true;
        }
    return false;
}
bool horse_move(int start_x, int start_y, int end_x, int end_y)
{
    for (int x = 0; x < 2; x++)
        for (int y = 0; y < 2; y++)
        {
            if (belong[start_x + walk_set[x]][start_y] != NOT)
                continue;
            int to_x = start_x + (walk_set[x] << 1), to_y = start_y + walk_set[y];
            if (end_x == to_x && end_y == to_y)
                return true;
        }
    for (int x = 0; x < 2; x++)
        for (int y = 0; y < 2; y++)
        {
            if (belong[start_x][start_y + walk_set[y]] != NOT)
                continue;
            int to_x = start_x + walk_set[x], to_y = start_y + (walk_set[y] << 1);
            if (end_x == to_x && end_y == to_y)
                return true;
        }
    return false;
}
bool car_move(int start_x, int start_y, int end_x, int end_y)
{
    if (start_x == end_x)
    {
        bool check = true;
        for (int y = min(start_y, end_y) + 1; y < max(start_y, end_y); y++)
            check &= belong[start_x][y] == NOT;
        if (check)
            return true;
    }
    if (start_y == end_y)
    {
        bool check = true;
        for (int x = min(start_x, end_x) + 1; x < max(start_x, end_x); x++)
            check &= belong[x][start_y] == NOT;
        if (check)
            return true;
    }
    return false;
}
bool duck_move(int start_x, int start_y, int end_x, int end_y)
{
    for (int x = 0; x < 2; x++)
        for (int y = 0; y < 2; y++)
        {
            if (belong[start_x + (walk_set[x] << 1)][start_y + walk_set[y]] != NOT ||
                belong[start_x + walk_set[x]][start_y] != NOT)
                continue;
            int to_x = start_x + (walk_set[x] << 1) + walk_set[x], to_y = start_y + (walk_set[y] << 1);
            if (end_x == to_x && end_y == to_y)
                return true;
        }
    for (int x = 0; x < 2; x++)
        for (int y = 0; y < 2; y++)
        {
            if (belong[start_x + walk_set[x]][start_y + (walk_set[y] << 1)] != NOT ||
                belong[start_x][start_y + walk_set[y]] != NOT)
                continue;
            int to_x = start_x + (walk_set[x] << 1), to_y = start_y + (walk_set[y] << 1) + walk_set[y];
            if (end_x == to_x && end_y == to_y)
                return true;
        }
    return false;
}
bool soldier_move(int start_x, int start_y, int end_x, int end_y)
{
    for (int x = 0; x < 2; x++)
    {
        int to_x = start_x + walk_set[x], to_y = start_y;
        if (end_x == to_x && end_y == to_y)
            return true;
    }
    for (int x = 0; x < 2; x++)
    {
        int to_x = start_x, to_y = start_y + walk_set[x];
        if (end_x == to_x && end_y == to_y)
            return true;
    }
    for (int x = 0; x < 2; x++)
    {
        int to_x = start_x + walk_set[x], to_y = start_y + walk_set[x];
        if (end_x == to_x && end_y == to_y)
            return true;
    }
    for (int x = 0; x < 2; x++)
    {
        int to_x = start_x + walk_set[x], to_y = start_y + walk_set[x ^ 1];
        if (end_x == to_x && end_y == to_y)
            return true;
    }
    return false;
}

bool choose(int start_x, int start_y, int end_x, int end_y)
{
    switch (board[start_x][start_y])
    {
    case captain:
        return captian_move(start_x, start_y, end_x, end_y);
        break;
    case guard:
        return guard_move(start_x, start_y, end_x, end_y);
        break;
    case elephant:
        return elephant_move(start_x, start_y, end_x, end_y);
        break;
    case horse:
        return horse_move(start_x, start_y, end_x, end_y);
        break;
    case car:
        return car_move(start_x, start_y, end_x, end_y);
        break;
    case duck:
        return duck_move(start_x, start_y, end_x, end_y);
        break;
    case soldier:
        return soldier_move(start_x, start_y, end_x, end_y);
        break;
    }
    return false;
}

bool work(int start_x, int start_y, int end_x, int end_y, belong_type turn)
{
    if (GAME_OVER || belong[start_x][start_y] != turn || belong[end_x][end_y] == turn)
        return false;//游戏结束,或者这颗棋子不是自己的,或者目的地有自己的棋子
    if (!choose(start_x, start_y, end_x, end_y))
        return false;//如果不能移动
    chess moved_chess = board[end_x][end_y];//存放被移走的棋子
    board[end_x][end_y] = board[start_x][start_y];
    belong[end_x][end_y] = belong[start_x][start_y];
    board[start_x][start_y] = NA;
    belong[start_x][start_y] = NOT;
    if (moved_chess == captain)//如果王被移走,游戏结束
        GAME_OVER = true;
    CHECK_MATE = false;//开始准备判定将军局面
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 9; j++)
            if (belong[i][j] != NOT)//如果有棋子,我们直接判断它是否能攻击到对方王的位置
                CHECK_MATE |= choose(i, j, CAPTAIN_X[!belong[i][j]], CAPTAIN_Y[!belong[i][j]]);
    printf("%s %s;%s;%s;%s\n", rank_string[turn].c_str(), chess_string[board[end_x][end_y]].c_str(),
           moved_chess == NA ? "NA" : (rank_string[!turn] + " " + chess_string[moved_chess]).c_str(),
           CHECK_MATE ? "yes" : "no", GAME_OVER ? "yes" : "no");//输出
    return true;
}

void restart(void)
{
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 9; j++)
            belong[i][j] = NOT;
    board[0][4] = board[9][4] = captain;
    board[0][3] = board[0][5] = board[9][3] = board[9][5] = guard;
    board[0][2] = board[0][6] = board[9][2] = board[9][6] = elephant;
    board[0][1] = board[0][7] = board[9][1] = board[9][7] = horse;
    board[0][0] = board[0][8] = board[9][0] = board[9][8] = car;
    board[2][0] = board[2][8] = board[7][0] = board[7][8] = duck;
    board[3][0] = board[3][2] = board[3][4] = board[3][6] = board[3][8] =
        board[6][0] = board[6][2] = board[6][4] = board[6][6] = board[6][8] = soldier;
    belong[0][0] = belong[0][1] = belong[0][2] = belong[0][3] = belong[0][4] = belong[0][5] = belong[0][6] = belong[0][7] = belong[0][8] =
        belong[2][0] = belong[2][8] = belong[3][0] = belong[3][2] = belong[3][4] = belong[3][6] = belong[3][8] = RED;
    belong[9][0] = belong[9][1] = belong[9][2] = belong[9][3] = belong[9][4] = belong[9][5] = belong[9][6] = belong[9][7] = belong[9][8] =
        belong[7][0] = belong[7][8] = belong[6][0] = belong[6][2] = belong[6][4] = belong[6][6] = belong[6][8] = BLUE;
    CAPTAIN_X[RED] = 0;
    CAPTAIN_Y[RED] = 4;
    CAPTAIN_X[BLUE] = 9;
    CAPTAIN_Y[BLUE] = 4;
    GAME_OVER = false;
    return;
}

int main()
{
    int Q;
    scanf("%d", &Q);
    restart();
    belong_type turn = RED;
    while (Q--)
    {
        int start_x, start_y, end_x, end_y;
        scanf("%d%d%d%d", &start_x, &start_y, &end_x, &end_y);
        if (work(start_x, start_y, end_x, end_y, turn))
            if (turn == RED) //回合变化
                turn = BLUE;
            else
                turn = RED;
        else
            puts("Invalid command"); //不合法操作
    }
    return 0;
}
posted @ 2020-05-14 07:20  Macesuted  阅读(67)  评论(0编辑  收藏  举报