【C++】Qt环境下的五子棋小程序

这篇具有很好参考价值的文章主要介绍了【C++】Qt环境下的五子棋小程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现要求

这个程序是一个基于Qt的五子棋游戏,实现了人机对战和双人对战两种游戏模式,提供了基本的棋谱记录和游戏音效功能。程序采用了MVC模式,将数据与界面分离,实现了代码的模块化和可扩展性。主要构建包括三个文件,分别为GameModel.h、mainwindow.h和mainwindow.cpp,它们分别实现了游戏逻辑、游戏界面和界面与逻辑的交互。其中,游戏逻辑主要实现在GameModel类中,包括游戏规则、棋盘的数据结构和游戏状态的维护等;游戏界面主要实现在mainwindow.h和mainwindow.cpp中,包括棋盘的绘制、交互事件的处理、音效的播放和游戏结果的显示等。用户可以通过鼠标点击棋盘落下棋子,在游戏中实时查看落子信息,并通过音效提示,游戏结束后弹出对话框。

实现思路

  1. 定义GameModel类,包括游戏规则、棋盘的数据结构和游戏状态的维护等。
  2. 定义MainWindow类,主要用于具体实现游戏界面,包含了一些私有成员变量和函数,如棋盘、鼠标事件的处理、游戏模式切换等。
  3. 在mainwindow.cpp中实现棋盘的绘制、交互事件的处理和音效的播放等功能。
  4. 在GameModel.cpp中实现游戏开始、更新游戏地图、人类和AI的行动、计算得分、判断胜利和平局等游戏逻辑。
  5. 在main.cpp中创建应用程序对象,创建和显示主窗口,启动事件循环。
  6. 结合信号和槽机制,实现游戏界面与游戏逻辑的交互。
  7. 提供基本的棋谱记录和游戏音效功能,使用户在游戏中获得更好的游戏体验。

难点

双人对战只需要判断是否有五个棋子连成线即可判断对局胜负。人机对战相对复杂,需要实现AI下棋的功能。
电脑下棋的思路是通过计算每个空位 AI 下该棋子后的得分,来决定下哪个位置的棋子。得分高的位置就是AI应该下的最佳位置。

当AI需要决定下一步走哪个位置时,它会考虑每个空白位置对游戏胜利的贡献程度,评分函数就是用来计算每个空白位置的得分。

评分函数的计算方式是,在棋盘上遍历每个空白位置,然后从这个位置出发向上下左右、左上到右下、右上到左下三个方向扩展,统计这些方向上连续出现的X或O的个数。对于每个空白位置,分别计算其在三个方向上的得分,然后将三个方向的得分相加,即可得到该位置的总得分。

整体功能架构

文件名称 功能描述
GameModel.h 定义了游戏模型类GameModel,包括游戏的基本信息和方法,如棋盘、得分地图、玩家标志、游戏状态、游戏类型和各种操作方法等
mainwindow.h 定义了MainWindow类,使用继承自QMainWindow类的方式,主要用于具体实现游戏界面,包含了一些私有成员变量和函数,如棋盘、鼠标事件的处理、游戏模式切换等
GameModel.cpp 实现了GameModel类的方法函数,如游戏开始、更新游戏地图、人类和AI的行动、计算得分、判断胜利和平局等
mainwindow.cpp 实现了游戏界面的方法函数,包括开始游戏、游戏模式切换、棋盘的绘制、鼠标事件的响应、音效的播放、游戏结果的显示等
main.cpp 程序入口文件,创建应用程序对象,创建和显示主窗口,启动事件循环

代码实现

GameModel.h

#ifndef GAMEMODEL_H
#define GAMEMODEL_H

#include <QObject>
#include <vector>

enum GameType
{
    person,
    bot
};


enum GameStatus
{
    playing,
    win,
    dead
};

const int kBoardSize=15;

class GameModel
{
public:
    GameModel();

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

