参考自Originum学长的博客,个人进行了一些小修改,
原博客地址:https://blog.csdn.net/Originum/article/details/80356452
联系邮箱:Originum@126.com
本人博客地址:Megalomania
一个简单的中国象棋游戏,主要实现:
1、两人对弈;
2、简单的棋子移动以及规则判断,不符合规则便重走;
3、有一方获胜便结束游戏。
一、类的设计
- “Chess”类:
(1) 私有成员有int型的Id,用于记录棋子的归属以及判断轮到的玩家是否可以移动;
(2) 公共成员函数有Get函数来获取Id,以及判断走法是否正确的Judgement纯虚函数;
(3) 作为基类来派生出其他棋子的类。
具体代码如下:
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() {}
};
- “Chessboard”类:
(1) 私有成员有一个10*11的指向Chess类的指针(为了方便操作将0的位置腾了出来),用于存放棋子的地址;
(2) 还有一个Char型的Chessword数组用于存放棋子的名字(一个汉字占4个Char型空间);
(3) 公共成员部分有static int型的 Player用于记录轮到哪个玩家以及哪个玩家获胜。
具体实现代码如下:
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();
};
二、具体变量的意义
红方棋子:“兵”,“炮”,“车”,“马”,“相”,“仕”,“帅”
Id为:7 6 5 4 3 2 1
绿方棋子:“将”,“士”,“象”,“馬”,“車”,“砲”,“卒”
Id为:-1 -2 - 3 -4 -5 -6 -7
用于实现移动的变量:
startx,starty: 开始的位置;
endx,endy:目标的位置;
S_Id: 存储开始位置的棋子的编号,若该点没有棋子(空指针),则值为0;
E_Id: 存储目标位置的棋子的编号,若该点没有棋子(空指针),则值为0;
TempX: 开始位置到目标位置的x坐标的偏移量(startx-endx);
TempY: 开始位置到目标位置的y坐标的偏移量(starty-endy)。
三、实现走棋
每次把位置信息传到Chessboard类的Move()函数时,会判断:
- 传入的两个位置是否越界(超出了10*11数组的范围),越界则返回false。
- 传入的开始位置的点的id是否为零(当点上无棋子,也就是空指针的时候为零),若为零则返回false。
- 当前选的棋子是否是这一回对应那一方的棋子,若不是则返回false。
- 对当前棋子的具体规则进行判断(通过指针调用虚函数,判断该棋子的具体规则)。若错误则返回false。
若以上判断都准确无误,则把棋子走到对应位置:
- 不吃子:目标位置为空指针时,把目标位置的指针指向该棋子对象,把棋子的起始位置指针赋值NULL,设为空指针。
- 吃子:delete目标位置的棋子对象,该棋子被吃。把目标位置的指针指向该棋子对象,把棋子的起始位置指针赋值NULL,设为空指针。
四、判断结束
判断结束:
- 棋盘类有一个静态变量bool End, 初始化为true。当将(帅)对象被析构时,把end赋值为false,表示棋局结束,退出走棋的循环(while(chessboard :: end)控制走棋是否继续)。
~General()
{
Chessboard::End = false;
}
- 当有一位玩家的某一步棋使双方的将(帅)面对面时,直接判负。具体实现是检测将(帅)所在的4、5、6