VS+QT五子棋游戏开发

1、首先安装好VS软件和QT库,将其配置好,具体不在此展开说明。

2、文件结构如下图:

3、绘制棋盘代码,如下:

void Qwzq::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);//防锯齿
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    for (int i = 0; i < kGridCount+1; i++)
    {
        painter.drawLine(kBoardMargin,kBoardMargin+i*kBlockSize,size().width()-kBoardMargin,kBoardMargin+i*kBlockSize);
        painter.drawLine(kBoardMargin+i*kBlockSize, kBoardMargin,kBoardMargin+i*kBlockSize,size().height()-kBoardMargin);
    }

    for (int i = 0; i < kGridCount; i++)
    {
        for (int j = 0; j < kGridCount; j++)
        {
            if (game->gameMap[i][j] == 1)
            {
                brush.setColor(Qt::white);
                painter.setBrush(brush);
                painter.drawEllipse(kBoardMargin+kBlockSize*j-kRadius,kBoardMargin+kBlockSize*i-kRadius,kRadius*2,kRadius*2);
            }
            else if (game->gameMap[i][j]==-1)
            {
                brush.setColor(Qt::black);
                painter.setBrush(brush);
                painter.drawEllipse(kBoardMargin + kBlockSize * j - kRadius, kBoardMargin + kBlockSize * i - kRadius, kRadius * 2, kRadius * 2);
            }
        }
    }
    QString str;
    if (game->isWin(clickPosRow, clickPosCol))
    {
        str = "Win!";
        QMessageBox::StandardButton btnValue = QMessageBox::information(this, tr("result"), str);
        close();
    }
    if (game->isDead())
    {
        str = "Over!";
        QMessageBox::StandardButton btnValue = QMessageBox::information(this, tr("result"), str);
        close();
    }
}

 4、绘制旗子代码,如下:

void Qwzq::mousePressEvent(QMouseEvent* event)
{
    int x = event->x();
    int y = event->y();

    int kr = kBoardMargin + kBlockSize * kGridCount;
    int kd = kBoardMargin + kBlockSize*kGridCount;
    if (x>=kBoardMargin&&x<=kr&&y>=kBoardMargin&&y<=kd)
    {
        int x1 = (x - kBoardMargin) / kBlockSize;
        int y1 = (y - kBoardMargin) / kBlockSize;

        x1 = x - (kBoardMargin + kBlockSize * x1);
        y1 = y - (kBoardMargin + kBlockSize * y1);

        if (x1 > kBlockSize / 2)
            x = (x-kBoardMargin) / kBlockSize + 1;
        else
            x = (x - kBoardMargin) / kBlockSize;

        if (y1 > kBlockSize / 2)
            y = (y-kBoardMargin) / kBlockSize + 1;
        else
            y = (y - kBoardMargin) / kBlockSize;
        
        game->updateMap(y, x);
        clickPosRow = y;
        clickPosCol = x;
    }
    update();
}

5、gameModel.cpp代码如下:

#include"GameModel.h"
#include<utility>
#include<qDebug>

void GameModel::startGame()
{
	gameMap.clear();
	for (int i = 0; i < kBoardSize; i++)
	{
		std::vector<int> lineBoard;
		for (int j = 0; j < kBoardSize; j++)
		{
			lineBoard.push_back(0);
		}
		gameMap.push_back(lineBoard);
	}
	playerFlag = true;
}

void GameModel::updateMap(int row, int col)
{
	if (playerFlag)
		gameMap[row][col] = 1;
	else
		gameMap[row][col] = -1;
	playerFlag = !playerFlag;
}

void GameModel::actionByPerson(int row, int col)
{
	updateMap(row,col);
}

