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

    效果图:

         

  • 相关阅读:
    CodeForces Round #288 Div.2
    POJ 3660 Cow Contest【传递闭包】
    ZOJ 3321 Circle【并查集】
    CF 286(div 2) B Mr. Kitayuta's Colorful Graph【传递闭包】
    CF 287(div 2) B Amr and Pins
    HDU 2122 Ice_cream’s world III【最小生成树】
    HDU 1233 还是畅通工程【最小生成树】
    奶牛接力 矩阵乘法
    家谱 并差集
    昂贵的聘礼 最短路 dijkstra
  • 原文地址:https://www.cnblogs.com/weiyikang/p/6361648.html
Copyright © 2011-2022 走看看