    void startGame(GameType type);
    void calculateScore();
    void actionByPerson(int row,int col);
    void actionByAi(int &row,int &col);
    void updateMap(int row,int col);
    bool isWin(int row,int col);
    bool isDeadGame();

signals:

};
#endif // GAMEMODEL_H

该文件是一个头文件,定义了一个游戏模型类 GameModel,包含一些游戏的基本信息和方法,如游戏地图、得分地图、玩家标志、游戏状态、游戏类型、开始游戏、计算分数、人类玩家行动、计算AI玩家行动、更新地图、判断游戏是否胜利、判断游戏是否结束等。同时包含了两个枚举类型 GameType 和 GameStatus,分别表示游戏类型和游戏状态。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "GameModel.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

protected:
    void paintEvent(QPaintEvent *event);

    void mouseMoveEvent(QMouseEvent *event);

    void mouseReleaseEvent(QMouseEvent *event);

private:
    GameModel *game;
    GameType game_type;
    int clickPosRow,clickPosCol;
    void initGame();
    void checkGame(int y,int x);



private slots:
    void chessOneByPerson();
    void chessOneByAi();
    void initPVPGame();
    void initPVCGame();




};
#endif // MAINWINDOW_H

这是一个名为mainwindow.h的头文件,其中定义了一个MainWindow类,该类继承自QMainWindow类。该类主要用于实现一个游戏,包括绘制棋盘,响应鼠标事件等功能。在该文件中还定义了一些私有函数和私有变量,包括一个GameModel类型的指针game,一个GameType类型的game_type,以及一些与游戏操作相关的函数,例如initGame、checkGame、chessOneByPerson、chessOneByAi等。此外,还定义了一些槽函数,例如initPVPGame和initPVCGame等,用于处理不同的游戏模式。

main.cpp

#include "mainwindow.h"

#include <QApplication>

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

此程序文件名为main.cpp,是一个Qt程序的主函数文件。该程序使用了Qt中的MainWindow类作为主窗口,通过调用show函数显示该窗口,然后进入Qt程序的事件循环。此程序中主要功能由MainWindow类实现,通过该类的构造函数和成员函数完成窗口的初始化、显示和其他操作。主函数的作用是创建应用程序对象,然后创建和显示主窗口,最后启动事件循环。整个程序的作用是显示一个Qt窗口,供用户进行交互操作。

GameModel.cpp

#include "GameModel.h"
#include <utility>
#include <time.h>
GameModel::GameModel()
{

}

void GameModel::startGame(GameType type)
{
    gameType = type;

    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);
    }

    if(gameType==bot)
    {
        scoreMap.clear();

        for(int i=0;i<kBoardSize;i++)
        {
            std::vector<int> lineScores;
            for(int j=0;j<kBoardSize;j++)
            {
                lineScores.push_back(0);
            }
            scoreMap.push_back(lineScores);
        }
    }
    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);
}

void GameModel::actionByAi(int &crow, int &ccol)
{
    calculateScore();
    int maxScore=0;
    std::vector<std::pair<int,int>> maxPoint;

    for(int i=1;i<kBoardSize;i++)
        for(int j=1;j<kBoardSize;j++)
        {
            if(gameMap[i][j]==0)
            {
                if(scoreMap[i][j]>maxScore)
                {
                    maxPoint.clear();
                    maxScore=scoreMap[i][j];
                    maxPoint.push_back(std::make_pair(i,j));
                }
                else if(scoreMap[i][j]==maxScore)
                    maxPoint.push_back(std::make_pair(i,j));
            }
        }
    srand((unsigned)time(0));
    int index=rand()%maxPoint.size();
    std::pair<int,int> pointPair=maxPoint.at(index);

    crow=pointPair.first;
    ccol=pointPair.second;
    updateMap(crow,ccol);
}

