VS+QT五子棋游戏开发

news2024/12/25 1:20:26

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、运行界面如下:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity之键盘鼠标的监控

小编最近在玩大表哥2&#xff0c;通过 W、A、S、D 来移动亚瑟&#xff0c;鼠标左键来不吃牛肉 我们都知道玩家通过按键鼠标来控制游戏人物做出相应的行为动作&#xff0c;那在Unity引擎里是怎么知道玩家是如何操作的呢&#xff1f;本篇来介绍Unity是怎样监控键盘和鼠标的。 首先…

智创有术开发公司,星潮宇宙开发。

2024年&#xff0c;星潮宇宙全网首发&#xff0c;一个全新的赛道将被开启&#xff0c;这将对游戏产业产生深远的影响。本文将深入探讨这场首发的对接团队以及他们的突破性举措&#xff0c;以展示其对游戏界的重要意义。 星潮宇宙全网首发概述 星潮宇宙的全网首发意味着将有一…

Cloud模型matlab

学习资料python 多维正态云python 预备知识&#xff1a; 如何获取具有特定均值和方差的正态分布随机数。首先&#xff0c;初始化随机数生成器&#xff0c;以使本示例中的结果具备可重复性。 rng(0,twister);基于均值为 500 且标准差为 5 的正态分布创建包含 1000 个随机值的向…

损失函数篇 | YOLOv8 引入 Shape-IoU 考虑边框形状与尺度的度量

作者导读&#xff1a;Shape-IoU&#xff1a;考虑边框形状与尺度的度量 论文地址&#xff1a;https://arxiv.org/abs/2312.17663 作者视频解读&#xff1a;https://www.bilibili.com 开源代码地址&#xff1a;https://github.com/malagoutou/Shape-IoU/blob/main/shapeiou.py…

Linux第16步_安装NFS服务

NFS&#xff08;Network File System&#xff09;是一种在网络上实现的分布式文件系统&#xff0c;它允许不同的操作系统和设备之间共享文件和资源。 在创建的linux目录下&#xff0c;再创建一个“nfs“文件夹&#xff0c;用来供nfs服务器使用&#xff0c;便于”我们的开发板“…

Android Studio 模拟器卡死的解决方法!

目录 前言 一、常规方法 二、简便解决方法 前言 在开发过程中&#xff0c;使用Android Studio模拟器是一种常见的方式来测试和调试应用程序。然而&#xff0c;有时候你可能会遇到模拟器卡死的情况&#xff0c;这给开发工作带来了一定的困扰。模拟器卡死可能会让你无法正常进…

设计模式——迭代器模式(Iterator Pattern)

概述 迭代器模式(Iterator Pattern)&#xff1a;提供一种方法来访问聚合对象&#xff0c;而不用暴露这个对象的内部表示&#xff0c;其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。 在软件开发中&#xff0c;我们经常需要使用聚合对象来存储一系列数据。聚合对象拥有…

密码学入门 古老的围栏密码技术

1、简述 由于隐私和安全的重要性不断增加&#xff0c;已经开发了多种加密方法和技术来保护我们的敏感数据。随着时间的推移而演变&#xff0c;从经典密码学发展到现代密码学。 在本文中&#xff0c;我们将了解一种被称为围栏密码技术的技术&#xff0c;涵盖其加密和解密过程及其…

Unity组件开发--升降梯

我开发的升降梯由三个部分组成&#xff0c;反正适用于我的需求了&#xff0c;其他人想复用到自己的项目的话&#xff0c;不一定。写的也不是很好&#xff0c;感觉搞的有点复杂啦。完全可以在优化一下&#xff0c;项目赶工期&#xff0c;就先这样吧。能用就行&#xff0c;其他的…

MidJourney笔记(10)-faq-fast-help-imagine-info-public-stealth

/faq 在官方 Midjourney Discord 服务器中使用可快速生成流行提示工艺频道常见问题解答的链接。 不过这个命令,我也是没有找到入口,之前还能在MidJourney的频道里使用,然后最近发现没有权限,有点奇怪。不知道系统又做了什么升级。 /fast 切换到快速模式。

