700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C++ QT中国象棋双人单机对战代码总结

C++ QT中国象棋双人单机对战代码总结

时间:2020-02-12 19:53:16

相关推荐

C++ QT中国象棋双人单机对战代码总结

Stone.h

#ifndef STONE_H#define STONE_H#include <QString>class Stone{public:Stone();//定义棋子的所有类型enum TYPE{JIANG,CHE,PAO,MA,BING,SHI,XIANG};//棋子所处的行int _row;//棋子所处的列int _col;//棋子的idint _id;//棋子是否已死bool _dead;//棋子是否为红子bool _red;//棋子类型TYPE _type;//初始化棋子void init(int id);//获取棋子的类型名QString getText();};#endif // STONE_H

Stone.cpp

#include "Stone.h"Stone::Stone(){}void Stone::init(int id){// 总共有16种棋子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){_row = pos[id].row;_col = pos[id].col;_type = pos[id].type;}else{_row = 9 - pos[id-16].row;_col = 8 - pos[id-16].col;_type = pos[id-16].type;}}QString Stone::getText(){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 "Wrong";}

Board.h

#ifndef BOARD_H#define BOARD_H#include <QWidget>#include "Stone.h"class Board : public QWidget{Q_OBJECTpublic:explicit Board(QWidget *parent = 0);Stone _s[32];// 32个棋子int _r; // r棋子的半径,格子一半的宽度int _selectid; // 被选中的棋子bool _bRedTurn; // 是否轮到红方走// 根据行和列获取棋子的idint getStoneId(int row, int col);//计算即将行走的棋子与某一坐标之间有几颗棋子int num_of_Stone(int moveid,int row,int col);//输入行列坐标判断该坐标上有没有棋子bool beStone(int row,int col);// 判断棋子的颜色是否相同bool sameColor(int moveid,int killid);// 由点击坐标转化为棋子的行列编号bool getRowCol(QPoint pt, int &row, int &col);bool canSelect(int id);//最基本的能不能走的判断判断bool canMove(int moveid,int row,int col,int killid);//判断将能不能走bool canMoveJIANG(int moveid,int row,int col,int killid);//判断士能不能走bool canMoveSHI(int moveid,int row,int col,int killid);//判断象能不能走bool canMoveXIANG(int moveid,int row,int col,int killid);//判断车能不能走bool canMoveCHE(int moveid,int row,int col,int killid);//判断马能不能走bool canMoveMA(int moveid,int row,int col,int killid);//判断炮能不能走bool canMovePAO(int moveid,int row,int col,int killid);//判断兵能不能走bool canMoveBING(int moveid,int row,int col,int killid);virtual void paintEvent(QPaintEvent *);//与显示到窗口中有关的函数void drawStone(QPainter& painter,int id);//输入行列坐标 返回像素坐标QPoint center(int row,int col);//输入棋子的id 返回像素坐标QPoint center(int id);void trySelectStone(int id);void tryMoveStone(int id,int row,int col);void click(QPoint pt);void click(int id, int row, int col);void moveStone(int _selectid, int killid, int row, int col);void mouseReleaseEvent(QMouseEvent *);//void click(QPoint pt);~Board();};#endif // BOARD_H

Board.cpp