void GameModel::calculateScore()
{
    int personNum=0;
    int botNum=0;
    int emptyNum=0;

    scoreMap.clear();
    for(int i=0;i<kBoardSize;i++)
    {
        std::vector<int> lineScore;
        for(int j=0;j<kBoardSize;j++)
            lineScore.push_back(0);
        scoreMap.push_back(lineScore);
    }

    for(int row=0;row<kBoardSize;row++)
        for(int col=0;col<kBoardSize;col++)
        {
            if(row>0&&col>0&&gameMap[row][col]==0)
            {
                for(int y=-1;y<=1;y++)
                    for(int x=-1;x<=1;x++)
                    {
                        int personNum=0;
                        int botNum=0;
                        int emptyNum=0;

                        if(!(y==0&&x==0))
                        {
                            for(int i=1;i<=4;i++)
                            {
                                if(row+i*y>0&&row+i*y<kBoardSize&&col+i*x>0&&col+i*x<kBoardSize&&gameMap[row+i*y][col+i*x]==1)
                                {
                                    personNum++;
                                }
                                else if(row+i*y>0&&row+i*y<kBoardSize&&col+i*x>0&&col+i*x<kBoardSize&&gameMap[row+i*y][col+i*x]==0)
                                {
                                    emptyNum++;
                                    break;
                                }
                                else
                                    break;
                            }
                            for(int i=1;i<=4;i++)
                            {
                                if(row-i*y>0&&row-i*y<kBoardSize&&col-i*x>0&&col-i*x<kBoardSize&&gameMap[row-i*y][col-i*x]==1)
                                {
                                    personNum++;
                                }
                                else if(row-i*y>0&&row-i*y<kBoardSize&&col-i*x>0&&col-i*x<kBoardSize&&gameMap[row-i*y][col-i*x]==0)
                                {
                                    emptyNum++;
                                    break;
                                }
                                else
                                    break;
                            }
                            if(personNum==1)
                                scoreMap[row][col]+=10;
                            else if(personNum==2)
                            {
                                if(emptyNum==1)
                                    scoreMap[row][col]+=30;
                                else if(emptyNum==2)
                                    scoreMap[row][col]+=40;
                            }
                            else if(personNum==3)
                            {
                                if(emptyNum==1)
                                    scoreMap[row][col]+=60;
                                else if(emptyNum==2)
                                    scoreMap[row][col]+=110;
                            }
                            else if(personNum==4)
                                scoreMap[row][col]+=10000;
                            emptyNum=0;


                            for(int i=1;i<=4;i++)
                            {
                                if(row+i*y>0&&row+i*y<kBoardSize&&col+i*x>0&&col+i*x<kBoardSize&&gameMap[row+i*y][col+i*x]==1)
                                {
                                    botNum++;
                                }
                                else if(row+i*y>0&&row+i*y<kBoardSize&&col+i*x>0&&col+i*x<kBoardSize&&gameMap[row+i*y][col+i*x]==0)
                                {
                                    emptyNum++;
                                    break;
                                }
                                else
                                    break;
                            }
                            for(int i=1;i<=4;i++)
                            {
                                if(row-i*y>0&&row-i*y<kBoardSize&&col-i*x>0&&col-i*x<kBoardSize&&gameMap[row-i*y][col-i*x]==-1)
                                {
                                   botNum++;
                                }
                                else if(row-i*y>0&&row-i*y<kBoardSize&&col-i*x>0&&col-i*x<kBoardSize&&gameMap[row-i*y][col-i*x]==0)
                                {
                                    emptyNum++;
                                    break;
                                }
                                else
                                    break;
                            }
                            if(botNum==0)
                                scoreMap[row][col]+=5;
                            else if(botNum==1)
                                scoreMap[row][col]+=10;
                            else if(botNum==2)
                            {
                                if(emptyNum==1)
                                    scoreMap[row][col]+=25;
                                else if(emptyNum==2)
                                    scoreMap[row][col]+=50;

                            }
                            else if(botNum==3)
                            {
                                if(emptyNum==1)
                                    scoreMap[row][col]+=50;
                                else if(emptyNum==2)
                                    scoreMap[row][col]+=110;
                            }
                            else if(botNum==4)
                                scoreMap[row][col]+=10000;
                        }
                    }
            }
        }
}