bool GameModel::isWin(int row, int col)
{
	//水平方向检查
	for (int i = 0; i <= kBoardSize - 5; i++)
	{
		if (gameMap[row][i] == 1||gameMap[row][i]==-1)
		{
			if (gameMap[row][i] == gameMap[row][i + 1])
			{
				if (gameMap[row][i + 1] == gameMap[row][i + 2])
				{
					if (gameMap[row][i + 2] == gameMap[row][i + 3])
					{
						if (gameMap[row][i + 3] == gameMap[row][i + 4])
						{
							return true;
						}
					}
				}
			}
		}
	}
	//竖直方向检查
	for (int i = 0; i <= kBoardSize - 5; i++)
	{
		if (gameMap[i][col] == 1 || gameMap[i][col] == -1)
		{
			if (gameMap[i][col] == gameMap[i+1][col])
			{
				if (gameMap[i+1][col] == gameMap[i+2][col])
				{
					if (gameMap[i+2][col] == gameMap[i+3][col])
					{
						if (gameMap[i+3][col] == gameMap[i+4][col])
						{
							return true;
						}
					}
				}
			}
		}
	}

	//135度方向检查
	int krow = kBoardSize -1- row;
	if (krow <= col)
	{
		int i_135 = row + krow;
		int j_135 = col - krow;
		for (j_135; j_135 <= kBoardSize - 5; j_135++)
		{
			if (gameMap[i_135][j_135] == 1)
			{
				if (gameMap[i_135][j_135] == gameMap[i_135 - 1][j_135 + 1])
				{
					if (gameMap[i_135 - 1][j_135 + 1] == gameMap[i_135 - 2][j_135 + 2])
					{
						if (gameMap[i_135 - 2][j_135 + 2] == gameMap[i_135 - 3][j_135 + 3])
						{
							if (gameMap[i_135 - 3][j_135 + 3] == gameMap[i_135 - 4][j_135 + 4])
							{
								return true;
							}
						}
					}
				}
			}i_135--;
		}
	}

	if (krow > col)
	{
		int i_135 = row + col;
		int j_135 = col - col;
		for (i_135; i_135 >= 4; i_135--)
		{
			if (gameMap[i_135][j_135] == 1)
			{
				if (gameMap[i_135][j_135] == gameMap[i_135 - 1][j_135 + 1])
				{
					if (gameMap[i_135 - 1][j_135 + 1] == gameMap[i_135 - 2][j_135 + 2])
					{
						if (gameMap[i_135 - 2][j_135 + 2] == gameMap[i_135 - 3][j_135 + 3])
						{
							if (gameMap[i_135 - 3][j_135 + 3] == gameMap[i_135 - 4][j_135 + 4])
							{
								return true;
							}
						}
					}
				}
			}j_135++;
		}
	}


	//45度方向检查
	if (row >= col)
	{
		int i_45 = row - col;
		int j_45 = col - col;
		for (i_45; i_45 < kBoardSize; i_45++)
		{
			if (gameMap[i_45][j_45] == 1)
			{
				if (gameMap[i_45][j_45] == gameMap[i_45 + 1][j_45 + 1])
				{
					if (gameMap[i_45 + 1][j_45 + 1] == gameMap[i_45 + 2][j_45 + 2])
					{
						if (gameMap[i_45 + 2][j_45 + 2] == gameMap[i_45 + 3][j_45 + 3])
						{
							if (gameMap[i_45 + 3][j_45 + 3] == gameMap[i_45 + 4][j_45 + 4])
							{
								return true;
							}
						}
					}
				}
			}j_45++;
		}
	}

	if (row < col)
	{
		int i_45 = row - row;
		int j_45 = col - row;
		for (j_45; j_45 < kBoardSize; j_45++)
		{
			if (gameMap[i_45][j_45] == 1)
			{
				if (gameMap[i_45][j_45] == gameMap[i_45 + 1][j_45 + 1])
				{
					if (gameMap[i_45 + 1][j_45 + 1] == gameMap[i_45 + 2][j_45 + 2])
					{
						if (gameMap[i_45 + 2][j_45 + 2] == gameMap[i_45 + 3][j_45 + 3])
						{
							if (gameMap[i_45 + 3][j_45 + 3] == gameMap[i_45 + 4][j_45 + 4])
							{
								return true;
							}
						}
					}
				}
			}i_45++;
		}
	}
	return false;
}

bool GameModel::isDead()//死局,即棋盘被下满了
{
	for(int i=0;i<kBoardSize;i++)
		for (int j = 0; j < kBoardSize; j++)
		{
			if (gameMap[i][j] == 0)
				return false;
		}
	return true;
}

6、gameModel.h代码如下:

#ifndef GAMEMODEL_H
#define GAMEMODEL_H

#include<QObject>
#include<vector>

