中国象棋游戏Chess(3) - 实现走棋规则
棋盘的绘制和走棋参看博文:中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制,中国象棋游戏Chess(2)
- 走棋
现在重新整理之前写的代码,并且对于每个棋子的走棋规则都进行了限制,不像之前那样每个棋子都可以走到任意位置。
也实现了红先黑后,并且每一方走一步,交替走棋的功能。
直接看代码:
- // Board.h
- // Board类实现了棋盘的绘制以及显示
- //
- #ifndef BOARD_H
- #define BOARD_H
- #include <QFrame>
- #include "Stone.h"
- #include "Step.h"
- #include <QVector>
- class Board : public QFrame
- {
- Q_OBJECT
- public:
- explicit Board(QWidget *parent = 0);
- ~Board();
- /*===> 游戏数据 <===*/
- Stone _s[32]; // 定义32个棋子
- int _r; // 棋子的半径
- QPoint _off;
- bool _bSide;
- QVector<Step*> _steps; // 悔棋时使用
- /*===> 游戏状态 <===*/
- int _selectid;
- bool _bRedTurn;
- void init(bool bRedSide);
- /*===> 绘图函数 <===*/
- virtual void paintEvent(QPaintEvent *);
- void DrawBackground(); // 设置背景颜色
- void drawPlate(QPainter& p); // 绘制棋盘
- void drawPlace(QPainter& p); // 绘制九宫格
- void drawInitPosition(QPainter& p); // 绘制炮兵位置上的十字
- void drawInitPosition(QPainter& p, int row, int col);
- void drawStone(QPainter &p); // 绘制棋子
- void drawStone(QPainter &p, int id);
- /*===> 坐标转换相关函数 <===*/
- QPoint center(int row, int col); // 返回棋盘行列对应的像素坐标
- QPoint center(int id);
- QPoint topLeft(int row, int col);
- QPoint topLeft(int id);
- QRect cell(int row, int col);
- QRect cell(int id);
- bool getClickRowCol(QPoint pt, int &row, int &col);
- /*===> 帮助函数 <===*/
- QString name(int id);
- bool red(int id);
- bool sameColor(int id1, int id2);
- int getStoneId(int row, int col); // 获取行row列col上的棋子id
- void killStone(int id);
- void reliveStone(int id);
- void moveStone(int moveid, int row, int col);
- bool isDead(int id); // 判断id棋子是否死亡
- /*===> 移动相关函数 <===*/
- virtual void mouseReleaseEvent(QMouseEvent *ev); // 鼠标点击象棋并释放鼠标时候触发
- void click(QPoint pt);
- virtual void click(int id, int row, int col);
- void trySelectStone(int id);
- void tryMoveStone(int killid, int row, int col);
- void moveStone(int moveid, int killid, int row, int col);
- void saveStep(int moveid, int killid, int row, int col, QVector<Step*>& steps);
- void backOne();
- void back(Step* step);
- virtual void back();
- /*===> 移动规则 <===*/
- bool canMove(int moveid, int killid, int row, int col);
- bool canMoveJiang(int moveid, int killid, int row, int col);
- bool canMoveShi(int moveid, int, int row, int col);
- bool canMoveXiang(int moveid, int, int row, int col);
- bool canMoveChe(int moveid, int, int row, int col);
- bool canMoveMa(int moveid, int killid, int row, int col);
- bool canMovePao(int moveid, int killid, int row, int col);
- bool canMoveBing(int moveid, int killid, int row, int col);
- bool canSelect(int id);
- /*===> 移动规则相关的几个帮助函数 <===*/
- int relation(int row1, int col1, int row, int col); // 得到两点之间的关系值
- bool isBottomSide(int id); // 判断id棋子是否在棋盘下方
- // 判断两个点是否在同一条直线上,炮和车走棋的时候需要用到
- int getStoneCountAtLine(int row1, int col1, int row2, int col2);
- signals:
- public slots:
- void slotBack();
- };
- #endif // BOARD_H
- // Board.cpp
- #include "Board.h"
- #include <QPainter> // 绘制棋盘需要
- #include <QMouseEvent>
- #include <QDebug>
- #define GetRowCol(__row, __col, __id) \
- int __row = _s[__id]._row;\
- int __col = _s[__id]._col
- Board::Board(QWidget *parent) : QFrame(parent)
- {
- this->_r = 20;
- setMinimumSize(_r * 18 + 1, _r * 20 + 1);
- init(true);
- }
- Board::~Board()
- {
- }
- void Board::init(bool bRedSide)
- {
- for (int i = 0; i < 32; ++i) {
- _s[i].init(i);
- }
- if (bRedSide) {
- for (int i = 0; i < 32; ++i) {
- _s[i].rotate();
- }
- }
- _selectid = -1;
- _bRedTurn = true;
- _bSide = bRedSide;
- update();
- }
- // 绘制棋盘
- void Board::paintEvent(QPaintEvent *)
- {
- DrawBackground(); // 绘制背景颜色
- int r = height() / 20;
- _r = r;
- _off = QPoint(r + 1, r + 1);
- QPainter p(this);
- p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
- p.save();
- drawPlate(p);
- p.restore();
- p.save();
- drawPlace(p);
- p.restore();
- p.save();
- drawInitPosition(p);
- p.restore();
- p.save();
- drawStone(p);
- p.restore();
- }
- // 设置背景颜色
- void Board::DrawBackground()
- {
- QPalette p = this->palette();
- p.setColor(QPalette::Window, QColor(224, 255, 255));
- this->setPalette(p);
- }
- // 绘制棋盘
- void Board::drawPlate(QPainter &p)
- {
- // 绘制10条横线
- for (int i = 0; i < 10; ++i) {
- if (i == 0 || i == 9) { // 上下边框画笔设置的粗一些
- p.setPen(QPen(Qt::black, 3, Qt::SolidLine));
- }
- else {
- p.setPen(QPen(Qt::black, 1, Qt::SolidLine));
- }
- p.drawLine(center(i, 0), center(i, 8));
- }
- // 绘制9条竖线
- for (int i = 0; i < 9; ++i) {
- if (i == 0 || i == 8) { // 中间有楚河汉界,不能画通
- p.setPen(QPen(Qt::black, 3, Qt::SolidLine));
- p.drawLine(center(0, i), center(9, i));
- }
- else {
- p.setPen(QPen(Qt::black, 1, Qt::SolidLine));
- p.drawLine(center(0, i), center(4, i));
- p.drawLine(center(5, i), center(9, i));
- }
- }
- }
- // 绘制九宫格
- void Board::drawPlace(QPainter &p)
- {
- p.drawLine(center(0, 3), center(2, 5));
- p.drawLine(center(2, 3), center(0, 5));
- p.drawLine(center(9, 3), center(7, 5));
- p.drawLine(center(7, 3), center(9, 5));
- }
- // 绘制炮兵位置上的十字
- void Board::drawInitPosition(QPainter &p)
- {
- drawInitPosition(p, 3, 0);
- drawInitPosition(p, 3, 2);
- drawInitPosition(p, 3, 4);
- drawInitPosition(p, 3, 6);
- drawInitPosition(p, 3, 8);
- drawInitPosition(p, 6, 0);
- drawInitPosition(p, 6, 2);
- drawInitPosition(p, 6, 4);
- drawInitPosition(p, 6, 6);
- drawInitPosition(p, 6, 8);
- drawInitPosition(p, 2, 1);
- drawInitPosition(p, 2, 7);
- drawInitPosition(p, 7, 1);
- drawInitPosition(p, 7, 7);
- }
- void Board::drawInitPosition(QPainter& p, int row, int col)
- {
- QPoint pt = center(row, col);
- QPoint off = QPoint(_r / 6, _r / 6);
- int len = _r / 3;
- QPoint ptStart;
- QPoint ptEnd;
- if (col != 0) {
- // 左上角
- ptStart = QPoint(pt.x() - off.x(), pt.y() - off.y());
- ptEnd = ptStart + QPoint(-len, 0);
- p.drawLine(ptStart, ptEnd);
- ptEnd = ptStart + QPoint(0, -len);
- p.drawLine(ptStart, ptEnd);
- // 左下角
- ptStart = QPoint(pt.x() - off.x(), pt.y() + off.y());
- ptEnd = ptStart + QPoint(-len, 0);
- p.drawLine(ptStart, ptEnd);
- ptEnd = ptStart + QPoint(0, +len);
- p.drawLine(ptStart, ptEnd);
- }
- if (col != 8) {
- // 右下角
- ptStart = QPoint(pt.x() + off.x(), pt.y() + off.y());
- ptEnd = ptStart + QPoint(+len, 0);
- p.drawLine(ptStart, ptEnd);
- ptEnd = ptStart + QPoint(0, +len);
- p.drawLine(ptStart, ptEnd);
- // 右上角
- ptStart = QPoint(pt.x() + off.x(), pt.y() - off.y());
- ptEnd = ptStart + QPoint(+len, 0);
- p.drawLine(ptStart, ptEnd);
- ptEnd = ptStart + QPoint(0, -len);
- p.drawLine(ptStart, ptEnd);
- }
- }
- // 绘制棋子
- void Board::drawStone(QPainter &p)
- {
- for (int i = 0; i < 32; ++i) {
- drawStone(p, i);
- }
- }
- void Board::drawStone(QPainter &p, int id)
- {
- if (isDead(id)) {
- return;
- }
- QColor color;
- if (red(id)) {
- color = Qt::red;
- }
- else {
- color = Qt::black;
- }
- p.setPen(QPen(QBrush(color), 2));
- if (id == _selectid) {
- p.setBrush(Qt::gray);
- }
- else {
- p.setBrush(Qt::yellow);
- }
- p.drawEllipse(cell(id));
- p.setFont(QFont("system", _r * 1.2, 700)); // 设置字体大小和类型
- p.drawText(cell(id), name(id), QTextOption(Qt::AlignCenter));
- }
- // 返回棋盘行列对应的像素坐标
- QPoint Board::center(int row, int col)
- {
- QPoint pt(_r * col * 2, _r * row * 2);
- return pt + _off;
- }
- // 重载center函数,方便调用
- QPoint Board::center(int id)
- {
- return center(_s[id]._row, _s[id]._col);
- }
- QPoint Board::topLeft(int row, int col)
- {
- return center(row, col) - QPoint(_r, _r);
- }
- QPoint Board::topLeft(int id)
- {
- return center(id) - QPoint(_r, _r);
- }
- QRect Board::cell(int row, int col)
- {
- return QRect(topLeft(row, col), QSize(_r * 2 - 1, _r * 2 - 1));
- }
- QRect Board::cell(int id)
- {
- return QRect(topLeft(id), QSize(_r * 2 - 1, _r * 2 - 1));
- }
- // 判断点击位置属于哪个顶点
- // 返回值为bool类型是为了处理点击在棋盘外的情况
- bool Board::getClickRowCol(QPoint pt, int &row, int &col)
- {
- row = pt.y() / (2 * _r) - 1;
- col = pt.x() / (2 * _r) - 1;
- QPoint c = center(row, col);
- int dx = c.x() - pt.x();
- int dy = c.y() - pt.y();
- int dist = dx * dx + dy * dy; // 和鼠标所处矩形左上顶点的距离
- if (dist < _r * _r) {
- return true;
- }
- row += 1;
- c = center(row, col);
- dx = c.x() - pt.x();
- dy = c.y() - pt.y();
- dist = dx * dx + dy * dy; // 和鼠标所处矩形左下顶点的距离
- if (dist < _r * _r) {
- return true;
- }
- row -= 1;
- col += 1;
- c = center(row, col);
- dx = c.x() - pt.x();
- dy = c.y() - pt.y();
- dist = dx * dx + dy * dy; // 和鼠标所处矩形右上顶点的距离
- if (dist < _r * _r) {
- return true;
- }
- row += 1;
- c = center(row, col);
- dx = c.x() - pt.x();
- dy = c.y() - pt.y();
- dist = dx * dx + dy * dy; // 和鼠标所处矩形右下顶点的距离
- if (dist < _r * _r) {
- return true;
- }
- return false;
- }
- QString Board::name(int id)
- {
- return _s[id].name();
- }
- bool Board::red(int id)
- {
- return _s[id]._red;
- }
- bool Board::sameColor(int id1, int id2)
- {
- if (id1 == -1 || id2 == -1) {
- return false;
- }
- return red(id1) == red(id2);
- }
- int Board::getStoneId(int row, int col)
- {
- for (int i = 0; i < 32; ++i) {
- if (_s[i]._row == row &&
- _s[i]._col == col && !isDead(i)) {
- return i;
- }
- }
- return -1; // 如果不是棋子返回-1
- }
- void Board::killStone(int id)
- {
- if (id == -1) {
- return;
- }
- _s[id]._dead = true;
- }
- void Board::reliveStone(int id)
- {
- if (id == -1) {
- return;
- }
- _s[id]._dead = false;
- }
- void Board::moveStone(int moveid, int row, int col)
- {
- _s[moveid]._row = row;
- _s[moveid]._col = col;
- _bRedTurn = !_bRedTurn;
- }
- bool Board::isDead(int id)
- {
- if (id == -1) {
- return true;
- }
- return _s[id]._dead;
- }
- void Board::saveStep(int moveid, int killid, int row, int col, QVector<Step*>& steps)
- {
- GetRowCol(row1, col1, moveid);
- Step* step = new Step;
- step->_colFrom = col1;
- step->_colTo = col;
- step->_rowFrom = row1;
- step->_rowTo = row;
- step->_moveid = moveid;
- step->_killid = killid;
- steps.append(step);
- }
- void Board::backOne()
- {
- if (this->_steps.size() == 0) {
- return;
- }
- Step* step = this->_steps.last();
- _steps.removeLast();
- back(step);
- update();
- delete step;
- }
- void Board::back(Step* step)
- {
- reliveStone(step->_killid);
- moveStone(step->_moveid, step->_rowFrom, step->_colFrom);
- }
- void Board::back()
- {
- backOne();
- }
- void Board::mouseReleaseEvent(QMouseEvent *ev)
- {
- if (ev->button() != Qt::LeftButton) { // 排除鼠标右键点击
- return;
- }
- click(ev->pos());
- }
- void Board::click(QPoint pt)
- {
- // 看有没有点中象棋
- // 将pt转化成象棋的行列值
- // 判断这个行列值上面有没有棋子
- int row, col;
- bool bClicked = getClickRowCol(pt, row, col);
- if (!bClicked) {
- return;
- }
- int id = getStoneId(row, col);
- click(id, row, col);
- }
- void Board::click(int id, int row, int col)
- {
- if (this->_selectid == -1) { // 如果点中的棋子之前未被选中
- trySelectStone(id);
- }
- else {
- tryMoveStone(id, row, col);
- }
- }
- void Board::trySelectStone(int id)
- {
- if (id == -1) {
- return;
- }
- if (!canSelect(id)) {
- return;
- }
- _selectid = id;
- update();
- }
- void Board::tryMoveStone(int killid, int row, int col)
- {
- if (killid != -1 && sameColor(killid, _selectid)) {
- trySelectStone(killid);
- return;
- }
- bool ret = canMove(_selectid, killid, row, col);
- if (ret) {
- moveStone(_selectid, killid, row, col);
- _selectid = -1;
- update();
- }
- }
- void Board::moveStone(int moveid, int killid, int row, int col)
- {
- saveStep(moveid, killid, row, col, _steps);
- killStone(killid);
- moveStone(moveid, row, col);
- }
- bool Board::canMove(int moveid, int killid, int row, int col)
- {
- // 如果moveid和killid颜色相同,则不能移动,还需要换选择
- if (_s[moveid]._red == _s[killid]._red) {
- _selectid = killid;
- update();
- return false;
- }
- switch (_s[moveid]._type) {
- case Stone::JIANG:
- return canMoveJiang(moveid, killid, row, col);
- case Stone::SHI:
- return canMoveShi(moveid, killid, row, col);
- case Stone::XIANG:
- return canMoveXiang(moveid, killid, row, col);
- case Stone::CHE:
- return canMoveChe(moveid, killid, row, col);
- case Stone::MA:
- return canMoveMa(moveid, killid, row, col);
- case Stone::PAO:
- return canMovePao(moveid, killid, row, col);
- case Stone::BING:
- return canMoveBing(moveid, killid, row, col);
- }
- return true;
- }
- bool Board::canMoveJiang(int moveid, int killid, int row, int col)
- {
- // 可直接吃对方将
- if (killid != -1 && _s[killid]._type == Stone::JIANG)
- {
- return canMoveChe(moveid, killid, row, col);
- }
- GetRowCol(row1, col1, moveid);
- int r = relation(row1, col1, row, col);
- if (r != 1 || r != 10) {
- return false;
- }
- if (col < 3 || col > 5) {
- return false;
- }
- if (isBottomSide(moveid)) {
- if (row < 7) {
- return false;
- }
- }
- else {
- if (row > 2) {
- return false;
- }
- }
- return true;
- }
- bool Board::canMoveShi(int moveid, int, int row, int col)
- {
- // 移动步长一个格子对角线
- GetRowCol(row1, col1, moveid);
- int r = relation(row1, col1, row, col);
- if (r != 11) {
- return false;
- }
- if (col < 3 || col > 5) {
- return false;
- }
- if (isBottomSide(moveid)) {
- if (row < 7) {
- return false;
- }
- }
- else {
- if (row > 2) {
- return false;
- }
- }
- return true;
- }
- bool Board::canMoveXiang(int moveid, int, int row, int col)
- {
- GetRowCol(row1, col1, moveid);
- int r = relation(row1, col1, row, col);
- if (r != 22) { // 象走田,所以r应该等于22
- return false;
- }
- // 看象眼有没有棋子
- int rEye = (row + row1) / 2;
- int cEye = (col + col1) / 2;
- if (getStoneId(rEye, cEye) != -1) {
- return false;
- }
- // 判断是否在棋盘的下方
- if (isBottomSide(moveid)) {
- if (row < 4) {
- return false;
- }
- }
- else {
- if (row > 5) {
- return false;
- }
- }
- return true;
- }
- bool Board::canMoveChe(int moveid, int, int row, int col)
- {
- GetRowCol(row1, col1, moveid);
- int ret = getStoneCountAtLine(row1, col1, row, col);
- if (ret == 0) { // 在一行,并且中间没有棋子
- return true;
- }
- return false;
- }
- bool Board::canMoveMa(int moveid, int, int row, int col)
- {
- GetRowCol(row1, col1, moveid);
- int r = relation(row1, col1, row, col);
- // 首先判断马要走马字
- if (r != 12 && r != 21) {
- return false;
- }
- // 判断有没有蹩马腿的情况
- if (r == 12) { // 列相差等于2
- if (getStoneId(row1, (col + col1) / 2) != -1) {
- return false;
- }
- }
- else { // 行相差等于2
- if (getStoneId((row + row1) / 2, col1) != -1) {
- return false;
- }
- }
- return true;
- }
- bool Board::canMovePao(int moveid, int killid, int row, int col)
- {
- GetRowCol(row1, col1, moveid);
- int ret = getStoneCountAtLine(row, col, row1, col1);
- if (killid != -1) { // 如果炮要吃对方的棋子
- if (ret == 1) { // 中间有一个棋子,可以走
- return true;
- }
- }
- else { // 如果炮不吃棋子
- if (ret == 0) { // 中间没有棋子,可以走
- return true;
- }
- }
- return false;
- }
- bool Board::canMoveBing(int moveid, int, int row, int col)
- {
- GetRowCol(row1, col1, moveid);
- int r = relation(row1, col1, row, col);
- // 首先判断兵只能走一步
- if (r != 1 && r != 10) {
- return false;
- }
- if (isBottomSide(moveid)) { // 下面一方的棋子
- if (row > row1) { // 如果目标行大于原始行,相当于并在后退
- return false;
- }
- if (row1 >= 5 && row == row1) { // 还没有过河就想横着走
- return false;
- }
- }
- else { // 上面一方的棋子
- if (row1 > row) { // 如果目标行小于原始行,相当于兵在后退
- return false;
- }
- if (row <= 4 && row == row1) { // 还没有过河就想横着走
- return false;
- }
- }
- return true;
- }
- bool Board::canSelect(int id)
- {
- return _bRedTurn == _s[id]._red;
- }
- int Board::relation(int row1, int col1, int row, int col)
- {
- return qAbs(row1 - row) * 10 + qAbs(col1 - col);
- }
- bool Board::isBottomSide(int id)
- {
- return _bSide == _s[id]._red;
- }
- int Board::getStoneCountAtLine(int row1, int col1, int row2, int col2)
- {
- int ret = 0;
- // 首先判断两个棋子是否在同一条直线上,如果不在同一条直线上,直接返回-1
- if (row1 != row2 && col1 != col2) {
- return -1;
- }
- if (row1 == row2 && col1 == col2) {
- return -1;
- }
- // 计算两个棋子之间的有多少个棋子
- if (row1 == row2) { // 在同一行
- int min = col1 < col2 ? col1 : col2;
- int max = col1 > col2 ? col1 : col2;
- for (int col = min + 1; col < max; ++col) {
- if (getStoneId(row1, col) != -1) {
- ++ret;
- }
- }
- }
- else { // 在同一列
- int min = row1 < row2 ? row1 : row2;
- int max = row1 > row2 ? row1 : row2;
- for (int row = min + 1; row < max; ++row) {
- if (getStoneId(row, col1) != -1) {
- ++ret;
- }
- }
- }
- return ret;
- }
- void Board::slotBack()
- {
- back();
- }
- #ifndef STEP_H
- #define STEP_H
- #include <QObject>
- class Step : public QObject
- {
- Q_OBJECT
- public:
- explicit Step(QObject *parent = 0);
- ~Step();
- int _moveid;
- int _killid;
- int _rowFrom;
- int _colFrom;
- int _rowTo;
- int _colTo;
- signals:
- public slots:
- };
- #endif // STEP_H
- // Stone.h
- // 棋子类,存储了棋子的基础信息
- #ifndef STONE_H
- #define STONE_H
- #include <QString>
- class Stone
- {
- public:
- Stone();
- ~Stone();
- enum TYPE{JIANG, CHE, PAO, MA, BING, SHI, XIANG};
- int _row;
- int _col;
- TYPE _type;
- int _id;
- bool _dead;
- bool _red;
- // 棋子的初始化
- void init(int id);
- // 判断_type返回相应字符串
- QString name();
- void rotate(); // 翻转棋盘
- };
- #endif // STONE_H
- // Stone.cpp
- #include "Stone.h"
- #include <QDebug>
- Stone::Stone()
- {
- }
- Stone::~Stone()
- {
- }
- void Stone::init(int id)
- {
- struct {
- int row, col;
- Stone::TYPE type;
- } pos[16] = {
- {0, 0, Stone::CHE},
- {0, 1, Stone::MA},
- {0, 2, Stone::XIANG},
- {0, 3, Stone::SHI},
- {0, 4, Stone::JIANG},
- {0, 5, Stone::SHI},
- {0, 6, Stone::XIANG},
- {0, 7, Stone::MA},
- {0, 8, Stone::CHE},
- {2, 1, Stone::PAO},
- {2, 7, Stone::PAO},
- {3, 0, Stone::BING},
- {3, 2, Stone::BING},
- {3, 4, Stone::BING},
- {3, 6, Stone::BING},
- {3, 8, Stone::BING},
- };
- //_id = id;
- _dead = false;
- _red = id < 16;
- if (id < 16) { // 上方的棋子
- this->_row = pos[id].row;
- this->_col = pos[id].col;
- this->_type = pos[id].type;
- }
- else { // 下方的棋子
- this->_row = 9 - pos[id - 16].row;
- this->_col = 8 - pos[id - 16].col;
- this->_type = pos[id - 16].type;
- }
- }
- QString Stone::name()
- {
- switch (this->_type)
- {
- case CHE:
- return "车";
- case MA:
- return "马";
- case PAO:
- return "炮";
- case BING:
- return "兵";
- case JIANG:
- return "将";
- case SHI:
- return "士";
- case XIANG:
- return "相";
- }
- return "错误";
- }
- void Stone::rotate()
- {
- this->_col = 8 - this->_col;
- this->_row = 9 - this->_row;
- }
- // main.cpp
- // Chess游戏主程序
- //
- // Created by Lucifer Zhang on 2015-07-21.
- // Copyright (c) 2015 Lucifer Zhang. All rights reserved.
- #include <QApplication>
- #include "Board.h"
- int main(int argc, char* argv[])
- {
- QApplication app(argc, argv);
- Board board;
- board.show();
- return app.exec();
- }
工程代码详情:Github
中国象棋游戏Chess(3) - 实现走棋规则的更多相关文章
- 中国象棋游戏Chess(2) - 走棋
之前的文章请看:中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制 现在实现走棋的功能. 首先需要获取点击到的棋子,用QWidget中的函数 mouseReleaseEvent 实现函数: vo ...
- 中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制
本项目都使用QT来实现绘图,没有任何第三方的资源. 工程详情:Github 首先将棋盘设计为一个类Board // Board.h // Board类实现了棋盘的绘制以及显示 // #ifndef B ...
- C/C++编程笔记:C语言打造中国象棋游戏,项目源代码分享!
中国象棋是起源于中国的一种棋,属于二人对抗性游戏的一种,在中国有着悠久的历史.由于用具简单,趣味性强,成为流行极为广泛的棋艺活动. 它是中国棋文化,也是中华民族的文化瑰宝,它源远流长,趣味浓厚,基本规 ...
- 基于HTML5实现的中国象棋游戏
棋类游戏在桌面游戏中已经非常成熟,中国象棋的版本也非常多.今天这款基于HTML5技术的中国象棋游戏非常有特色,我们不仅可以选择中国象棋的游戏难度,而且可以切换棋盘的样式.程序写累了,喝上一杯咖啡,和电 ...
- C#中国象棋+游戏大厅 服务器 + 客户端源码
来源:www.ajerp.com/bbs C#中国象棋+游戏大厅 服务器 + 客户端源码 源码开源 C#版中国象棋(附游戏大厅) 基于前人大虾的修改版 主要用委托实现 服务器支持在线人数,大厅桌数的设 ...
- 【原创】使用HTML5+canvas+JavaScript开发的原生中国象棋游戏及源码分享
目前已经实现的功能: V1.0 : 实现棋子的布局,画布及游戏场景的初始化V2.0 : 实现棋子的颜色改变V3.0 :实现所有象棋的走棋规则V4.0 : 实现所有棋子的吃子功能 GItHub源码下载地 ...
- GMchess Linux下的中国象棋游戏
gmchess,一款Linux下的中国象棋程序
- cocos2dx 3.2 的中国象棋游戏
改编来源:http://cn.cocos2d-x.org/tutorial/lists?id=103 在cocos2dx官网看到了这么个教程,是cocos2dx 2.x版本的,于是用 cocos2dx ...
- 亲自动手实现Python+pygame中国象棋游戏
功能1:实现游戏整体界面显示 一.创建基本的结构 代码如下: import time import pygame def main(): # 初始化pygame pygame.init() # 创建用 ...
随机推荐
- ROS_Kinetic_29 kamtoa simulation学习与示例分析(一)
致谢源代码网址:https://github.com/Tutorgaming/kamtoa-simulation kamtoa simulation学习与示例分析(一) 源码学习与分析是学习ROS,包 ...
- 《Shazam It! Music Recognition Algorithms, Fingerprinting, and Processing》译文
最近看到一篇老外写的博客,简单介绍了shazam的工作原理.图非常好,所以就把它翻译成中文,希望对搞听歌识曲的人有帮助. 你可能遇到这样的场景:在酒吧或者餐厅听到你非常熟悉的歌,也许你曾经听过无数次, ...
- VMware 下的CentOS6.7 虚拟机与Windows7通信
在有网络的情况下,VMware 虚拟机使用桥接模式(Bridged) 和NAT方式,会自动通信,但是在没有网络的情况下怎么办呢?对,是的,使用host-only模式,如何设置呢? 注:将Windows ...
- SpriteKit:在场景过渡中暂停动画
Pausing Scenes During a Transition 你应该意识到两个重要的SKTrnsition属性在场景之间的过渡中. 它们是pausesIncomingScene和pausesO ...
- SSO 基于Cookie+fliter实现单点登录 实例解析(一)
接上文,SSO的理论讲解,接下来实践实践! 1.使用Cookie解决单点登录 技术点: 1.设置Cookie的路径为setPath("/").即Tomcat的目录下都有效 2.设置 ...
- 《java入门第一季》之对文件和字符串进行MD5加密工具类
上一篇介绍了MD5加密算法,之前写的代码有些冗余,而且可读性很差.今天把对文本数据的加密,以及获取文件的md5值做一个封装类.代码如下: package com.itydl.utils; import ...
- Java在Linux下 不能处理图形的解决办法 Can't connect to X11 window server
java在图形处理时调用了本地的图形处理库.在利用Java作图形处理(比如:图片缩放,图片签名,生成报表)时,如果运行在windows上不会出问题.如果将程序移植到Linux/Unix上的时候有可能出 ...
- java操作XML文件--读取内容
先把问题贴出来:编写一个可以解析xml及修改xml内容的工具类 由于我以前做过Android应用程序开发,之前也解析过xml文件,所以,这道题不是很难,这篇文章我先解决第一个问 ...
- Cocos2D v3.4.9粒子效果不能显示的原因分析及解决办法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在游戏App中为了衬托气氛我们往往使用一些特殊的图形效果,粒子 ...
- Struts2处理流程性需求的一种解决方案
在应用程序设计中,经常出现如下的需求. 查看用户填写的数据,而且数据是分页填写. 看下面这个情况 用户的信息有三页,分别是Form abc. 现在的问题是,后面的逻辑该如何设计. 如果把,FormAB ...