zoukankan      html  css  js  c++  java
  • 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

    效果图:

         

  • 相关阅读:
    golang删除数组某个元素
    golang用通道实现信号量,控制并发个数
    什么是ScaleIO中的forwards rebuild和backwards rebuild?
    SQL Server中的database checkpoint
    如何将thick provision lazy zeroed的VMDK文件转换为thick provision eager zeroed?
    LoadTestAgentResultsLateException in VS2010
    SQL Server Instance无法启动了, 因为TempDB所在的分区没有了, 怎么办?
    VMware vCenter中, 如何辩认虚机上Raw Device Mapping过了的一块物理磁盘?
    SQL Server AlwaysOn Setup Step-By-Step Guide
    TPC-E在populate测试Database时需要注意的一些事项
  • 原文地址:https://www.cnblogs.com/weiyikang/p/6361648.html
Copyright © 2011-2022 走看看