使用C++的QT框架实现五子棋

编程入门 行业动态 更新时间:2024-10-07 12:19:04

使用C++的QT<a href=https://www.elefans.com/category/jswz/34/1770644.html style=框架实现五子棋"/>

使用C++的QT框架实现五子棋

最近有点无聊正好想玩五子棋,那就实现一下这个游戏吧,网上的五子棋逻辑又长又复杂,我这个逻辑还是蛮简单的,展示如下

这是一个简单的五子棋,今天就了解一下这个游戏的思路,使用的是QT框架,只要思路了解什么框架都能实现

1.首先画棋盘,主要是分横和竖两个方向,代码如下

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

加上窗口的大小标题设置

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();
}

使用循环进行画线,如下

2.创建棋子类,头文件为

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

cpp为

#include "qizizhuangtai.h"  // 包含自定义头文件 "qizizhuangtai.h"
#include <QBrush>  // 包含 QBrush 类的头文件qizizhuangtai::qizizhuangtai(QPoint dian)
{this->x = dian.x();  // 构造函数,设置类的 x 成员变量为传入 QPoint 对象的 x 坐标this->y = dian.y();  // 构造函数,设置类的 y 成员变量为传入 QPoint 对象的 y 坐标
}void qizizhuangtai::shua(int a)
{this->yanse = a;  // 成员函数,设置类的 yanse 成员变量为传入的整数参数 a
}void qizizhuangtai::fangkai()
{this->zhuangtai = true;  // 成员函数,将类的 zhuangtai 成员变量设置为 true
}

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

3.将棋盘上所有的点都装进一个数组,就是chushihua()这个方法,具体实现如下

