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
View Code

棋盘类:

 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
View Code

判断走棋函数:

 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 }
View Code

“将” 的走棋规则说明:

 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 }
View Code

判断 “将” 要移动的位置与原来位置相差一步的处理:

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 }
View Code

效果图:

     

原文地址:https://www.cnblogs.com/weiyikang/p/6361648.html