Qt中国象棋之棋盘的绘制
中国象棋简介
中国象棋是起源于中国的一种棋戏,属于二人对抗性游戏的一种,在中国有着悠久的历史。由于用具简单,趣味性强,成为流行极为广泛的棋艺活动。
棋盘简介
- 直线
棋盘上较长的平行排列的边称为直线,共有9条,其中7条被河界隔断。用红色棋子一方的直线从右往左依次用中文数字一、二、三、四、五、六、七、八、九表示;用黑色棋于一方的直线在红方对面也从右往左依次用阿拉伯数字1、2、3、4、5、6、7、8、9表示。
- 横线
棋盘上较短的平行排列的边称为横线。横线共有10条,用红色棋子一方的横线从红方底线算起,从下往上依次用中文数字一至十表示;用黑色棋子一方的横线则从黑方底线开始,依次用阿拉伯数字1-10表示。
- 交叉点
直线与横线相交的地方称为“交叉点”。整个棋盘共有90个交叉点,棋子就摆放和活动在这些交叉点上。
- 河界
棋盘中央没有画直线的地方称为“河界”。它代表弃战双方的分界线,确定了各自的地域。
- 九宫
棋盘两端各画有斜交叉线的地方称为“九宫”。将则只能在各自“九宫”的9个交叉点上活动。
棋子
所有的棋子共有三十二个,其中又分为红、黑两组(分别代表对垒的一方),每组共有十六个棋子(为了区别双方的棋子,不仅在颜色中有所区别,而且还会使用同音不同字的棋子),其中又各分为七种棋子,其名称和数目如下:
红棋子:帅一个,车、马、炮、相、士各两个,兵五个。
黑棋子:将一个,车、马、炮、象、士各两个,卒五个。
通过Qt5实现中国象棋
Qt5纯代码实现中国象棋,通过paintEvent绘制事件绘制棋盘和棋子
通过重绘事件绘制棋盘和棋子,通过鼠标事件实现棋子移动等
设计思路
- 绘制棋盘
- 绘制棋子
- 走棋
- 走棋规则
一、新建项目
新建项目 -> 其他项目 -> Empty qmake Project,项目名填myChinessChess
添加新文件 -> C++ -> C++ Source File,文件名main.cpp
工程文件myChinessChess.pro添加一行
#include #include "chessboard.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);ChessBoard board;board.show();return app.exec();
}
棋盘头文件chessboard.h头文件中
#ifndef CHESSBOARD_H
#define CHESSBOARD_H#include
#include
#include
#include
#include
#include class ChessBoard : public QWidget
{Q_OBJECT
public:QPoint origin; /*棋盘原点坐标*/int sideLen; /*棋盘格子边长*/explicit ChessBoard(QWidget *parent = nullptr); /*构造函数*/void paintEvent(QPaintEvent *); /*重绘事件*/void drawRightAngle(QPainter &pt, QPoint c); /*绘制棋子炮的停靠点(绘制几个直角)*/QPoint center(int row, int col); /*将棋盘行、列坐标转换成像素坐标*/signals:public slots:
};#endif // CHESSBOARD_H
棋盘实现文件chessboard.cpp
#include "chessboard.h"ChessBoard::ChessBoard(QWidget *parent) : QWidget(parent)
{setWindowTitle(tr("中国象棋"));origin = QPoint(60,60); /*棋盘原点坐标*/sideLen = 60; /*棋盘格子边长*/resize(origin.x()*3+sideLen*8, origin.y()*2+sideLen*9);
}/*重绘事件*/
void ChessBoard::paintEvent(QPaintEvent *)
{QPainter painter(this);QPen pen;pen.setWidth(3);painter.setPen(pen);/*绘制棋盘外廊框*/painter.drawRect(QRect(origin.x()-5,origin.y()-5, sideLen*8+10, sideLen*9+10));/*绘制棋盘外围*/pen.setWidth(1);painter.setPen(pen);painter.drawRect(QRect(origin, center(9,8)));/*绘制剩下的8横7竖*/for(int i=1; i<=8; i++) {painter.drawLine(center(i,0), center(i,8));if(i<8) {painter.drawLine(center(0,i), center(4,i));painter.drawLine(center(5,i), center(9,i));}}/*绘制九宫斜线*/painter.drawLine(center(0,3), center(2,5));painter.drawLine(center(2,3), center(0,5));painter.drawLine(center(7,3), center(9, 5));painter.drawLine(center(9,3), center(7,5));/*绘制楚河、汉界*/painter.setPen(Qt::gray);painter.setFont(QFont("system", 24, sideLen/2));painter.drawText(QRect(center(4,1), center(5,3)), "楚河", QTextOption(Qt::AlignCenter));painter.drawText(QRect(center(4,5), center(5,7)), "汉界", QTextOption(Qt::AlignCenter));/*绘制直角(棋子炮的停靠点)*/drawRightAngle(painter, center(2,1));drawRightAngle(painter, center(2,7));drawRightAngle(painter, center(7,1));drawRightAngle(painter, center(7,7));
}/*绘制棋子炮的停靠点(绘制几个直角)*/
void ChessBoard::drawRightAngle(QPainter &pt, QPoint c)
{int x = c.x();int y = c.y();int r = sideLen/10;pt.drawLine(x-2*r, y-r, x-r, y-r);pt.drawLine(x-2*r, y+r, x-r, y+r);pt.drawLine(x+r, y-r, x+2*r, y-r);pt.drawLine(x+r, y+r, x+2*r, y+r);pt.drawLine(x-r, y-2*r, x-r, y-r);pt.drawLine(x-r, y+r, x-r, y+2*r);pt.drawLine(x+r, y-2*r, x+r, y-r);pt.drawLine(x+r, y+r, x+r, y+2*r);
}/*将棋盘行、列坐标转换成像素坐标*/
QPoint ChessBoard::center(int row, int col)
{return QPoint(origin.x()+sideLen*col, origin.y()+sideLen*row);
}
效果图

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