void Widget::chushihua()
{for (int a = 1; a < 20; a++) {for (int b = 1; b < 20; b++) {QPoint dian = QPoint(a * 40, b * 40);  // 创建一个 QPoint 对象,坐标为 (a*40, b*40)qizizhuangtai qi(dian);  // 创建一个 qizizhuangtai 对象 qi,传入 QPoint 对象 dianquan.append(qi);  // 将 qizizhuangtai 对象 qi 添加到容器 quan 中}}
}

可能会有人问为什么要这样做,其实很简单,应为我们画棋子本事就是根据一个点,加上半径即可,半径已经选好了,那么主要是这个棋子圆形状的坐标,而鼠标事件正好可以捕获坐标,点到哪会将这个位置的棋子状态改变

4.根据鼠标选择要画哪里,如下

或者这种 

这个是怎么实现的呢,其实本质是使用加减算出上下左右坐标的点,之后求出鼠标离这四个点的聚类最后求出最近的点画棋子,代码如下

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#define QIZIBANJING 15
#define LUOZIBIAOJI 6
#define GEZIDAXIAO 40
#include <QMouseEvent>
#include <QDebug>
#include "qizizhuangtai.h"
#include <QMessageBox>void Widget::mouseMoveEvent(QMouseEvent *event)
{int x = event->x() / 40;  // 将鼠标事件的x坐标除以40,用于确定鼠标所在的列int y = event->y() / 40;  // 将鼠标事件的y坐标除以40,用于确定鼠标所在的行int shubiaox = event->x();  // 获取鼠标事件的x坐标int shubiaoy = event->y();  // 获取鼠标事件的y坐标qDebug() << "x为:" << x << "  " << "y为:" << y;QPoint zuoshang = QPoint(x * 40, y * 40);  // 左上角的点坐标QPoint youshang = zuoshang + QPoint(40, 0);  // 右上角的点坐标QPoint zuoxia = zuoshang + QPoint(0, 40);   // 左下角的点坐标QPoint youxia = zuoshang + QPoint(40, 40);   // 右下角的点坐标// 比较鼠标事件点与四个角的距离的平方int zs = (shubiaox - zuoshang.x()) * (shubiaox - zuoshang.x()) + (shubiaoy - zuoshang.y()) * (shubiaoy - zuoshang.y());int ys = (shubiaox - youshang.x()) * (shubiaox - youshang.x()) + (shubiaoy - youshang.y()) * (shubiaoy - youshang.y());int zx = (shubiaox - zuoxia.x()) * (shubiaox - zuoxia.x()) + (shubiaoy - zuoxia.y()) * (shubiaoy - zuoxia.y());int yx = (shubiaox - youxia.x()) * (shubiaox - youxia.x()) + (shubiaoy - youxia.y()) * (shubiaoy - youxia.y());qDebug() << "左上距离" << zs << " 右上距离" << ys << " 左下距离" << zx << " 右下距离" << yx;// 根据距离的平方选择一个标记点if (zs < 800) {this->biaojidianx = zuoshang.x();this->biaojidiany = zuoshang.y();}if (ys < 800) {this->biaojidianx = youshang.x();this->biaojidiany = youshang.y();}if (zx < 800) {this->biaojidianx = zuoxia.x();this->biaojidiany = zuoxia.y();}if (yx < 800) {this->biaojidianx = youxia.x();this->biaojidiany = youxia.y();}qDebug() << "标记点x:" << this->biaojidianx << "标记点y:" << this->biaojidiany;
}

这样大致就求出要画棋子的点了

5.落子,主要还是使用鼠标的松开事件,进行对状态的修改

void Widget::mouseReleaseEvent(QMouseEvent *event)
{// 遍历存储在 'quan' 向量中的棋子对象for (int a = 0; a < quan.size(); a++) {// 检查当前棋子的坐标是否与 'biaojidianx' 和 'biaojidiany' 匹配if (quan[a].x == biaojidianx && quan[a].y == biaojidiany) {// 对匹配的棋子执行 'shua' 操作,传入当前玩家的信息 'qishou'quan[a].shua(this->qishou);// 对匹配的棋子执行 'fangkai' 操作,可能是该操作的状态变化quan[a].fangkai();// 切换当前玩家。如果当前玩家是 '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){// 创建一个画刷 'huashua',设置颜色为黑色QBrush huashua;huashua.setColor(Qt::black);huashua.setStyle(Qt::SolidPattern);// 设置绘图对象 'huajia' 的画刷为 'huashua'huajia.setBrush(huashua);// 绘制一个小矩形,可能用于标记某个点的位置huajia.drawRect(biaojidianx-6, biaojidiany-6, 12, 12);// 创建另一个画刷 'huashua2',设置颜色为红色QBrush huashua2;huashua2.setColor(Qt::red);huashua2.setStyle(Qt::SolidPattern);// 此处似乎有错误,应该设置 'huajia' 的画刷为 'huashua2' 而不是 'huashua'huajia.setBrush(huashua);// 绘制圆形for (int a = 0; a < quan.size(); a++) {if (quan[a].zhuangtai == true) {if (quan[a].yanse == 0) {// 设置画刷颜色为蓝色huashua.setColor(Qt::blue);huajia.setBrush(huashua);// 绘制蓝色圆形huajia.drawEllipse(quan[a].x-15, quan[a].y-15, 30, 30);// 调用 'jiance' 函数,可能用于检查圆形的位置jiance(quan[a].x, quan[a].y);}else {// 设置画刷颜色为红色huashua2.setColor(Qt::red);huajia.setBrush(huashua2);// 绘制红色圆形huajia.drawEllipse(quan[a].x-15, quan[a].y-15, 30, 30);// 调用 'jiance' 函数,可能用于检查圆形的位置jiance(quan[a].x, quan[a].y);}}}// 更新绘图,可能会触发重新绘制操作this->update();// 调用基类的绘图事件处理函数,以确保正常的事件处理流程return QWidget::paintEvent(event);
}

如下所示 

这样就大致实现了五子棋的功能,当然忘记写检测了,其实也蛮容易的,只需要双层for遍历所有的点和这个点的左右上下连续四个是否的yanse属性一样就可以了,大家可以自己试一下,那五子棋到这里就写完了

更多推荐

使用C++的QT框架实现五子棋

本文发布于:2023-11-17 07:49:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1641621.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:框架   五子   QT

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!