【C++】C++下的简易中国象棋

参考自Originum学长的博客,个人进行了一些小修改,
原博客地址:https://blog.csdn.net/Originum/article/details/80356452
联系邮箱:Originum@126.com

本人博客地址:Megalomania

一个简单的中国象棋游戏,主要实现:
1、两人对弈;
2、简单的棋子移动以及规则判断,不符合规则便重走;
3、有一方获胜便结束游戏。

一、类的设计

  1. “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() {}
};
  1. “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()函数时,会判断:

  1. 传入的两个位置是否越界(超出了10*11数组的范围),越界则返回false。
  2. 传入的开始位置的点的id是否为零(当点上无棋子,也就是空指针的时候为零),若为零则返回false。
  3. 当前选的棋子是否是这一回对应那一方的棋子,若不是则返回false。
  4. 对当前棋子的具体规则进行判断(通过指针调用虚函数,判断该棋子的具体规则)。若错误则返回false。

若以上判断都准确无误,则把棋子走到对应位置:

  1. 不吃子:目标位置为空指针时,把目标位置的指针指向该棋子对象,把棋子的起始位置指针赋值NULL,设为空指针。
  2. 吃子:delete目标位置的棋子对象,该棋子被吃。把目标位置的指针指向该棋子对象,把棋子的起始位置指针赋值NULL,设为空指针。

四、判断结束

判断结束:

  1. 棋盘类有一个静态变量bool End, 初始化为true。当将(帅)对象被析构时,把end赋值为false,表示棋局结束,退出走棋的循环(while(chessboard :: end)控制走棋是否继续)。
~General()
	{
		Chessboard::End = false;
	}
  1. 当有一位玩家的某一步棋使双方的将(帅)面对面时,直接判负。具体实现是检测将(帅)所在的4、5、6
中国象棋C++代码 #include "chess_zn.h" QTcpSocket * Chess_ZN::client = new QTcpSocket; QUndoStack * Chess_ZN::undoStack = new QUndoStack(); int Chess_ZN::second = 120; bool Chess_ZN::isTurn = false; Chess_ZN::Chess_ZN(QWidget *parent) : QWidget(parent) { init(); initElse(); } void Chess_ZN::initElse(){ treeitem = 1; timer=new QTimer; portmap=0; isConn = true; start = false; isTimer = false; isSearch = false; connect(timer,SIGNAL(timeout()),this,SLOT(stopWatch())); connect(wigettree[1],SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(getInfo(QTreeWidgetItem*))); connect(wigettree[0],SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(connectToHost_PK(QTreeWidgetItem*))); connect(client,SIGNAL(connected()),this,SLOT(connected())); //连接一旦断开 connect(client,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error(QAbstractSocket::SocketError ))); connect(client,SIGNAL(readyRead()),this,SLOT(readyRead())); peer = new PeerManager(this); peer->setServerPort(10001); items=wigettree[1]->currentItem(); item_pk=wigettree[0]->currentItem(); item_pk_info=wigettree[0]->currentItem(); connect(undoStack, SIGNAL(canUndoChanged(bool)),action2[8], SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canUndoChanged(bool)),action2[9], SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canUndoChanged(bool)),action2[10], SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canUndoChanged(bool)),action2[11], SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canUndoChanged(bool)),button[0], SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canUndoChanged(bool)),button[1], SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canUndoChanged(bool)),button[2], SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canUndoChanged(bool)),button[3], SLOT(setEnabled(bool))); timer->start(1000); createUndoView(); isChoose = true; tableeditor=new TableEditor("users"); } void Chess_ZN::createUndoView() { undoVie
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值