Bootstrap

C++中国象棋

玩法:P1先输入,P2再输入,输入格式:

旗子位置:列(数字形式)+空格+行(数字形式)+换行

移动到的位置:列(数字形式)+空格+行(数字形式)+换行

如果输入的走法错误将会提醒并重新输入!

其他规则与标准中国象棋规则相同。

注:输入坐标时请勿输入汉字一二三四五六七八九十!


#include<iostream>
#include<cstring>
#include<cstdlib>
#include<windows.h>
#include<cmath>
using namespace std;
class Chessboard;
class Chess
{
private:
    int Id;
public:
    Chess(int x) :Id(x) {}
    int Get()                //取ID
    {
        return Id;
    }
    virtual bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy) = 0;//判断走步合理性
    virtual ~Chess() {}
};
class Chessboard
{
private:
    Chess *c[10][11];        //棋盘:X为横(9),Y为纵(10),从1开始记
    char Chessword[15][4] = { "兵","炮","车","马","相","仕","帅"," ","将","士","象","馬","車","砲","卒" };
public:
    static int Player;       //上半区为1,下半区为-1
    static bool End;         //判断是否结束
    Chessboard();
    Chess *Get(int x, int y);//返回指定点的指针
    int Getid(int x, int y);//返回指定点处棋子ID的指针
    bool Move(int startx, int starty, int endx, int endy);  //移动
    void Init();               //初始化棋子
    void Show();               //打印
    void Play();               //开始游戏
    ~Chessboard();
};
class General :public Chess//将、帅类,ID为-1和1
{
public:
    General(int i) :Chess((i == 0 ? -1 : 1)) {}
    bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy)
    {
        int TempX = startx - endx;
        int TempY = starty - endy;
        int S_Id = ch.Getid(startx, starty);
        int E_Id = ch.Getid(endx, endy);
        if ((S_Id*E_Id <= 0) && (TempX*TempX + TempY * TempY == 1) && (endx >= 4 && endx <= 6) && (endy >= 1 && endy <= 3 || endy >= 8 && endy <= 10))
        {
            return true;
        }
        return false;
    }
    ~General()
    {
        Chessboard::End = false;
    }
};
class BodyGuard :public Chess//士、仕类,ID为-2和2
{
public:
    BodyGuard(int i) :Chess((i == 0 ? -2 : 2)) {}
    bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy)
    {
        int TempX = startx - endx;
        int TempY = starty - endy;
        int S_Id = ch.Getid(startx, starty);
        int E_Id = ch.Getid(endx, endy);
        if ((S_Id*E_Id <= 0) && (TempX*TempX + TempY * TempY == 2) && (endx >= 4 && endx <= 6) && (endy >= 1 && endy <= 3 || endy >= 8 && endy <= 10))
        {
            return true;
        }
        return false;
    }
};
class Chancellor :public Chess//象、相类,ID为-3和3
{
public:
    Chancellor(int i) :Chess((i == 0 ? -3 : 3)) {}
    bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy)
    {
        int TempX = startx - endx;
        int TempY = starty - endy;
        int S_Id = ch.Getid(startx, starty);
        int E_Id = ch.Getid(endx, endy);
        if ((S_Id*E_Id <= 0) && (TempX*TempX + TempY * TempY == 8) && (endx % 2 != 0 && endx >= 1 && endy <= 9) && ((starty - 1) / 5 == (endy - 1) / 5) && !ch.Get(startx + (TempX / 2), starty + (TempY / 2)))
        {
            return true;
        }
        return false;
    }
};
class Horse :public Chess//馬、马类,ID为-4和4
{
public:
    Horse(int i) :Chess((i == 0 ? -4 : 4)) {}
    bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy)
    {
        int TempX = startx - endx;
        int TempY = starty - endy;
        int S_Id = ch.Getid(startx, starty);
        int E_Id = ch.Getid(endx, endy);
        if ((S_Id*E_Id <= 0) && (TempX*TempX + TempY * TempY == 5) && !ch.Get(startx + (TempX / 2), starty + (TempY / 2)))
        {
            return true;
        }
        return false;
    }
};
class Chariot :public Chess//車、车类,ID为-5和5
{
public:
    Chariot(int i) :Chess((i == 0 ? -5 : 5)) {}
    bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy)
    {
        int TempX = startx - endx;
        int TempY = starty - endy;
        int S_Id = ch.Getid(startx, starty);
        int E_Id = ch.Getid(endx, endy);
        if ((S_Id*E_Id <= 0) && (!(TempX&&TempY)) && (TempX + TempY))
        {
            if (TempX)
            {
                int Sign = (TempX > 0 ? -1 : 1);
                for (int i = 1; i < fabs(TempX); i++)
                {
                    if (ch.Get(startx + Sign * i, starty))
                    {
                        return false;
                    }
                }
            }
            else
            {
                int Sign = (TempY > 0 ? -1 : 1);
                for (int i = 1; i < fabs(TempY); i++)
                {
                    if (ch.Get(startx, starty + Sign * i))
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        return false;
    }
};
class Cannon :public Chess//砲、炮类,ID为-6和6
{
public:
    Cannon(int i) :Chess((i == 0 ? -6 : 6)) {}
    bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy)
    {
        int TempX = startx - endx;
        int TempY = starty - endy;
        int S_Id = ch.Getid(startx, starty);
        int E_Id = ch.Getid(endx, endy);
        if ((S_Id*E_Id <= 0) && (!(TempX&&TempY)) && (TempX + TempY))
        {
            int Tmp = 0;
            if (TempX)
            {
                int Sign = (TempX > 0 ? -1 : 1);
                for (int i = 1; i < fabs(TempX); i++)
                {
                    if (ch.Get(startx + Sign * i, starty))
                    {
                        Tmp++;
                    }
                }
            }
            else
            {
                int Sign = (TempY > 0 ? -1 : 1);
                for (int i = 1; i < fabs(TempY); i++)
                {
                    if (ch.Get(startx, starty + Sign * i))
                    {
                        Tmp++;
                    }
                }
            }
            if (E_Id)
            {
                if (Tmp == 1)
                {
                    return true;
                }
            }
            else
            {
                if (!Tmp)
                {
                    return true;
                }
            }
        }
        return false;
    }
};
class Soldier :public Chess//卒、兵类,ID为-7和7
{
public:
    Soldier(int i) :Chess((i == 0 ? -7 : 7)) {}
    bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy)
    {
        int TempX = startx - endx;
        int TempY = starty - endy;
        int S_Id = ch.Getid(startx, starty);
        int E_Id = ch.Getid(endx, endy);
        if ((S_Id*E_Id <= 0) && (S_Id*TempY <= 0))
        {
            if (fabs(TempY) == 1 && TempX == 0)
            {
                return true;
            }
            if (fabs(TempX) == 1 && TempY == 0)
            {
                if (((starty - 1) / 5 == 0 && S_Id < 0) || ((starty - 1) / 5 == 1 && S_Id > 0))
                {
                    return true;
                }
            }
        }
        return false;
    }
};
int Chessboard::Player = -1;
bool Chessboard::End = true;
inline Chessboard::Chessboard()
{
    memset(c, NULL, sizeof(c));
}
inline Chess * Chessboard::Get(int x, int y)
{
    return c[x][y];
}
int Chessboard::Getid(int x, int y)
{
    if (c[x][y] != NULL)
    {
        return c[x][y]->Get();
    }
    return NULL;
}
bool Chessboard::Move(int startx, int starty, int endx, int endy)
{
    if (startx >= 1 && startx <= 9 && starty >= 1 && starty <= 10 && endx >= 1 && endx <= 9 && endy >= 1 && endy <= 10 && Getid(startx, starty) && Getid(startx, starty)*Player > 0 && c[startx][starty]->Judgement(*this, startx, starty, endx, endy))
    {
        if (c[endx][endy] != NULL)
        {
            delete c[endx][endy];           //吃子
        }
        c[endx][endy] = c[startx][starty];
        c[startx][starty] = NULL;
        Player *= -1;                       //更换玩家操作
        return true;
    }
    else
    {
        cout << "走法错误,请重新输入:" << endl;
        return false;
    }
}
void Chessboard::Init()
{
    c[1][1] = new Chariot(1);
    c[9][1] = new Chariot(1);
    c[2][1] = new Horse(1);
    c[8][1] = new Horse(1);
    c[3][1] = new Chancellor(1);
    c[7][1] = new Chancellor(1);
    c[4][1] = new BodyGuard(1);
    c[6][1] = new BodyGuard(1);
    c[5][1] = new General(1);
    c[2][3] = new Cannon(1);
    c[8][3] = new Cannon(1);
    c[1][4] = new Soldier(1);
    c[3][4] = new Soldier(1);
    c[5][4] = new Soldier(1);
    c[7][4] = new Soldier(1);
    c[9][4] = new Soldier(1);
    c[1][10] = new Chariot(0);
    c[9][10] = new Chariot(0);
    c[2][10] = new Horse(0);
    c[8][10] = new Horse(0);
    c[3][10] = new Chancellor(0);
    c[7][10] = new Chancellor(0);
    c[4][10] = new BodyGuard(0);
    c[6][10] = new BodyGuard(0);
    c[5][10] = new General(0);
    c[2][8] = new Cannon(0);
    c[8][8] = new Cannon(0);
    c[1][7] = new Soldier(0);
    c[3][7] = new Soldier(0);
    c[5][7] = new Soldier(0);
    c[7][7] = new Soldier(0);
    c[9][7] = new Soldier(0);
}
void Chessboard::Show()
{
    cout << endl;
    HANDLE handle;
    handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(handle, 0xF0);
    cout << "     P2  一 二 三 四 五 六 七 八 九" << endl << endl;
    char num[11][4] = { "零","一","二","三","四","五","六","七","八","九" ,"十" };
    for (int i = 1; i < 11; i++)
    {
        if (i == 6)
        {
            SetConsoleTextAttribute(handle, 0xF0);
            cout << "          ————楚河 汉界————" << endl << endl;
        }
        SetConsoleTextAttribute(handle, 0xF0);
        cout << "     " << num[i] << "  ";
        for (int j = 1; j < 10; j++)
        {
            if (c[j][i] != NULL)
            {
                if (c[j][i]->Get() > 0)
                {
                    SetConsoleTextAttribute(handle, 0xF2);
                    cout << Chessword[c[j][i]->Get() + 7] << " ";
                }
                else
                {
                    SetConsoleTextAttribute(handle, 0xFC);
                    cout << Chessword[c[j][i]->Get() + 7] << " ";
                }
            }
            else if ((i == 2 && j == 5) || (i == 9 && j == 5))
            {
                SetConsoleTextAttribute(handle, 0xF0);
                cout << "米" << " ";
            }
            else
            {
                SetConsoleTextAttribute(handle, 0xF0);
                cout << "十" << " ";
            }
        }
        cout << endl << endl;
    }
    SetConsoleTextAttribute(handle, 0xF0);
    cout << "     P1  一 二 三 四 五 六 七 八 九" << endl << endl;
}
void Chessboard::Play()
{
    HANDLE handle;
    handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(handle, 0xFC);
    system("cls");
    this->Init();
    this->Show();
    do
    {
        int startx, starty, aimx, aimy, iflag;
        int sid, aid;
        iflag = 0;
        do
        {
            sid = aid = 0;
            if ((Chessboard::Player == 1 ? 2 : 1) == 1)
            {
                SetConsoleTextAttribute(handle, 0xFC);
            }
            else
            {
                SetConsoleTextAttribute(handle, 0xF2);
            }
            cout << "请P" << (Chessboard::Player == 1 ? 2 : 1) << "输入起始棋子位置与目标位置的坐标:" << endl;
            cin >> startx >> starty >> aimx >> aimy;
        } while (!this->Move(startx, starty, aimx, aimy));
        system("cls");
        this->Show();
        for (int i = 4; i < 7; i++)
        {
            for (int j = 1; j < 11; j++)
            {
                if (c[i][j] != NULL)
                {
                    if ((int)fabs(c[i][j]->Get()) == 1)
                    {
                        iflag++;
                    }
                    else if (iflag != 0 && iflag != 2)
                    {
                        if ((int)fabs(c[i][j]->Get()) != 1)
                        {
                            iflag--;
                        }
                    }
                }
            }
        }
        if (iflag == 2)
        {
            Player *= -1;
            Chessboard::End = false;
        }
    } while (Chessboard::End);
    if ((Chessboard::Player == 1 ? 1 : 2) == 1)
    {
        SetConsoleTextAttribute(handle, 0xFC);
    }
    else
    {
        SetConsoleTextAttribute(handle, 0xF2);
    }
    cout << "结束,赢家是Player" << (Chessboard::Player == 1 ? 1 : 2) << endl;
}
Chessboard::~Chessboard()
{
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 11; j++)
        {
            if (c[i][j] != NULL)
            {
                delete c[i][j];
                c[i][j] = NULL;
            }
        }
    }
}
using namespace std;
int main()
{
    Chessboard C;
    C.Play();
    system("pause");
}

;