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