Vue3-34-路由-路由配置参数 props

说明 路由的路径中可以携带参数&#xff0c; 形式如 &#xff1a;/a/:pname &#xff0c;这个:表示这是个参数&#xff0c;pname &#xff1a;表示 参数名称。 在组件中&#xff0c;可以通过 当前路由对象的 params 属性来获取到这个参数&#xff0c; 当前路由对象 可以通过 us…

Flutter 混合开发 - aar打包

背景 项目接入 Flutter 后有两种方式&#xff0c;一种是 module 引入开发&#xff0c;一种是 aar 依赖开发。当前项目中在 Debug 阶段为了方便调试采用 module 开发&#xff0c;在发版时&#xff08;即 Release 阶段&#xff09;采用 aar 依赖引入。为了配合这种模式就需要在 …

SpringBoot中动态注册接口

1. 说明 接口注册&#xff0c;使用RequestMappingHandlerMapping来实现mybatis中动态执行sql使用github上的SqlMapper工具类实现 2. 核心代码片段 以下代码为spring动态注册接口代码示例 Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping;publ…

手机上连网络转接app,电脑连接手机,共用网络转接app的办法

方法一&#xff0c;&#xff08;不推荐&#xff09; 因为太简单了所以写一下 电脑安装MuMu模拟器&#xff0c;之后安装网络转接app&#xff0c;这个模拟器设置了从电脑上安装app和&#xff0c;安卓与电脑同步文件夹功能&#xff0c;实现文件共享。所以直接用就可以了。 方法二…

彻底认识Unity ui设计中Space - Overlay、Screen Space - Camera和World Space三种模式

文章目录 简述Screen Space - Overlay优点缺点 Screen Space - Camera优点缺点 World Space优点缺点 简述 用Unity中开发了很久&#xff0c;但是对unity UI管理中Canvas组件的Render Mode有三种主要类型&#xff1a;Screen Space - Overlay、Screen Space - Camera和World Spa…

OR-3150:IGBT驱动光耦,可替代HCPL3150

具有MOSFET高输入阻抗和GTR低导通压降特性提供隔离反馈 高隔离电压 1.5A输出电流 工业温度范围&#xff1a;–40C 至 110C 宽工作 VCC 范围 特征 VCM 1500V 时最小共模抑制 &#xff08;CMR&#xff09; 为 35 kV/μs 最大低电平输出电压 &#xff08;VOL&#xff09; 1.0…

ERROR:SyntaxError: Non-ASCII character ‘\xc3‘ in file

报错信息&#xff1a; SyntaxError: Non-ASCII character ‘\xc3’ in file /home/user/ROSpy-LeaderFollower/src/follow_/src/scripts/tb3_flw.py on line 46, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details 解决办法&#xff1a; pyt…

数据的创建、调用、修改、删除存储过程,以及第一类丢失更新(回滚丢失)和 第二类丢失更新(覆盖丢失/两次更新问题)

数据的创建存储过程、调用存储过程、修改存储过程、删除存储过程&#xff0c;以及第一类丢失更新&#xff08;回滚丢失&#xff09;和 第二类丢失更新&#xff08;覆盖丢失/两次更新问题&#xff09; 文章目录 一、创建存储的语法二、调用存储过程三、修改存储过程四、删除存储…

码云Gitee复制 GitHub 项目

码云提供了直接复制 GitHub 项目的功能&#xff0c;方便我们做项目的迁移和下载。 1.新建仓库 2.导入仓库 3.强制同步 如果 GitHub 项目更新了以后&#xff0c;在码云项目端可以手动重新同步&#xff0c;进行更新&#xff01;

Vue3-36-路由-路由的元数据信息 meta

什么是 meta 简单的理解&#xff0c;meta 就是路由对象 的一个属性对象&#xff0c; 可以 通过这个 属性给 路由对象添加 一些必要的属性值&#xff0c; 在使用路由对象时可以获取到这个属性型对象&#xff0c;从而进行一些其他的逻辑判断。 meta 这个非常的简单&#xff0c;就…