enum GameStatus
{
	playing,
	win,
	dead
};

const int kBoardSize = 15;

class GameModel
{
public:

public:
	std::vector<std::vector<int>>gameMap;
	bool playerFlag;
	GameStatus gameStatus;

	void startGame();
	void actionByPerson(int row, int col);
	void updateMap(int row, int col);
	bool isWin(int row, int col);
	bool isDead();

};
#endif // !GAMEMODEL_H

7、Qwzq.cpp代码如下:

#include "Qwzq.h"
#include <QMouseEvent>
#include <QMenuBar>
#include <QPainter>
#include <QDebug>
#include<QMessageBox>


const int kBoardMargin = 30;
const int kRadius = 15;
const int kBlockSize = 40;
const int kGridCount = 15;


Qwzq::Qwzq(QWidget *parent)
    : QMainWindow(parent)
{
    //ui.setupUi(this);
    setFixedSize(kBoardMargin * 2 + kGridCount * kBlockSize, kBoardMargin * 2 + kGridCount * kBlockSize);
    setMouseTracking(true);

    QMenu* gameMenu = menuBar()->addMenu(tr("Game Model:"));
    QAction* actionPVP = new QAction("PVP", this);
    menuBar()->addAction(actionPVP);

    connect(actionPVP, SIGNAL(triggered()), this, SLOT(initPVPGame()));
    initGame();
}

void Qwzq::initGame()
{
    game = new GameModel;
    initPVPGame();
    clickPosRow = clickPosCol = 0;
}

void Qwzq::initPVPGame()
{
    game->gameStatus = playing;
    game->startGame();
}

Qwzq::~Qwzq()
{
    if (game)
    {
        delete game;
        game = nullptr;
    }

}

void Qwzq::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);//防锯齿
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    for (int i = 0; i < kGridCount+1; i++)
    {
        painter.drawLine(kBoardMargin,kBoardMargin+i*kBlockSize,size().width()-kBoardMargin,kBoardMargin+i*kBlockSize);
        painter.drawLine(kBoardMargin+i*kBlockSize, kBoardMargin,kBoardMargin+i*kBlockSize,size().height()-kBoardMargin);
    }

    for (int i = 0; i < kGridCount; i++)
    {
        for (int j = 0; j < kGridCount; j++)
        {
            if (game->gameMap[i][j] == 1)
            {
                brush.setColor(Qt::white);
                painter.setBrush(brush);
                painter.drawEllipse(kBoardMargin+kBlockSize*j-kRadius,kBoardMargin+kBlockSize*i-kRadius,kRadius*2,kRadius*2);
            }
            else if (game->gameMap[i][j]==-1)
            {
                brush.setColor(Qt::black);
                painter.setBrush(brush);
                painter.drawEllipse(kBoardMargin + kBlockSize * j - kRadius, kBoardMargin + kBlockSize * i - kRadius, kRadius * 2, kRadius * 2);
            }
        }
    }
    QString str;
    if (game->isWin(clickPosRow, clickPosCol))
    {
        str = "Win!";
        QMessageBox::StandardButton btnValue = QMessageBox::information(this, tr("result"), str);
        close();
    }
    if (game->isDead())
    {
        str = "Over!";
        QMessageBox::StandardButton btnValue = QMessageBox::information(this, tr("result"), str);
        close();
    }
}

void Qwzq::mousePressEvent(QMouseEvent* event)
{
    int x = event->x();
    int y = event->y();

    int kr = kBoardMargin + kBlockSize * kGridCount;
    int kd = kBoardMargin + kBlockSize*kGridCount;
    if (x>=kBoardMargin&&x<=kr&&y>=kBoardMargin&&y<=kd)
    {
        int x1 = (x - kBoardMargin) / kBlockSize;
        int y1 = (y - kBoardMargin) / kBlockSize;

        x1 = x - (kBoardMargin + kBlockSize * x1);
        y1 = y - (kBoardMargin + kBlockSize * y1);

        if (x1 > kBlockSize / 2)
            x = (x-kBoardMargin) / kBlockSize + 1;
        else
            x = (x - kBoardMargin) / kBlockSize;

        if (y1 > kBlockSize / 2)
            y = (y-kBoardMargin) / kBlockSize + 1;
        else
            y = (y - kBoardMargin) / kBlockSize;
        
        game->updateMap(y, x);
        clickPosRow = y;
        clickPosCol = x;
    }
    update();
}