bool GameModel::isWin(int row, int col)
{
    for(int i=0;i<5;i++)
    {
        if(col-i>0&&col-i+4<kBoardSize&&gameMap[row][col-i]==gameMap[row][col-i+1]&&gameMap[row][col-i]==gameMap[row][col-i+2]&&gameMap[row][col-i]==gameMap[row][col-i+3]&&gameMap[row][col-i]==gameMap[row][col-i+4])
            return true;
    }
    for(int i=0;i<5;i++)
    {
        if(row-i>0&&row-i+4<kBoardSize&&gameMap[row-i][col]==gameMap[row-i+1][col]&&gameMap[row-i][col]==gameMap[row-i+2][col]&&gameMap[row-i][col]==gameMap[row-i+3][col]&&gameMap[row-i][col]==gameMap[row-i+4][col])
            return true;
    }
    for(int i=0;i<5;i++)
    {
        if(row+i<kBoardSize&&row+i-4>0&&col-i>0&&col-i+4<kBoardSize&&gameMap[row+i][col-i]==gameMap[row+i-1][col-i+1]&&gameMap[row+i][col-i]==gameMap[row+i-2][col-i+2]&&gameMap[row+i][col-i]==gameMap[row+i-3][col-i+3]&&gameMap[row+i][col-i]==gameMap[row+i-4][col-i+4])
            return true;
    }
    for(int i=0;i<5;i++)
    {
        if(row-i>0&&row-i+4<kBoardSize&&col-i>0&&col-i+4<kBoardSize&&gameMap[row-i][col-i]==gameMap[row-i+1][col-i+1]&&gameMap[row-i][col-i]==gameMap[row-i+2][col-i+2]&&gameMap[row-i][col-i]==gameMap[row-i+3][col-i+3]&&gameMap[row-i][col-i]==gameMap[row-i+4][col-i+4])
            return true;
    }
    return false;

}

bool GameModel::isDeadGame()
{
    for(int i=1;i<kBoardSize;i++)
        for(int j=1;j<kBoardSize;j++)
        {
            if(!(gameMap[i][j]==1||gameMap[i][j]==-1))
                return false;
        }
    return true;
}

该程序文件是一个游戏模型的实现,其中包含了游戏开始、更新游戏地图、人类和AI的行动、计算得分、判断胜利和平局等功能。程序使用了C++语言,其中定义了常量kBoardSize表示棋盘的大小。程序中的gameMap代表游戏地图,scoreMap代表每个空位的得分,playerFlag代表玩家的标记(true表示玩家为黑棋,false表示玩家为白棋),gameType代表游戏类型(bot表示人机对战)。在startGame()中初始化gameMap和scoreMap,并根据游戏类型初始化玩家标记。在actionByPerson()和actionByAi()中分别更新gameMap,并在actionByAi()中使用calculateScore()计算每个空位的得分,再根据得分为AI选择最好的空位进行行动。在calculateScore()中,分别计算空位周围读和AI已下的棋子形成的连续棋子数,并将其转换为得分,存储在scoreMap中。在isWin()中,根据五子棋规则判断某个空位是否胜利。在isDeadGame()中,判断游戏是否为平局。

mainwindow.cpp

#include "mainwindow.h"
#include <QPainter>
#include <QTimer>
#include <QSound>
#include <QMouseEvent>
#include <QMessageBox>
#include <QMenu>
#include <QMenuBar>
#include <QDebug>
#include <math.h>

#define CHESS_ONE_SOUND ":/res/chessone.wav"
#define WIN_SOUND ":/res/win.wav"
#define LOSE_SOUND ":/res/lose.wav"

