QT实现五子棋对局

2024-06-07 17:57 李志远 394

一、UI

二、画棋盘

1、棋盘上横竖的线

void Widget::paintEvent(QPaintEvent *event) {
    // 创建一个 QPainter 对象,用于绘制图形,以当前的 Widget 为绘图设备
    QPainter painter(this);
 
    // 使用循环绘制水平和垂直的线条,创建一个网格效果
    for (int a = 0; a < 21; a++) {
        // 绘制垂直线条,起点为 (a*40, 0),终点为 (a*40, 800)
        painter.drawLine(QPoint(a * 40, 0), QPoint(a * 40, 800));
 
        // 绘制水平线条,起点为 (0, a*40),终点为 (800, a*40)
        painter.drawLine(QPoint(0, a * 40), QPoint(800, a * 40));
    }
 
    // 调用基类的 paintEvent 函数来完成绘制操作
    return QWidget::paintEvent(event);
}

2、窗口的大小标题设置

Widget::Widget(QWidget *parent)
    : QWidget(parent) // 构造函数初始化列表,传递父窗口指针
    , ui(new Ui::Widget) // 创建一个 Ui::Widget 对象,通常用于用户界面设计
{
    ui->setupUi(this); // 调用 Ui::Widget 对象的 setupUi 函数来设置用户界面
 
    // 启用鼠标跟踪,以便能够捕获鼠标移动事件
    this->setMouseTracking(true);
 
    // 设置窗口的固定大小为 800x800 像素
    this->setFixedSize(QSize(800, 800));
 
    // 设置窗口的标题为 "五子棋"
    this->setWindowTitle("五子棋");
 
    // 调用 chushihua() 函数来执行初始化操作
    chushihua();
}

效果如下

三、棋子类

棋子类的属性为:棋子的x,y坐标,状态(比如一开始都为false,而绘画只绘画出为true的棋子),颜色

#ifndef chessmanStatus_H  // 条件编译指令,防止头文件被重复包含
#define chessmanStatus_H
 
#include <QPoint>  // 包含 QPoint 类的头文件
#include <QBrush>  // 包含 QBrush 类的头文件
 
class chessmanStatus : public QPoint  // 定义一个 chessmanStatus 类,继承自 QPoint 类
{
 
public:
    explicit chessmanStatus(QPoint dian);  // 构造函数声明
 
    int x;  // 整型变量 x
    int y;  // 整型变量 y
    int yanse = 0;  // 整型变量 yanse,初始化为 0
    bool status = false;  // 布尔变量 status,初始化为 false
    QBrush paint;  // QBrush 对象 paint
    void shua(int a);  // 成员函数声明 shua
    void luozi();  // 成员函数声明 luozi
};
 
#endif // chessmanStatus_H  // 结束条件编译指令,确保头文件完整性

四、落子

使用鼠标的松开事件,进行对状态的修改

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    // 遍历存储在 'lzy' 向量中的棋子对象
    for (int a = 0; a < lzy.size(); a++) {
        // 检查当前棋子的坐标是否与 'luodianx' 和 'luodiany' 匹配
        if (lzy[a].x == luodianx && lzy[a].y == luodiany) {
            // 对匹配的棋子执行 'shua' 操作,传入当前玩家的信息 'qishou'
            lzy[a].shua(this->qishou);
 
            // 对匹配的棋子执行 'luozi' 操作,可能是该操作的状态变化
            lzy[a].luozi();
 
            // 切换当前玩家。如果当前玩家是 'hei',则切换为 'bai',反之亦然
            if (this->qishou == hei) {
                this->qishou = bai;
            } else if (this->qishou == bai) {
                this->qishou = hei;
            }
        }
    }
 
    // 调用基类的鼠标释放事件处理函数,以确保正常的事件处理流程
    return QWidget::mouseReleaseEvent(event);
}

五、绘画

落子进行绘画,代码如下

void Widget::paintEvent(QPaintEvent *event){
    // 创建一个画刷 'paint',设置颜色为黑色
    QBrush paint;
    paint.setColor(Qt::black);
    paint.setStyle(Qt::SolidPattern);
    // 设置绘图对象 'painter' 的画刷为 'paint'
    painter.setBrush(paint);
    // 绘制一个小矩形,可能用于标记某个点的位置
    painter.drawRect(luodianx-6, luodiany-6, 12, 12);
 
    // 创建另一个画刷 'paint2',设置颜色为红色
    QBrush paint2;
    paint2.setColor(Qt::red);
    paint2.setStyle(Qt::SolidPattern);
    // 此处似乎有错误,应该设置 'painter' 的画刷为 'paint2' 而不是 'paint'
    painter.setBrush(paint);
 
    // 绘制圆形
    for (int a = 0; a < lzy.size(); a++) {
        if (lzy[a].status == true) {
            if (lzy[a].yanse == 0) {
                // 设置画刷颜色为蓝色
                paint.setColor(Qt::blue);
                painter.setBrush(paint);
                // 绘制蓝色圆形
                painter.drawEllipse(lzy[a].x-15, lzy[a].y-15, 30, 30);
                // 调用 'jiance' 函数,可能用于检查圆形的位置
                jiance(lzy[a].x, lzy[a].y);
            }
            else {
                // 设置画刷颜色为红色
                paint2.setColor(Qt::red);
                painter.setBrush(paint2);
                // 绘制红色圆形
                painter.drawEllipse(lzy[a].x-15, lzy[a].y-15, 30, 30);
                // 调用 'jiance' 函数,可能用于检查圆形的位置
                jiance(lzy[a].x, lzy[a].y);
            }
        }
    }
 
    // 更新绘图,可能会触发重新绘制操作
    this->update();
 
    // 调用基类的绘图事件处理函数,以确保正常的事件处理流程
    return QWidget::paintEvent(event);
}

六、效果呈现