#include "Board.h"#include <QPainter>#include <QMouseEvent>Board::Board(QWidget *parent): QWidget(parent){for(int i=0;i<32;i++){_s[i].init(i);}_selectid = -1;_bRedTurn = true;}Board::~Board(){}void Board::paintEvent(QPaintEvent *){QPainter painter(this);int d=40;// 画10条横线_r = d/2;for(int i=1;i<=10;i++){painter.drawLine(QPoint(d, i*d),QPoint(9*d,i*d));}for(int i=1;i<=9;i++){if(i==1 || i==9)painter.drawLine(QPoint(i*d,d),QPoint(i*d,10*d));else{painter.drawLine(QPoint(i*d,d),QPoint(i*d,5*d));painter.drawLine(QPoint(i*d,6*d),QPoint(i*d,10*d));}}// 九宫格painter.drawLine(QPoint(4*d,1*d),QPoint(6*d,3*d));painter.drawLine(QPoint(6*d,1*d),QPoint(4*d,3*d));painter.drawLine(QPoint(4*d,8*d),QPoint(6*d,10*d));painter.drawLine(QPoint(6*d,8*d),QPoint(4*d,10*d));// 绘制32个棋子for(int i=0;i<32;i++){drawStone(painter,i);}}QPoint Board::center(int row, int col){return QPoint((col+1)*_r*2,(row+1)*_r*2);}QPoint Board::center(int id){return center(_s[id]._row, _s[id]._col);}void Board::drawStone(QPainter & painter, int id){if(_s[id]._dead)return;QPoint c=center(id);QRect rect = QRect(c.x()-_r,c.y()-_r,_r*2,_r*2);if(id == _selectid)painter.setBrush(QBrush(Qt::gray));elsepainter.setBrush(QBrush(Qt::yellow));painter.setPen(Qt::black);painter.drawEllipse(c,_r,_r);if(_s[id]._red)painter.setPen(Qt::red);painter.setFont(QFont("system",_r,700));painter.drawText(rect,_s[id].getText(),QTextOption(Qt::AlignCenter));}/*确定某个行列位置上是否有棋子*/bool Board::beStone(int row,int col){for(int i=0;i<32;i++)if(_s[i]._row==row&&_s[i]._col==col&&!_s[i]._dead)return true;return false;}//计算即将行走的棋子与某一坐标之间有几颗棋子 默认返回值为-1int Board::num_of_Stone(int moveid,int row,int col){int i;int sum=0;if(_s[moveid]._row==row){if(col-_s[moveid]._col>0)for(i=_s[moveid]._col+1;i<col;i++){if(beStone(_s[moveid]._row,i)==true)sum++;}elsefor(i=_s[moveid]._col-1;i>col;i--){if(beStone(_s[moveid]._row,i)==true)sum++;}return sum;}else if(_s[moveid]._col==col){if(row-_s[moveid]._row>0)for(i=_s[moveid]._row+1;i<row;i++){if(beStone(i,_s[moveid]._col)==true)sum++;}elsefor(i=_s[moveid]._row-1;i>row;i--){if(beStone(i,_s[moveid]._col)==true)sum++;}return sum;}//两个棋子不在一条直线上return -1;}bool Board::sameColor(int moveid, int killid){return _s[moveid]._red == _s[killid]._red;}// 总的逻辑判断函数// 总的逻辑判断函数bool Board::canMove(int moveid, int killid, int row, int col){if(killid==-1||!sameColor(moveid,killid)){switch(_s[moveid]._type){case Stone::JIANG:return canMoveJIANG(moveid,row,col,killid);break;case Stone::SHI:return canMoveSHI(moveid,row,col,killid);break;case Stone::XIANG:return canMoveXIANG(moveid,row,col,killid);break;case Stone::CHE:return canMoveCHE(moveid,row,col,killid);break;case Stone::MA:return canMoveMA(moveid,row,col,killid);break;case Stone::PAO:return canMovePAO(moveid,row,col,killid);break;case Stone::BING:return canMoveBING(moveid,row,col,killid);break;default: break;}}//move的棋子和kill的棋子是相同颜色的if(sameColor(moveid,killid)){/*换选择*/_selectid=killid;update();return false;}return true;}bool Board::canMoveSHI(int moveid,int row,int col,int killid){if(_s[moveid]._red){//判断红方士的纵向行走是否超出米字格范围if(row>2) return false;}else{//判断黑方士的纵向行走是否超出米字格范围if(row<7) return false;}//判断红黑双方方士的横向行走是否超出米字格范围if(col<3) return false;if(col>5) return false;//判断是否为沿着对角线斜着行走int dr=_s[moveid]._row-row;int dc=_s[moveid]._col-col;if(abs(dr)==1&&abs(dc)==1)return true;return false;}bool Board::canMoveBING(int moveid,int row,int col,int killid){/*兵的走棋规则*/int dr=_s[moveid]._row-row;int dc=_s[moveid]._col-col;//红棋if(_s[moveid]._red){//过河前if(_s[moveid]._row>=3&&_s[moveid]._row<=4){//竖着走if(dr==-1&&dc==0)return true;//横着走elsereturn false;}//过河后else{if(abs(dr)==1&&abs(dc)==0||(abs(dc)==1&&abs(dr)==0)){//竖着走if(dr==1)//竖着走走了回头路就要返回错误return false;//横着走elsereturn true;}elsereturn false;}}//黑棋else{//过河前if(_s[moveid]._row>=5&&_s[moveid]._row<=6){//竖着走if(dr==1&&dc==0)return true;//横着走elsereturn false;}//过河后else{//竖着走if(abs(dr)==1&&abs(dc)==0||(abs(dc)==1&&abs(dr)==0)){//竖着走走了回头路就要返回错误if(dr==-1)return false;//横着走elsereturn true;}elsereturn false;}}return true;}bool Board::canMoveXIANG(int moveid,int row,int col,int killid){//不能过河if(_s[moveid]._red){if(row>4) return false;}else{if(row<5) return false;}//走田字格int dr=_s[moveid]._row-row;int dc=_s[moveid]._col-col;int medium_r=(_s[moveid]._row+row)/2;int medium_c=(_s[moveid]._col+col)/2;if(abs(dr)==2&&abs(dc)==2)//别象眼检验if(!beStone(medium_r,medium_c))return true;return false;}bool Board::canMoveMA(int moveid,int row,int col,int killid){int dr=_s[moveid]._row-row;int dc=_s[moveid]._col-col;int medium_r=(_s[moveid]._row+row)/2;int medium_c=(_s[moveid]._col+col)/2;if(abs(dr)==1&&abs(dc)==2||(abs(dr)==2&&abs(dc)==1)){if(abs(dr)==2){//别马腿检验if(beStone(medium_r,_s[moveid]._col)==false)return true;}else{//别马腿检验if(beStone(_s[moveid]._row,medium_c)==false)return true;}}return false;}bool Board::canMoveJIANG(int moveid, int row, int col, int killid){if(_s[moveid]._red){if(row > 2)return false;}else{if(row < 7)return false;}if(col < 3)return false;if(col > 5)return false;int dr = _s[moveid]._row - row;int dc = _s[moveid]._col - col;int d = abs(dr)*10 + abs(dc);if(d==1||d==10)return true;return false;}bool Board::canMovePAO(int moveid,int row,int col,int killid){int ret = num_of_Stone(moveid,row,col);if(killid!=-1 && ret == 1)return true;else if(killid==-1 && ret ==0)return true;elsereturn false;}bool Board::canMoveCHE(int moveid,int row,int col,int killid){int ret = num_of_Stone(moveid,row,col);return !ret;}bool Board::getRowCol(QPoint pt, int &row, int &col){for(row=0;row<=9;row++){for(col=0;col<=8;col++){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;}}return false;}int Board::getStoneId(int row, int col){for(int i=0;i<32;i++){if(_s[i]._row == row && _s[i]._col == col)return i;}return -1;}void Board::click(int id, int row, int col){if(this->_selectid == -1) // 如果没有选择到棋子,选择棋子trySelectStone(id);else // 选择到棋子,移动棋子tryMoveStone(id,row,col);}void Board::click(QPoint pt){int row, col;bool bClicked = getRowCol(pt, row, col);if(!bClicked) // 点击地方不合理return;int id = getStoneId(row,col);click(id,row,col);}void Board::trySelectStone(int id){if(_bRedTurn == _s[id]._red){_selectid = id;update();}}// 尝试走棋void Board::tryMoveStone(int killid, int row, int col){// 如果尝试吃颜色相同的棋子,那么重新选择棋子if(killid!=-1 && sameColor(killid, _selectid)){trySelectStone(killid);return;}// 如果可以移动棋子,那么移动棋子if(canMove(_selectid, killid, row, col)){moveStone(_selectid, killid, row, col);_selectid = -1;update();}}void Board::moveStone(int _selectid, int killid, int row, int col){_s[_selectid]._row = row;_s[_selectid]._col = col;if(killid!=-1){_s[killid]._dead = true;}_selectid = -1;_bRedTurn = !_bRedTurn;// 对方回合}void Board::mouseReleaseEvent(QMouseEvent *ev){QPoint pt = ev->pos();click(pt);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。