const int kBoardMargin = 30; // 棋盘边缘空隙
const int kRadius = 15; // 棋子半径
const int kMarkSize = 6; // 落子标记边长
const int kBlockSize = 40; // 格子的大小
const int kPosDelta = 20; // 鼠标点击的模糊距离上限

const int kAIDelay = 700; // AI下棋的思考时间

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //ui->setupUi(this);

    setFixedSize(kBoardMargin*2+kBlockSize*kBoardSize,kBoardMargin*2+kBlockSize*kBoardSize);
    //setStyleSheet("background-color:white;");
    //setStyleSheet("background-color:transparent;");
    setMouseTracking(true);


    QMenu *gameMenu = menuBar()->addMenu(tr("Game Model:"));
    QAction *actionPVP = new QAction("PVP",this);
    connect(actionPVP,SIGNAL(triggered()),this,SLOT(initPVPGame()));
    menuBar()->addAction(actionPVP);
    //gameMenu->addAction(actionPVP);

    QAction *actionPVC = new QAction("PVC",this);
    connect(actionPVC,SIGNAL(triggered()),this,SLOT(initPVCGame()));
    menuBar()->addAction(actionPVC);
    //gameMenu->addAction(actionPVC);


    initGame();
}

MainWindow::~MainWindow()
{

    if(game)
    {
        delete game;
        game=nullptr;
    }
}

void MainWindow::initGame()
{
    game = new GameModel;
    initPVPGame();
}

void MainWindow::initPVPGame()
{
    game_type=person;
    game->gameStatus=playing;
    game->startGame(game_type);
    update();

}