8、Qwzq.h代码如下:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_Qwzq.h"
#include <GameModel.h>


class Qwzq : public QMainWindow
{
    Q_OBJECT

public:
    Qwzq(QWidget *parent = nullptr);
    ~Qwzq();

    GameModel* game;
    int clickPosRow, clickPosCol;
    void initGame();

private slots:
    void initPVPGame();

private:


private:
    Ui::QwzqClass ui;
    void paintEvent(QPaintEvent* event);
    void mousePressEvent(QMouseEvent* event);
};

9、main.cpp代码如下:

#include "Qwzq.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Qwzq w;
    w.show();
    return a.exec();
}

10、运行界面如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/297397.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性代数第一课+第二课总结

第一课 第一课是简单的行列式计算&#xff0c;主要就是要把左下角的数字全部转换为0&#xff0c;通过减去其他行的式子即可实现&#xff0c;最后把对角线的所有数字相乘&#xff0c;得到的结果是最后行列式的答案 第二课 例题1 硬算理论上其实也是可行的&#xff0c;但是使…

遇见狂神说 Spring学习笔记(完整笔记+代码)

简介 Spring是一个开源的免费的框架&#xff08;容器&#xff09;Spring是一个轻量级的、非入侵式的框架控制反转(IOC&#xff09;&#xff0c;面向切面编程 (AOP)支持事务的处理&#xff0c;支持对框架进行整合 Spring就是一个轻量级的控制反转&#xff08;IOC&#xff09;和…

亚马逊云科技基于 listmonk 的电子邮件营销解决方案

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 背景 电子邮件营销&#xff08;EDM&#xff09;在广告、电商、供应链物流等行业应用…

Linux操作系统基础(10):Linux的特殊权限

1. 特殊权限是什么 在Linux中&#xff0c;特殊权限是指针对文件或目录的特殊权限设置&#xff0c;包括SetUID、SetGID和Sticky Bit。 SetUID&#xff08;Set User ID&#xff09;&#xff1a; 当一个可执行文件被设置了SetUID权限后&#xff0c;当任何用户执行该文件时&#x…

UI5与后端的文件交互(二)

文章目录 前言一、开发Action1. 创建Structure2. BEDF添加Action3. class中实现Action 二、修改UI5 项目1. 添加一个按钮2. 定义事件函数 三、测试及解析1. 测试2. js中提取到的excel流数据3. 后端解析 前言 这系列文章详细记录在Fiori应用中如何在前端和后端之间使用文件进行…

数字图像处理(图像灰度变换、图像直方图及均衡、图像中值滤波、图像空域锐化增强、图像频域滤波)

数字图像处理&#xff08;图像灰度变换、图像直方图及均衡、图像中值滤波、图像空域锐化增强、图像频域滤波&#xff09; 目录 1 图像灰度变换 1.1 灰度线性变换 1.2 图像二值化 1.3 负象变换 1.4 灰度非线性变换 1.5 程序设计流程图 2 图像直方图及均衡 2.1 直方图 2…

了解单元测试

一&#xff0c;测试分类 1.1 E2E测试&#xff08;end to end端到端测试&#xff09; 属于黑盒测试。 主要通过测试框架&#xff0c;站在用户测试人员的角度&#xff0c;模拟用户的操作进行页面功能的验证&#xff0c;不管内部实现机制&#xff0c;完全模拟浏览器的行为。&am…

Pytest——Fixture夹具的使用

一、什么是Fixture 在测试开展的过程中&#xff0c;会需要考虑到测试前的准备工作&#xff0c;以及测试后的释放操作行为。这些在Pytest中&#xff0c;会通过Fixture的方式来实现。如果说在运行pytest的测试用例的时候&#xff0c;需要调用一些数据来实现测试行为&#xff0c;…

thingsboard规则节点功能记录(自用)

本文是对【ThingsBoard源码级分析规则节点使用第一季】 https://www.bilibili.com/video/BV1CT411e7vt/?p4&share_sourcecopy_web&vd_source9a5ca7ed3cff97385fdab4b6188e485c 学习的一些记录&#xff0c;加深自己的理解&#xff0c;在此声明。 asset profile switch…

