Qt版本中国象棋开发
Posted Weiyikang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt版本中国象棋开发相关的知识,希望对你有一定的参考价值。
实现功能:棋子初始化及走棋规则
棋子类:
1 #ifndef STONE_H 2 #define STONE_H 3 4 #include <QString> 5 6 class Stone 7 { 8 public: 9 Stone(); 10 ~Stone(); 11 12 enum TYPE{JIANG, CHE, PAO, MA, BING, SHI, XIANG}; 13 14 int _row; //棋子所在行 15 int _col; //棋子所在列 16 TYPE _type; //棋子类型(JIANG,CHE...) 17 18 19 int _id; //棋子id(0-31) 20 bool _dead; //棋子是否死亡 21 bool _red; //是否为红方 22 23 void init(int id) //初始化棋子信息 24 { 25 struct { 26 int row, col; 27 Stone::TYPE type; 28 } pos[16] = { 29 {0, 0, Stone::CHE}, 30 {0, 1, Stone::MA}, 31 {0, 2, Stone::XIANG}, 32 {0, 3, Stone::SHI}, 33 {0, 4, Stone::JIANG}, 34 {0, 5, Stone::SHI}, 35 {0, 6, Stone::XIANG}, 36 {0, 7, Stone::MA}, 37 {0, 8, Stone::CHE}, 38 39 {2, 1, Stone::PAO}, 40 {2, 7, Stone::PAO}, 41 {3, 0, Stone::BING}, 42 {3, 2, Stone::BING}, 43 {3, 4, Stone::BING}, 44 {3, 6, Stone::BING}, 45 {3, 8, Stone::BING}, 46 }; 47 48 _id = id; 49 _dead = false; 50 _red = id<16; 51 52 if(id < 16) 53 { 54 _row = pos[id].row; 55 _col = pos[id].col; 56 _type = pos[id].type; 57 } 58 else 59 { 60 _row = 9-pos[id-16].row; 61 _col = 8-pos[id-16].col; 62 _type = pos[id-16].type; 63 } 64 65 } 66 67 QString getText() //返回棋子类型对应的汉字,便于绘制棋面汉字 68 { 69 switch(this->_type) 70 { 71 case CHE: 72 return "车"; 73 case MA: 74 return "马"; 75 case PAO: 76 return "炮"; 77 case BING: 78 return "兵"; 79 case JIANG: 80 return "将"; 81 case SHI: 82 return "士"; 83 case XIANG: 84 return "相"; 85 } 86 return "错误"; 87 } 88 }; 89 90 #endif // STONE_H
棋盘类:
1 #ifndef BOARD_H 2 #define BOARD_H 3 4 #include <QWidget> 5 #include "Stone.h" 6 7 class Board : public QWidget 8 { 9 Q_OBJECT 10 public: 11 explicit Board(QWidget *parent = 0); 12 13 Stone _s[32]; //32枚棋子 14 int _r; //棋子的半径 15 int _selectid; //记录选中的棋子id 16 bool _bRedTurn; //记录是否轮到红方走棋 17 18 /* 返回象棋棋盘行列对应的像素坐标 */ 19 QPoint center(int row, int col); 20 QPoint center(int id); 21 22 /* 返回象棋棋盘上某个坐标对应的行,列 */ 23 bool getRowCol(QPoint pt, int& row, int& col); 24 25 /* 绘制棋子*/ 26 void drawStone(QPainter& painter, int id); 27 28 void paintEvent(QPaintEvent *); 29 30 /* 鼠标释放事件 */ 31 void mouseReleaseEvent(QMouseEvent *); 32 33 /* 根据要移动的棋子moveid,将要移动到的位置(row,col),将被吃掉的棋子killid判断能否走棋 */ 34 bool canMove(int moveid, int row, int col, int killid); 35 /* 将 */ 36 bool canMove1(int moveid, int row, int col, int killid); 37 /* 车 */ 38 bool canMove2(int moveid, int row, int col, int killid); 39 bool canMove3(int moveid, int row, int col, int killid); 40 bool canMove4(int moveid, int row, int col, int killid); 41 bool canMove5(int moveid, int row, int col, int killid); 42 bool canMove6(int moveid, int row, int col, int killid); 43 bool canMove7(int moveid, int row, int col, int killid); 44 45 signals: 46 47 public slots: 48 49 }; 50 51 #endif // BOARD_H
判断走棋函数:
1 bool Board::canMove(int moveid, int row, int col, int killid) 2 { 3 if(_s[moveid]._red == _s[killid]._red)//moveid和killid颜色相同) 4 { 5 //换选择 6 _selectid = killid; 7 update(); 8 9 return false; 10 } 11 12 switch(_s[moveid]._type) 13 { 14 case Stone::JIANG: 15 return canMove1(moveid, row, col, killid); 16 break; 17 case Stone::SHI: 18 return canMove2(moveid, row, col, killid); 19 break; 20 case Stone::XIANG: 21 return canMove3(moveid, row, col, killid); 22 break; 23 case Stone::CHE: 24 return canMove4(moveid, row, col, killid); 25 break; 26 case Stone::MA: 27 return canMove5(moveid, row, col, killid); 28 break; 29 case Stone::PAO: 30 return canMove6(moveid, row, col, killid); 31 break; 32 case Stone::BING: 33 return canMove7(moveid, row, col, killid); 34 break; 35 } 36 37 return true; 38 }
“将” 的走棋规则说明:
1 bool Board::canMove1(int moveid, int row, int col, int killid) 2 { 3 /* 4 1.首先目标位置在九宫内 5 2.移动的步长是一个格子 6 */ 7 if(_s[moveid]._red) 8 { 9 if(row > 2)return false; 10 } 11 else 12 { 13 if(row < 7)return false; 14 } 15 16 if(col < 3) return false; 17 if(col > 5) return false; 18 19 int dr = _s[moveid]._row - row; 20 int dc = _s[moveid]._col - col; 21 int d = abs(dr)*10 + abs(dc); // 12, 21 22 10, 1 22 if(d == 1 || d == 10) 23 return true; 24 25 return false; 26 }
判断 “将” 要移动的位置与原来位置相差一步的处理:
1 int dr = _s[moveid]._row - row; 2 int dc = _s[moveid]._col - col; 3 int d = abs(dr)*10 + abs(dc); // 12, 21 22 10, 1 4 if(d == 11) 5 return true;
鼠标点击释放事件:
1 void Board::mouseReleaseEvent(QMouseEvent *ev) 2 { 3 QPoint pt = ev->pos(); 4 // 将pt转化成象棋的行列值 5 // 判断这个行列值上面有没有棋子 6 int row, col; 7 bool bRet = getRowCol(pt, row, col); 8 if(bRet == false) // 点到棋盘外 9 return; 10 11 int i; 12 int clickid = -1; 13 for(i=0;i<32;++i) 14 { 15 if(_s[i]._row == row && _s[i]._col == col && _s[i]._dead== false) 16 { 17 break; 18 } 19 } 20 21 if(i<32) 22 { 23 clickid = i; 24 } 25 26 if(_selectid == -1) 27 { 28 if(clickid != -1) 29 { 30 if(_bRedTurn == _s[clickid]._red) 31 { 32 _selectid = clickid; 33 update(); 34 } 35 } 36 } 37 else 38 { 39 if(canMove(_selectid, row, col, clickid)) 40 { 41 /*走棋*/ 42 _s[_selectid]._row = row; 43 _s[_selectid]._col = col; 44 if(clickid != -1) 45 { 46 _s[clickid]._dead = true; 47 } 48 _selectid = -1; 49 _bRedTurn = !_bRedTurn; 50 update(); 51 } 52 } 53 }
效果图:
以上是关于Qt版本中国象棋开发的主要内容,如果未能解决你的问题,请参考以下文章
26.Qt Quick QML-RotationAnimationPathAnimationSmoothedAnimationBehaviorPauseAnimationSequential(代码片段