void MainWindow::initPVCGame()
{
    game_type=bot;
    game->gameStatus=playing;
    game->startGame(game_type);
    update();
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing,true);

    for(int i=0;i<kBoardSize+1;i++)
    {
        painter.drawLine(kBoardMargin+kBlockSize*i,kBoardMargin,kBoardMargin+kBlockSize*i,size().height()-kBoardMargin);
        painter.drawLine(kBoardMargin,kBoardMargin+kBlockSize*i,size().width()-kBoardMargin,kBoardMargin+kBlockSize*i);
    }
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    if(clickPosRow>0&&clickPosRow<kBoardSize&&clickPosCol>0&&clickPosCol<kBoardSize&&game->gameMap[clickPosRow][clickPosCol]==0)
    {
        if(game->playerFlag)
            brush.setColor(Qt::white);
        else
            brush.setColor(Qt::black);
        painter.setBrush(brush);
        painter.drawRect(kBoardMargin+kBlockSize*clickPosCol-kMarkSize/2,kBoardMargin+kBlockSize*clickPosRow-kMarkSize/2,kMarkSize,kMarkSize);
    }

    for(int i=0;i<kBoardSize;i++)
        for(int j=0;j<kBoardSize;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);
            }
        }

    if(clickPosRow>0&&clickPosRow<kBoardSize&&clickPosCol>0&&clickPosCol<kBoardSize&&(game->gameMap[clickPosRow][clickPosCol]==1||game->gameMap[clickPosRow][clickPosCol]==-1))
    {
        if(game->isWin(clickPosRow,clickPosCol)&&game->gameStatus==playing)
        {
            qDebug()<<"win";
            game->gameStatus=win;
            QSound::play(WIN_SOUND);

            QString str;
            if(game->gameMap[clickPosRow][clickPosCol]==1)
                str="white player";
            else if(game->gameMap[clickPosRow][clickPosCol]==-1)
                str="black player";
            QMessageBox::StandardButton btnValue = QMessageBox::information(this,"congratulations",str+"win");

            if(btnValue==QMessageBox::Ok)
            {
                game->startGame(game_type);
                game->gameStatus=playing;
            }
        }
    }
    if(game->isDeadGame())
    {
        QSound::play(LOSE_SOUND);
        QMessageBox::StandardButton btnValue=QMessageBox::information(this,"oops","dead game");
        if(btnValue==QMessageBox::Ok)
        {
            game->startGame(game_type);
            game->gameStatus=playing;
        }
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    int x=event->x();
    int y=event->y();

    if(x>=kBoardMargin+kBlockSize/2&&x<size().width()-kBoardMargin&&y>=kBoardMargin+kBlockSize/2&&y<size().height()-kBoardMargin)
    {
        int col=x/kBlockSize;
        int row=y/kBlockSize;

        int leftTopPosX=kBoardMargin+kBlockSize*col;
        int leftTopPosY=kBoardMargin+kBlockSize*row;

        clickPosRow=-1;
        clickPosCol=-1;
        int len=0;

        len=sqrt((x - leftTopPosX) * (x - leftTopPosX) + (y - leftTopPosY) * (y - leftTopPosY));
        if(len<kPosDelta)
        {
            clickPosRow = row;
            clickPosCol = col;
        }
        len=sqrt((x - leftTopPosX - kBlockSize) * (x - leftTopPosX - kBlockSize) + (y - leftTopPosY) * (y - leftTopPosY));
        if (len < kPosDelta)
        {
            clickPosRow = row ;
            clickPosCol = col + 1;
        }
        len=sqrt((x-leftTopPosX)*(x-leftTopPosX)+(y-leftTopPosY-kBlockSize)*(y-leftTopPosY-kBlockSize));
        if(len<kPosDelta)
        {
            clickPosRow=row+1;
            clickPosCol=col;
        }
        len=sqrt((x-leftTopPosX-kBlockSize)*(x-leftTopPosX-kBlockSize)+(y-leftTopPosY-kBlockSize)*(y-leftTopPosY-kBlockSize));
        if(len<kPosDelta)
        {
            clickPosRow=row+1;
            clickPosCol=col+1;
        }

    }
    update();
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    // 人下棋,并且不能抢机器的棋
    if (!(game_type == bot && !game->playerFlag))
    {
        chessOneByPerson();
        // 如果是人机模式,需要调用AI下棋
        if (game->gameType == bot && !game->playerFlag)
        {
            // 用定时器做一个延迟
            QTimer::singleShot(kAIDelay, this, SLOT(chessOneByAi()));
        }
    }

}

void MainWindow::chessOneByPerson()
{
    if(clickPosRow!=-1&&clickPosCol!=-1&&game->gameMap[clickPosRow][clickPosCol]==0)
    {
        game->actionByPerson(clickPosRow,clickPosCol);
        QSound::play(CHESS_ONE_SOUND);
        update();
    }
}

void MainWindow::chessOneByAi()
{
    game->actionByAi(clickPosRow,clickPosCol);
    QSound::play(CHESS_ONE_SOUND);
    update();
}

该程序实现了一个围棋游戏的主窗口界面,可以通过菜单选择双人对战或人机对战,人机对战中可以调节AI下棋的思考时间。用户可以通过鼠标点击棋盘落下棋子,在游戏中实时查看落子信息,并通过音效提示,游戏结束后弹出对话框。程序采用了MVC模式,利用GameModel类管理游戏逻辑,将数据与界面分离,实现了代码的模块化和可扩展性。

程序运行结果

如下图所示:
【C++】Qt环境下的五子棋小程序
【C++】Qt环境下的五子棋小程序

打包发布

可以使用Enigma Virtual Box软件打包程序。
Enigma Virtual Box是一个用于将应用程序打包为单一可执行文件的工具。它将应用程序和所有相关文件打包到一个虚拟的可执行文件中,这个文件可以像一个普通的可执行文件一样运行,而不需要安装或配置任何依赖项。这样在其他计算机上程序也可以运行,实现可移植性。文章来源地址https://www.toymoban.com/news/detail-418648.html

