玩法: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");
}