文章以及源码均为原创,当然欢迎转载,转载请加说明
用VS编写的Qt项目,包含双人模式、人机模式、联网模式,这篇文章贴出双人模式源码,欢迎阅读讨论,源码如下
gobang.h
#ifndef GOBANG_H #define GOBANG_H #include#include "ui_gobang.h" #include #include #include "doublegame.h" #include "manmachinegame.h" #include "onlinegame.h" #pragma execution_character_set("utf-8") class CGobang : public QWidget { Q_OBJECT public: CGobang(QWidget *parent = 0); ~CGobang(); private: Ui::CGobangClass ui; QStackedWidget m_StackedWidget; QPushButton m_DoubleGameButton; CDoubleGame m_DoubleGame; QPushButton m_ManMachineGameButton; CManMachineGame m_ManMachineGame; QPushButton m_OnlineGameButton; COnlineGame m_OnlineGame; public slots: void DoubleGameStartSlot(); void DoubleGameOverSlot(); void ManMachineGameStartSlot(); void ManMachineGameOverSlot(); void OnlineGameStartSlot(); void OnlineGameOverSlot(); }; #endif // GOBANG_H
gobang.cpp
#include "gobang.h"
CGobang::CGobang(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setFixedSize(240, 240);
setWindowTitle("五子棋");
connect(&m_DoubleGameButton, &QPushButton::clicked, this, &CGobang::DoubleGameStartSlot);
connect(&m_DoubleGame, &CDoubleGame::GameOverSignal, this, &CGobang::DoubleGameOverSlot);
m_DoubleGameButton.setParent(this);
m_DoubleGameButton.resize(100, 40);
m_DoubleGameButton.setText("双人游戏");
m_DoubleGameButton.move(70, 40);
connect(&m_ManMachineGameButton, &QPushButton::clicked, this, &CGobang::ManMachineGameStartSlot);
connect(&m_ManMachineGame, &CManMachineGame::GameOverSignal, this, &CGobang::ManMachineGameOverSlot);
m_ManMachineGameButton.setParent(this);
m_ManMachineGameButton.resize(100, 40);
m_ManMachineGameButton.setText("人机游戏");
m_ManMachineGameButton.move(70, 100);
connect(&m_OnlineGameButton, &QPushButton::clicked, this, &CGobang::OnlineGameStartSlot);
connect(&m_OnlineGame, &COnlineGame::GameOverSignal, this, &CGobang::OnlineGameOverSlot);
m_OnlineGameButton.setParent(this);
m_OnlineGameButton.resize(100, 40);
m_OnlineGameButton.setText("联网游戏");
m_OnlineGameButton.move(70, 160);
}
CGobang::~CGobang()
{
}
void CGobang::DoubleGameStartSlot()
{
m_DoubleGame.Start();
m_DoubleGame.show();
hide();
}
void CGobang::DoubleGameOverSlot()
{
m_DoubleGame.close();
show();
}
void CGobang::ManMachineGameStartSlot()
{
m_ManMachineGame.Start();
m_ManMachineGame.show();
hide();
}
void CGobang::ManMachineGameOverSlot()
{
m_ManMachineGame.close();
show();
}
void CGobang::OnlineGameStartSlot()
{
m_OnlineGame.show();
hide();
}
void CGobang::OnlineGameOverSlot()
{
m_OnlineGame.close();
show();
}
public.h
#ifndef PUBLIC_H #define PUBLIC_H const char BLACKCHESSPIECES = '1'; //黑棋 const char WHITECHESSPIECES = '2'; //白棋 const int XLEFT = 30;//棋盘左边界的X坐标 const int XRIGHT = 450;//棋盘右边界的X坐标 const int YUP = 30;//棋盘上边界的Y坐标 const int YDOWN = 450;//棋盘下边界的Y坐标 const int UNITLENGTH = 30;//单位长度,等于棋盘每个小格子的边长,也等于棋子的直径 #endif // PUBLIC_H
doublegame.h
#ifndef DOUBLEGAME_H #define DOUBLEGAME_H #include#include "ui_doublegame.h" #include #include #include #include #include "public.h" #pragma execution_character_set("utf-8") class CDoubleGame : public QWidget { Q_OBJECT public: CDoubleGame(QWidget *parent = 0); ~CDoubleGame(); //开始游戏 void Start(); protected: void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *I_Event); //关闭游戏 inline void Over(); //更新提示信息 void UpdateInfoArea(); //落子 void LuoZi(int I_Row, int I_Col); //是否赢棋 bool IsWin(int I_Row, int I_Col); //连珠数量 int GetLineSameNum(int I_RowChg, int I_ColChg, int I_Row, int I_Col); //获取落子位置(鼠标点击位置) bool GetPosition(int I_X, int I_Y, int &O_Row, int &O_Col); private: Ui::CDoubleGame ui; QPainter m_Painter; QPixmap m_Pixmap; QLabel m_BlackLabel; QLabel m_WhiteLabel; QLabel m_RoundLabel; char m_BlackOrWhite; char m_CheckerBoard[15][15]; int m_BlackNum; int m_WhiteNum; bool m_IsStart; signals: void GameOverSignal(); }; #endif // DOUBLEGAME_H
doublegame.cpp
#include "doublegame.h"
CDoubleGame::CDoubleGame(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setFixedSize(720, 480);
setWindowTitle("双人模式");
m_Pixmap = QPixmap(720, 480);
m_Pixmap.fill(Qt::lightGray);
QPalette Palette;
Palette.setColor(QPalette::WindowText,QColor(128, 64, 0));
QFont Font("宋体", 25);
m_BlackLabel.setParent(this);
m_BlackLabel.resize(UNITLENGTH * 6, UNITLENGTH * 3);
m_BlackLabel.move(XRIGHT + UNITLENGTH, YUP + UNITLENGTH);
m_BlackLabel.setFont(Font);
m_BlackLabel.setAlignment(Qt::AlignCenter);
m_BlackLabel.setPalette(Palette);
m_WhiteLabel.setParent(this);
m_WhiteLabel.resize(UNITLENGTH * 6, UNITLENGTH * 3);
m_WhiteLabel.move(XRIGHT + UNITLENGTH, YUP + UNITLENGTH*10);
m_WhiteLabel.setFont(Font);
m_WhiteLabel.setAlignment(Qt::AlignCenter);
m_WhiteLabel.setPalette(Palette);
m_RoundLabel.setParent(this);
m_RoundLabel.resize(UNITLENGTH * 6, UNITLENGTH * 2);
m_RoundLabel.move(XRIGHT + UNITLENGTH, YUP + UNITLENGTH*6);
m_RoundLabel.setFont(Font);
m_RoundLabel.setAlignment(Qt::AlignCenter);
m_RoundLabel.setPalette(Palette);
m_IsStart = false;
}
CDoubleGame::~CDoubleGame()
{
m_IsStart = false;
}
void CDoubleGame::paintEvent(QPaintEvent *)
{
if (!m_IsStart)
{
return;
}
m_Painter.begin(this);
m_Painter.drawPixmap(0, 0, m_Pixmap);
m_Painter.end();
}
void CDoubleGame::mousePressEvent(QMouseEvent *I_Event)
{
if (!m_IsStart)
{
return;
}
int X = 0;
int Y = 0;
int Row = 0;
int Col = 0;
if (Qt::LeftButton == I_Event->button())
{
X = I_Event->x();
Y = I_Event->y();
if (GetPosition(X, Y, Row, Col))
{
LuoZi(Row, Col);
if (IsWin(Row, Col))
{
Over();
}
else
{
if (BLACKCHESSPIECES == m_BlackOrWhite)
{
m_BlackOrWhite = WHITECHESSPIECES;
}
else
{
m_BlackOrWhite = BLACKCHESSPIECES;
}
UpdateInfoArea();
}
}
}
}
void CDoubleGame::Start()
{
if (m_IsStart)
{
return;
}
m_Painter.begin(&m_Pixmap);
QPen Pen(QColor(128, 64, 0));
QBrush Brush(QColor(128, 64, 0));
Brush.setStyle(Qt::SolidPattern);
m_Painter.setPen(Pen);
m_Painter.setBrush(Brush);
for (int x = XLEFT; x <= XRIGHT; x += UNITLENGTH)
{
m_Painter.drawLine(x, YUP, x, YDOWN);
}
for (int y = YUP; y <= YDOWN; y += UNITLENGTH)
{
m_Painter.drawLine(XLEFT, y, XRIGHT, y);
}
m_Painter.drawEllipse(QPoint(XLEFT + UNITLENGTH * 3, YUP + UNITLENGTH * 3), 3, 3);
m_Painter.drawEllipse(QPoint(XLEFT + UNITLENGTH * 3, YDOWN - UNITLENGTH * 3), 3, 3);
m_Painter.drawEllipse(QPoint(XRIGHT - UNITLENGTH * 3, YUP + UNITLENGTH * 3), 3, 3);
m_Painter.drawEllipse(QPoint(XRIGHT - UNITLENGTH * 3, YDOWN - UNITLENGTH * 3), 3, 3);
m_Painter.drawEllipse(QPoint(XLEFT + UNITLENGTH * 7, YUP + UNITLENGTH * 7), 3, 3);
m_Painter.drawLine(XRIGHT, YUP, XRIGHT + 240, YUP);
m_Painter.drawLine(XRIGHT, YUP + 150, XRIGHT + 240, YUP + 150);
m_Painter.drawLine(XRIGHT, YUP + 270, XRIGHT + 240, YUP + 270);
m_Painter.drawLine(XRIGHT, YDOWN, XRIGHT + 240, YDOWN);
m_Painter.drawLine(XRIGHT, YUP, XRIGHT, YDOWN);
m_Painter.drawLine(XRIGHT + 240, YUP, XRIGHT + 240, YDOWN);
m_Painter.end();
m_BlackLabel.setText("黑棋0手");
m_WhiteLabel.setText("白棋0手");
m_RoundLabel.setText("黑棋回合");
m_BlackOrWhite = BLACKCHESSPIECES;
memset(m_CheckerBoard, 0, sizeof(m_CheckerBoard));
m_BlackNum = 0;
m_WhiteNum = 0;
m_IsStart = true;
}
inline void CDoubleGame::Over()
{
m_Pixmap.fill(Qt::lightGray);
repaint();
m_IsStart = false;
emit this->GameOverSignal();
}
void CDoubleGame::UpdateInfoArea()
{
char Str[32] = { 0 };
sprintf_s(Str, "黑棋%d手", m_BlackNum);
m_BlackLabel.setText(Str);
sprintf_s(Str, "白棋%d手", m_WhiteNum);
m_WhiteLabel.setText(Str);
if (BLACKCHESSPIECES == m_BlackOrWhite)
{
sprintf_s(Str, "黑棋回合");
}
else
{
sprintf_s(Str, "白棋回合");
}
m_RoundLabel.setText(Str);
}
void CDoubleGame::LuoZi(int I_Row, int I_Col)
{
int X = I_Col * UNITLENGTH + XLEFT;
int Y = I_Row * UNITLENGTH + YUP;
if (BLACKCHESSPIECES == m_BlackOrWhite)
{
m_Painter.begin(&m_Pixmap);
QBrush Brush(QColor(0, 0, 0));
m_Painter.setBrush(Brush);
m_Painter.drawEllipse(QPoint(X, Y), 15, 15);
m_Painter.end();
m_BlackNum++;
}
else if (WHITECHESSPIECES == m_BlackOrWhite)
{
m_Painter.begin(&m_Pixmap);
QBrush Brush(QColor(255, 255, 255));
m_Painter.setBrush(Brush);
m_Painter.drawEllipse(QPoint(X, Y), 15, 15);
m_Painter.end();
m_WhiteNum++;
}
update();
m_CheckerBoard[I_Row][I_Col] = m_BlackOrWhite;
}
bool CDoubleGame::IsWin(int I_Row, int I_Col)
{
if (GetLineSameNum(0, 1,I_Row,I_Col) >= 5
|| GetLineSameNum(1, 0, I_Row, I_Col) >= 5
|| GetLineSameNum(1, 1, I_Row, I_Col) >= 5
|| GetLineSameNum(-1, 1, I_Row, I_Col) >= 5)
{
if (BLACKCHESSPIECES == m_BlackOrWhite)
{
m_BlackOrWhite = WHITECHESSPIECES;
UpdateInfoArea();
QMessageBox MessageBox(this);
MessageBox.setWindowTitle("赢了");
MessageBox.setText("黑棋赢了");
if (QMessageBox::Ok == MessageBox.exec())
{
}
}
else
{
m_BlackOrWhite = BLACKCHESSPIECES;
UpdateInfoArea();
QMessageBox MessageBox(this);
MessageBox.setWindowTitle("赢了");
MessageBox.setText("白棋赢了");
if (QMessageBox::Ok == MessageBox.exec())
{
}
}
return true;
}
return false;
}
int CDoubleGame::GetLineSameNum(int I_RowChg, int I_ColChg, int I_Row, int I_Col)
{
int Num = 0;
int RowTemp = I_Row;
int ColTemp = I_Col;
while (RowTemp >= 0 && RowTemp < 15 && ColTemp >= 0 && ColTemp < 15)
{
if (m_BlackOrWhite != m_CheckerBoard[RowTemp][ColTemp])
{
break;
}
Num++;
RowTemp += I_RowChg;
ColTemp += I_ColChg;
}
RowTemp = I_Row;
ColTemp = I_Col;
while (RowTemp >= 0 && RowTemp < 15 && ColTemp >= 0 && ColTemp < 15)
{
if (m_BlackOrWhite != m_CheckerBoard[RowTemp][ColTemp])
{
break;
}
Num++;
RowTemp -= I_RowChg;
ColTemp -= I_ColChg;
}
Num--;
return Num;
}
bool CDoubleGame::GetPosition(int I_X, int I_Y, int &O_Row, int &O_Col)
{
if (XLEFT - 5 <= I_X&&I_X <= XRIGHT + 5 && YUP - 5 <= I_Y&&I_Y <= YDOWN + 5)
{
I_X = I_X - XLEFT;
O_Col = I_X / UNITLENGTH;
if (I_X % UNITLENGTH < 6)
{
O_Col += 0;
}
else if (I_X % UNITLENGTH > 24)
{
O_Col += 1;
}
else
{
return false;
}
I_Y = I_Y - YUP;
O_Row = I_Y / UNITLENGTH;
if (I_Y % UNITLENGTH < 6)
{
O_Row += 0;
}
else if (I_Y % UNITLENGTH > 24)
{
O_Row += 1;
}
else
{
return false;
}
}
else
{
return false;
}
if (' ' != m_CheckerBoard[O_Row][O_Col])
{
return false;
}
return true;
}



