VS+QT五子棋游戏开发

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

2、文件结构如下图:

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

cpp 复制代码
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、绘制旗子代码,如下:

cpp 复制代码
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代码如下:

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代码如下:

cpp 复制代码
#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代码如下:

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代码如下:

cpp 复制代码
#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代码如下:

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

相关推荐
我是黄大仙7 分钟前
利用飞书多维表格自动发布版本
运维·服务器·数据库·飞书
曾经的三心草8 分钟前
Mysql之约束与事件
android·数据库·mysql·事件·约束
WuMingf_15 分钟前
redis
数据库·redis
Dontla21 分钟前
Rust泛型系统类型推导原理(Rust类型推导、泛型类型推导、泛型推导)为什么在某些情况必须手动添加泛型特征约束?(泛型trait约束)
开发语言·算法·rust
张某布响丸辣22 分钟前
SQL中的时间类型:深入解析与应用
java·数据库·sql·mysql·oracle
Neophyte06081 小时前
C++算法练习-day40——617.合并二叉树
开发语言·c++·算法
慕容复之巅1 小时前
基于MATLAB的条形码的识别图像处理报告
开发语言·图像处理·matlab
zqzgng1 小时前
Python 数据可视化pilot
开发语言·python·信息可视化
写bug的小屁孩1 小时前
websocket初始化
服务器·开发语言·网络·c++·websocket·网络协议·qt creator