五、HTML 标题

在 HTML 文档中&#xff0c;标题很重要。 一、HTML 标题 标题&#xff08;Heading&#xff09;是通过 <h1> - <h6> 标签进行定义的。<h1> 定义最大的标题。 <h6> 定义最小的标题。 <h1>这是一个标题。</h1> <h2>这是一个标题。&l…

微型导轨在设备中起什么作用

微型导轨精度高&#xff0c;摩擦系数小&#xff0c;自重轻&#xff0c;结构紧凑&#xff0c;可以用于电子制造设备、半导体制造设备、医疗设备、光学设备和机器人等各种工业机械设备中&#xff0c;那么微型导轨在设备中起什么作用呢&#xff1f; 1、导向与定位&#xff1a;为机…

Flume基础知识(九):Flume 企业开发案例之复制和多路复用

1&#xff09;案例需求 使用 Flume-1 监控文件变动&#xff0c;Flume-1 将变动内容传递给 Flume-2&#xff0c;Flume-2 负责存储 到 HDFS。同时 Flume-1 将变动内容传递给 Flume-3&#xff0c;Flume-3 负责输出到 Local FileSystem。 2&#xff09;需求分析&#xff1a; 3&…

【论文解读】基于神经辐射场NeRF的像素级交互式编辑(Seal-3D)

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://arxiv.org/pdf/2307.15131 项目主页&#xff1a;https://windingwind.github.io/seal-3d/ 摘要&#xff1a; 随着隐式神经表征或神经辐射场&#xff08;NeRF&#xff09;的普及…

推荐几个免费的HTTP接口Mock网站和工具

在前后端分离开发架构下&#xff0c;经常遇到调用后端数据API接口进行测试、集成、联调等需求&#xff0c;比如&#xff1a; &#xff08;1&#xff09;前端开发人员很快开发完成了UI界面&#xff0c;但后端开发人员的API接口还没有完成&#xff0c;不能进行前后端数据接口对接…

嵌入式开发——电源管理单元PMU

学习目标 了解什么是电池管理单元PMU了解ARM32中的电源域了解几种省电模式学习内容 PMU PMU全称Power Management Unit,电源管理单元。 电源域 总共有三大电源域,包括VDD / VDDA域,1.2V域和备份域。 VDD/VDDA域 VDD/VDDA域如下图: 提供PMU 常规电源供应以下模块的供电…

C# 反射的乌云,MethodInfo的Json序列化参数入参问题

文章目录 前言直接运行MethodInfo运行结果 Json解决ParamterInfo实例化运行结果无法实例化问题部分参数的问题 Json反序列化 经过长达一天的研究&#xff0c;我终于完全的解决的了实战思路方法测试用例运行测试运行结果 代码总结总结 前言 我上篇文章已经基本解决了反射的基本…

【SpringCloud】之远程消费(进阶使用)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringCloud开发之远程消费》。&#x1f3af;&a…

python画图工具总结

一、python工具 python运行工具&#xff1a;Anaconda3 Anaconda3运行模式&#xff1a;jupyter notebook 操作系统&#xff1a;window11 二、折线图 from matplotlib import pyplot import matplotlib.pyplot as plt from math import sqrt import pandas as pd from matplot…

ffmpeg.c(4.3.1)源码剖析

文章目录 前言一、FFmpeg 源码结构图二、ffmpeg.h 头文件详解三、main 函数主要流程分析四、ffmpeg_parse_options1、命令行例子①、解析命令行 split_commandline()②、parse_optgroup()③、MATCH_PER_XXX_OPT() 2、vf 选项解析①、filters②、vf 术语③、avfilter_graph_pars…

【LeetCode每日一题】2807. 在链表中插入最大公约数(模拟+求最大公约数的6中写法)

2024-1-6 文章目录 [2807. 在链表中插入最大公约数](https://leetcode.cn/problems/insert-greatest-common-divisors-in-linked-list/)思路&#xff1a;模拟求最大公约数的几种方法&#xff1a; 1.暴力枚举法2.辗转相除法3.辗转相除法 ---递归调用4.辗转相除法 ---递归调用---…