到了这里,关于【C++】Qt环境下的五子棋小程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++课程设计报告——简易五子棋游戏

    五子棋是是一种两人对弈的纯策略型棋类游戏,通常双方分别使用黑白两色的棋子在棋盘交替下棋,先形成五子连线者获胜。此次课程设计主要目的是实现五子棋的双人对弈,对战双方通过鼠标点击进行对弈。 游戏通过鼠标点击实现下棋,黑白子交替下棋。 程序通过使用e

    2024年02月13日
    浏览(39)
  • C++项目:网络版本在线五子棋对战

    目录 1.项目介绍 2.开发环境 3.核心技术 4. 环境搭建 5.websocketpp 5.1原理解析 5.2报文格式  5.3websocketpp常用接口介绍 5.4websocket服务器 6.JsonCpp使用 6.1Json数据格式 6.2JsonCpp介绍 7.MySQL API 7.1MySQL API介绍 7.2MySQL API使用 7.3实现增删改查操作 8.项目结构设计 8.1项目模块划分说明 8.2业务处

    2024年02月10日
    浏览(52)
  • C++在线五子棋对战(网页版)项目:websocket协议

    目标:认识理解websocket协议、websocket切换过程和websocket协议格式。认识和学会使用websocketpp库常用接口。了解websocketpp库搭建服务器流程,认识和学会使用websocketpp库bin接口,最后使用websocketpp库搭建服务器。 平时我们在逛某宝,点击商品查看商品信息,从HTTP角度来看,就是客

    2024年02月13日
    浏览(53)
  • python实现《五子棋》

            今天突然心血来潮,想全程自己写一个小游戏(毕竟对于一个才接触python不到一个月的小白来说,还是比较为难,虽然不算是完全成功,因为棋盘大小和布局还是借鉴了其它博主的,但这都是小问题,重要是其它的都是自己写的嘛!!!(咦,这小编真能扯,还不上

    2024年02月12日
    浏览(35)
  • Python实现五子棋

    我认为这个五子棋核心还是在于二维数组,将实际当中鼠标点击的物理位置转换到棋盘中的逻辑地址,之后便用数组的方法进行操作,例如检测是否获胜,电脑下棋策略等。 是否可落子 是否有输赢 每次标记最新下棋的位置即可 电脑下棋 策略:主要根据一个网上的经验评分

    2024年02月06日
    浏览(43)
  • 五子棋(Python实现)

    2024年02月11日
    浏览(44)
  • 微信小程序项目实例——双人五子棋

    项目代码见文字底部,点赞关注有惊喜 微信小程序项目实例——双人五子棋 双人五子棋是一款游戏小程序 两位选手可以在15x15的棋盘上 进行五子棋竞技 同时小程序设置了悔棋功能 点击落子 判断胜负 胜利效果 重新开始 悔棋 具体的介绍就到这里了 有兴趣的同学可以继续研

    2024年02月12日
    浏览(47)
  • C++项目:在线五子棋对战网页版--数据模块开发

    数据管理模块,基于mysql数据库进行数据管理以及封装数据管理模块实现数据库访问。因此,在数据库中,我需要为每一张表创建出对应类,通过类实例化的对象来访问这张数据库表中的数 据,这样的话当我们要访问哪张表的时候,使⽤哪个类实例化的对象即可。 那么在五子

    2024年02月13日
    浏览(35)
  • python实现简单五子棋

     规则 :用鼠标下子,黑子白子交替下子 核心 :1、使用turtle库画棋盘            2、turtle库中的onscreenclick()函数,实现鼠标点击 详细步骤: 用turtle()库fd()函数实现画直线,tracer(0)消除动画效果 定义一个二维数组,也就是列表来对应棋盘上的落子情况,没有子为0,黑子为

    2024年02月05日
    浏览(33)
  • python实现五子棋(完整代码)

    本文主要讲解基于p

    2024年02月10日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包