C++ Qt实现经典五子棋小游戏(双人游戏,人机大战)

为君一笑 提交于 2020-01-01 02:37:24

原创,转载请注明出处。
这里用Qt实现了五子棋,可进行双人游戏,人机对战,悔棋等操作,是C++,Qt的必备练手项目,界面设置如下图:
在这里插入图片描述
添加三个类,分别为游戏总控制类gamewidget 、界面类boardwidget和AI控制类gomokuai。代码分别如下:

boardwidget.h:

#ifndef BOARDWIDGET_H
#define BOARDWIDGET_H

#include <QWidget>
#include <QStack>
#include <QPoint>
#include <QSet>

typedef int (*Board)[15];

class BoardWidget : public QWidget
{
    Q_OBJECT
public:
    explicit BoardWidget(QWidget *parent = nullptr);

    //设置棋盘控件接受的下棋方,在ai模式中只接受白色方,双人模式中都接受
    void setReceivePlayers(const QSet<int> &value);
    //获取棋盘信息
    Board getBoard();

protected:
    void paintEvent(QPaintEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);

private:
    //初始化棋盘控件
    void initBoard();
    //切换下一位下棋者
    void switchNextPlayer();
    //检查是否有获胜方,或者平局
    void checkWinner();
    //判断从(x, y)处开始,是否有五个同色棋子在一条线上
    bool isFivePieceFrom(int x, int y);
    //判断从(x, y)处开始,向下是否有五个同色棋子
    bool isVFivePieceFrom(int x, int y);
    //判断从(x, y)处开始,向下是否有五个同色棋子
    bool isHFivePieceFrom(int x, int y);
    //判断从(x, y)处开始,右上方向是否有五个同色棋子
    bool isFSFivePieceFrom(int x, int y);
    //判断(x, y)处开始, 右下方向是否有五个同色棋子
    bool isBSFivePieceFrom(int x, int y);

signals:
    void gameOver(int winner);
    void turnNextPlayer(int player);

public slots:
    //清除棋盘信息,开始新游戏
    void newGame();
    //落子
    void downPiece(int x, int y);
    void undo(int steps);	//悔棋

public:
    static const QSize WIDGET_SIZE;         //棋盘控件大小
    static const QSize CELL_SIZE;           //棋盘单元格大小
    static const QPoint START_POS;          //棋盘单元格开始位置
    static const QPoint ROW_NUM_START;      //行标号开始位置
    static const QPoint CLU_NUM_START;      //列标号开始位置
    static const int BOARD_WIDTH = 15;      //棋盘列数
    static const int BOARD_HEIGHT = 15;     //棋盘行数
    static const int NO_PIECE = 0;          //棋子标志,表示无子
    static const int WHITE_PIECE = 1;       //棋子标志, 表示白子
    static const int BLACK_PIECE = 2;       //棋子标志,表示黑子
    static const bool WHITE_PLAYER = true;  //棋手标志, 表示白方
    static const bool BLACK_PLAYER = false; //棋手标志, 表示黑方

    void setTrackPos(const QPoint &value);  //设置当前鼠标所在棋盘中的位置

private:
    bool endGame;                               //游戏是否结束标志
    int board[BOARD_WIDTH][BOARD_HEIGHT];       //棋盘信息
    int nextPlayer;                             //表示下一位棋手
    QPoint trackPos;                            //记录鼠标在棋盘中的位置
    QVector<QPoint> winPoses;                   //获胜的五子位置
    QSet<int> receivePlayers;                   //棋盘接受点击下棋的棋手
    QStack<QPoint> dropedPieces;                //每一步落子位置
};

#endif // BOARDWIDGET_H

boardwidget.cpp:

#include "boardwidget.h"
#include <QPainter>
#include <QMouseEvent>
#include <QFile>
#include <QDataStream>

/*类静态数据成员定义*/
const QSize BoardWidget::WIDGET_SIZE(430, 430);
const QSize BoardWidget::CELL_SIZE(25, 25);
const QPoint BoardWidget::START_POS(40, 40);
const QPoint BoardWidget::ROW_NUM_START(15, 45);
const QPoint BoardWidget::CLU_NUM_START(39, 25);
const int BoardWidget::BOARD_WIDTH;
const int BoardWidget::BOARD_HEIGHT;
const int BoardWidget::NO_PIECE;
const int BoardWidget::WHITE_PIECE;
const int BoardWidget::BLACK_PIECE;
const bool BoardWidget::WHITE_PLAYER;
const bool BoardWidget::BLACK_PLAYER;

BoardWidget::BoardWidget(QWidget *parent) :
    QWidget(parent),
    trackPos(28, 28)
{
    setFixedSize(WIDGET_SIZE);
    setMouseTracking(true);

    initBoard();
}

void BoardWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.fillRect(0, 0, width(), height(), Qt::lightGray);	//背景颜色

    for (int i = 0; i < BOARD_WIDTH; i++)
    {
        painter.drawText(CLU_NUM_START + QPoint(i * CELL_SIZE.width(), 0),
                         QString::number(i + 1));
    }
    for (int i = 0; i < BOARD_HEIGHT; i++)
    {
        painter.drawText(ROW_NUM_START + QPoint(0, i * CELL_SIZE.height()),
                         QString::number(i + 1));
    }

    for (int i = 0; i < BOARD_WIDTH - 1; i++)	//绘制棋盘格子
    {
        for (int j = 0; j < BOARD_HEIGHT - 1; j++)
        {
            painter.drawRect(QRect(START_POS + QPoint(i * CELL_SIZE.width(), j * CELL_SIZE.height()),
                                   CELL_SIZE));
        }
    }

    painter.setPen(Qt::red);
    QPoint poses[12] = {
        trackPos + QPoint(0, 8),
        trackPos,
        trackPos + QPoint(8, 0),
        trackPos + QPoint(17, 0),
        trackPos + QPoint(25, 0),
        trackPos + QPoint(25, 8),
        trackPos + QPoint(25, 17),
        trackPos + QPoint(25, 25),
        trackPos + QPoint(17, 25),
        trackPos + QPoint(8, 25),
        trackPos + QPoint(0, 25),
        trackPos + QPoint(0, 17)
    };
    painter.drawPolyline(poses, 3);
    painter.drawPolyline(poses + 3, 3);
    painter.drawPolyline(poses + 6, 3);
    painter.drawPolyline(poses + 9, 3);

    painter.setPen(Qt::NoPen);
    for (int i = 0; i < BOARD_WIDTH; i++)	//绘制棋子
    {
        for (int j = 0; j < BOARD_HEIGHT; j++)
        {
            if (board[i][j] != NO_PIECE)
            {
                QColor color = (board[i][j] == WHITE_PIECE) ? Qt::white : Qt::black;
                painter.setBrush(QBrush(color));
                painter.drawEllipse(START_POS.x() - CELL_SIZE.width()/2 + i*CELL_SIZE.width(),
                                    START_POS.y() - CELL_SIZE.height()/2 + j*CELL_SIZE.height(),
                                    CELL_SIZE.width(), CELL_SIZE.height());
            }
        }
    }

    painter.setPen(Qt::red);
    if (!dropedPieces.isEmpty())
    {
        QPoint lastPos = dropedPieces.top();
        QPoint drawPos = START_POS + QPoint(lastPos.x() * CELL_SIZE.width(), lastPos.y() * CELL_SIZE.height());
        painter.drawLine(drawPos + QPoint(0, 5), drawPos + QPoint(0, -5));
        painter.drawLine(drawPos + QPoint(5, 0), drawPos + QPoint(-5, 0));
    }

    for (QPoint pos : winPoses)
    {
        QPoint drawPos = START_POS + QPoint(pos.x() * CELL_SIZE.width(), pos.y() * CELL_SIZE.height());
        painter.drawLine(drawPos + QPoint(0, 5), drawPos + QPoint(0, -5));
        painter.drawLine(drawPos + QPoint(5, 0), drawPos + QPoint(-5, 0));
    }
}

void BoardWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (receivePlayers.contains(nextPlayer) && !endGame)
    {
        QPoint pos = event->pos() - START_POS;
        int x = pos.x();
        int y = pos.y();
        int pieceX = x / CELL_SIZE.width();
        int pieceY = y / CELL_SIZE.height();
        int offsetX = x % CELL_SIZE.width();
        int offsetY = y % CELL_SIZE.height();
        if (offsetX > CELL_SIZE.width() / 2)
        {
            pieceX++;
        }
        if (offsetY > CELL_SIZE.height() / 2)
        {
            pieceY++;
        }
        downPiece(pieceX, pieceY);
    }
}

void BoardWidget::mouseMoveEvent(QMouseEvent *event)
{
    QPoint pos = event->pos() - START_POS + QPoint(CELL_SIZE.width()/2, CELL_SIZE.height()/2);
    int x = pos.x();
    int y = pos.y();
    //超过范围
    if (x < 0 || x >= CELL_SIZE.width() * BOARD_WIDTH ||
            y < 0 || y >= CELL_SIZE.height() * BOARD_HEIGHT)
    {
        return;
    }
    int offsetX = x % CELL_SIZE.width();
    int offsetY = y % CELL_SIZE.height();
    setTrackPos(QPoint(x - offsetX, y - offsetY) + START_POS - QPoint(CELL_SIZE.width()/2, CELL_SIZE.height()/2));
}


void BoardWidget::initBoard()
{
    receivePlayers << WHITE_PLAYER << BLACK_PLAYER;
    newGame();
}

void BoardWidget::downPiece(int x, int y)
{
    if (x >= 0 && x < BOARD_WIDTH && y >= 0 && y < BOARD_HEIGHT && board[x][y] == NO_PIECE)
    {
        dropedPieces.push(QPoint(x, y));
        board[x][y] = (nextPlayer == WHITE_PLAYER) ? WHITE_PIECE : BLACK_PIECE;
        update();
        checkWinner();
        if (!endGame)
        {
            switchNextPlayer();
        }
    }
}

void BoardWidget::undo(int steps)
{
    if (!endGame)
    {
        for (int i = 0; i < steps && !dropedPieces.isEmpty(); i++)
        {
            QPoint pos = dropedPieces.pop();
            board[pos.x()][pos.y()] = NO_PIECE;
        }

        update();
        if(steps==2)
        {
            nextPlayer=BLACK_PLAYER;
        }
        switchNextPlayer();
    }
}

void BoardWidget::setTrackPos(const QPoint &value)
{
    trackPos = value;
    update();
}

void BoardWidget::setReceivePlayers(const QSet<int> &value)
{
    receivePlayers = value;
}

Board BoardWidget::getBoard()
{
    return board;
}

void BoardWidget::switchNextPlayer()
{
    nextPlayer = !nextPlayer;
    emit turnNextPlayer(nextPlayer);
}

void BoardWidget::checkWinner()
{
    bool fullPieces = true;
    for (int i = 0; i < BOARD_WIDTH; i++)
    {
        for (int j = 0; j < BOARD_HEIGHT; j++)
        {
            if (board[i][j] == NO_PIECE)
            {
                fullPieces = false;
            }
            if (board[i][j] != NO_PIECE && isFivePieceFrom(i, j))
            {
                bool winner = (board[i][j] == WHITE_PIECE) ? WHITE_PLAYER : BLACK_PLAYER;
                endGame = true;
                emit gameOver(winner);
            }
        }
    }
    if (fullPieces)
    {
        endGame = true;
        emit gameOver(2);   //代表和棋
    }
}

bool BoardWidget::isFivePieceFrom(int x, int y)
{
    return isVFivePieceFrom(x, y) || isHFivePieceFrom(x, y) || isFSFivePieceFrom(x, y) || isBSFivePieceFrom(x, y);
}

bool BoardWidget::isVFivePieceFrom(int x, int y)
{
    int piece = board[x][y];
    for (int i = 1; i < 5; i++)
    {
        if (y + i >= BOARD_HEIGHT || board[x][y + i] != piece)
        {
            return false;
        }
    }
    winPoses.clear();
    for (int i = 0; i < 5; i++)
    {
        winPoses.append(QPoint(x, y + i));
    }
    return true;
}

bool BoardWidget::isHFivePieceFrom(int x, int y)
{
    int piece = board[x][y];
    for (int i = 1; i < 5; i++)
    {
        if (x + i >= BOARD_WIDTH || board[x + i][y] != piece)
        {
            return false;
        }
    }
    winPoses.clear();
    for (int i = 0; i < 5; i++)
    {
        winPoses.append(QPoint(x + i, y));
    }
    return true;
}

bool BoardWidget::isFSFivePieceFrom(int x, int y)
{
    int piece = board[x][y];
    for (int i = 1; i < 5; i++)
    {
        if (x + i >= BOARD_WIDTH || y - i < 0 || board[x + i][y - i] != piece)
        {
            return false;
        }
    }
    winPoses.clear();
    for (int i = 0; i < 5; i++)
    {
        winPoses.append(QPoint(x + i, y - i));
    }
    return true;
}

bool BoardWidget::isBSFivePieceFrom(int x, int y)
{
    int piece = board[x][y];
    for (int i = 1; i < 5; i++)
    {
        if (x + i >= BOARD_WIDTH || y + i >= BOARD_HEIGHT || board[x + i][y + i] != piece)
        {
            return false;
        }
    }
    winPoses.clear();
    for (int i = 0; i < 5; i++)
    {
        winPoses.append(QPoint(x + i, y + i));
    }
    return true;
}


void BoardWidget::newGame()
{
    for (int i = 0; i < BOARD_WIDTH; i++)
    {
        for (int j = 0; j < BOARD_HEIGHT; j++)
        {
            board[i][j] = NO_PIECE;
        }
    }
    winPoses.clear();
    dropedPieces.clear();
    nextPlayer = BLACK_PLAYER;
    endGame = false;
    update();
    emit turnNextPlayer(nextPlayer);
}

gamewidget.h :

#ifndef GAMEWIDGET_H
#define GAMEWIDGET_H

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include "boardwidget.h"
#include "gomokuai.h"

class GameWidget : public QWidget
{
    Q_OBJECT

public:
    GameWidget(QWidget *parent = 0);
    ~GameWidget();

private:
    //初始化游戏窗口界面
    void initWidget();
    //显示获胜者
    void showWinner(int winner);
    //切换playerLabel标签显示内容
    void switchPlayerLabel(bool player);
    //切换至双人对战模式
    void switchHumanGame();
    //切换到Ai对战模式
    void switchAiGame();
    //接受下棋信号,如果为ai模式且轮到ai时,搜索最佳位置下棋
    void nextDropPiece(bool player);
    //悔棋
    void undo();
    //新游戏;
    void newGame();

private:
    GomokuAi *ai;               //ai 对象指针
    bool isGameWithAi;          //是否为ai对战模式

    BoardWidget *boardWidget;   //棋盘控件
    QLabel *playerLabel;        //用于提示下一步轮哪一方
    QLabel *winLabel;           //提示获胜的标签
    QPushButton *newGameBtn;    //新游戏按钮
    QPushButton *humanGameBtn;  //双人游戏按钮
    QPushButton *aiGameBtn;     //ai对战按钮
    QPushButton *undoBtn;       //悔棋按钮
};

#endif // GAMEWIDGET_H

gamewidget.cpp:

#include "gamewidget.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QFileDialog>
#include <QLabel>
#include <QDebug>

GameWidget::GameWidget(QWidget *parent)
    : QWidget(parent)
{
    ai = new GomokuAi(this);
    isGameWithAi = false;
    initWidget();

    switchHumanGame();
}

GameWidget::~GameWidget()
{

}

void GameWidget::initWidget()
{

    setWindowTitle("五子棋");

    //创建水平布局作为总布局
    QHBoxLayout *mainLayout = new QHBoxLayout(this);

    //棋盘控件
    boardWidget = new BoardWidget(this);
    mainLayout->addWidget(boardWidget);

    //创建垂直布局作为界面右边标签和菜单的子布局
    QVBoxLayout *vLayout = new QVBoxLayout();
    playerLabel = new QLabel("轮到白方落子", this);
    playerLabel->setFont(QFont("微软雅黑", 25));
    vLayout->addWidget(playerLabel);
    vLayout->addStretch();

    winLabel = new QLabel(this);
    winLabel->setFont(QFont("微软雅黑", 20));
    vLayout->addWidget(winLabel);
    vLayout->addStretch();          //添加一个伸缩因子

    //创建栅格布局作为菜单按钮的布局
    QGridLayout *gLayout = new QGridLayout();
    newGameBtn = new QPushButton("新游戏");
    humanGameBtn = new QPushButton("双人游戏");
    aiGameBtn = new QPushButton("人机对战");
    undoBtn = new QPushButton("悔棋");
    gLayout->addWidget(newGameBtn, 0, 0);
    gLayout->addWidget(humanGameBtn, 0, 1);
    gLayout->addWidget(aiGameBtn, 0, 2);
    gLayout->addWidget(undoBtn, 0, 3);

    vLayout->addLayout(gLayout);
    mainLayout->addLayout(vLayout);

    connect(boardWidget, &BoardWidget::gameOver, this, &GameWidget::showWinner);
    connect(boardWidget, &BoardWidget::turnNextPlayer, this, &GameWidget::switchPlayerLabel, Qt::QueuedConnection);
    connect(boardWidget, &BoardWidget::turnNextPlayer, this, &GameWidget::nextDropPiece, Qt::QueuedConnection);
    connect(newGameBtn, &QPushButton::clicked, this, &GameWidget::newGame);
    connect(humanGameBtn, &QPushButton::clicked, this, &GameWidget::switchHumanGame);
    connect(aiGameBtn, &QPushButton::clicked, this, &GameWidget::switchAiGame);
    connect(undoBtn, &QPushButton::clicked, this, &GameWidget::undo);
}


void GameWidget::showWinner(int winner)
{
    if (winner != 2)
    {
        QString playerName = (winner == BoardWidget::WHITE_PLAYER) ? "白方" : "黑方";
        QMessageBox::information(this, "游戏结束", tr("恭喜%1获胜!!").arg(playerName), QMessageBox::Ok);
    }
    else
    {
        QMessageBox::information(this, "游戏结束", "和棋!", QMessageBox::Ok);
    }
}

void GameWidget::switchPlayerLabel(bool player)
{
    QString playerName = (player == BoardWidget::WHITE_PLAYER) ? "白方" : "黑方";
    QString labelText = tr("轮到%1落子").arg(playerName);
    playerLabel->setText(labelText);
}

void GameWidget::switchHumanGame()
{
    humanGameBtn->setEnabled(false);
    aiGameBtn->setEnabled(true);
    QSet<int> receivePlayers;
    receivePlayers << BoardWidget::WHITE_PLAYER << BoardWidget::BLACK_PLAYER;
    boardWidget->setReceivePlayers(receivePlayers);
    isGameWithAi = false;
    boardWidget->newGame();
}

void GameWidget::switchAiGame()
{
    aiGameBtn->setEnabled(false);
    humanGameBtn->setEnabled(true);
    QSet<int> receivePlayers;
    receivePlayers << BoardWidget::WHITE_PLAYER;
    boardWidget->setReceivePlayers(receivePlayers);
    isGameWithAi = true;
    boardWidget->newGame();
}

void GameWidget::nextDropPiece(bool player)
{
    if (isGameWithAi && player == GomokuAi::AI_PLAYER)
    {
        QPoint pos = ai->searchAGoodPos(boardWidget->getBoard());
        boardWidget->downPiece(pos.x(), pos.y());
    }
}

void GameWidget::undo()
{
    if (isGameWithAi)
    {
        boardWidget->undo(2);
    }
    else
    {
        boardWidget->undo(1);
    }
}

void GameWidget::newGame()
{
    winLabel->setText("");
    boardWidget->newGame();
}

gomokuai.h:

#ifndef GOMOKUAI_H
#define GOMOKUAI_H

#include <QObject>
#include "boardwidget.h"

class GomokuAi : public QObject
{
    Q_OBJECT
public:
    explicit GomokuAi(QObject *parent = nullptr);

private:
    //返回棋盘上所有空的位置
    QVector<QPoint> getAllDropPos();
    //返回该位置的相对于player的分数
    int getPieceScore(int x, int y, int player);
    //返回该位置的分数,越靠近中间分数越大
    int getPosValue(int x, int y);
    //返回该位置dire方向上的棋型
    int getChessType(int x, int y, int dire, int pieceColor);	//返回此处棋型
    //获取该位置该方向上pieceColor颜色的连续棋子数, pieceEnd为结束位置棋子
    int getLinePieceNum(int x, int y, int dire, int pieceColor, int &pieceEnd);
    bool isBeyond(int x, int y);

signals:

public slots:
    QPoint searchAGoodPos(Board nBoard);
public:
    static const int CHESS_VALUES[9];
    static const int MIN_VALUE = -2000000;
    static const int AI_PLAYER = BoardWidget::BLACK_PLAYER;

private:
    int board[BoardWidget::BOARD_WIDTH][BoardWidget::BOARD_HEIGHT];
    QPoint bestPos;
};

#endif // GOMOKUAI_H

gomokuai.cpp:

#include "gomokuai.h"
#include <QDebug>
#include <cmath>

const int GomokuAi::CHESS_VALUES[9] = {0, 50, 100, 200, 500, 650, 2500, 10000, 30000};
const int GomokuAi::MIN_VALUE;
const int GomokuAi::AI_PLAYER;

GomokuAi::GomokuAi(QObject *parent) : QObject(parent)
{
}

QVector<QPoint> GomokuAi::getAllDropPos()
{
    QVector<QPoint> allPos;
    for (int i = 0; i < BoardWidget::BOARD_WIDTH; i++)
    {
        for (int j = 0; j < BoardWidget::BOARD_HEIGHT; j++)
        {
            if (board[i][j] == BoardWidget::NO_PIECE)
            {
                allPos.push_back(QPoint(i, j));
            }
        }
    }
    return allPos;
}

int GomokuAi::getPieceScore(int x, int y, int player)
{
    int value = 0;
    int piece = (player == BoardWidget::WHITE_PLAYER) ? BoardWidget::WHITE_PIECE : BoardWidget::BLACK_PIECE;
    for (int i = 0; i < 8; i++)
    {
        int t = getChessType(x, y, i, piece);
        value += CHESS_VALUES[t];
    }
    value += getPosValue(x, y);
    return value;
}

int GomokuAi::getPosValue(int x, int y)
{
    int valuex =BoardWidget::BOARD_WIDTH - std::abs(x - BoardWidget::BOARD_WIDTH / 2);
    int valuey =BoardWidget::BOARD_HEIGHT - std::abs(y - BoardWidget::BOARD_HEIGHT / 2);
    return valuex + valuey;
}

int GomokuAi::getChessType(int x, int y, int dire, int piece)
{
    int chessType = 0;
    int end = BoardWidget::NO_PIECE;
    int num = getLinePieceNum(x, y, dire, piece, end);
    if (num == 5)
    {
        chessType = 8;
    }
    else if (num == 4 && end == BoardWidget::NO_PIECE)
    {
        chessType = 7;
    }
    else if (num == 4 && end != BoardWidget::NO_PIECE)
    {
        chessType = 6;
    }
    else if (num == 3 && end == BoardWidget::NO_PIECE)
    {
        chessType = 5;
    }
    else if (num == 3 && end != BoardWidget::NO_PIECE)
    {
        chessType = 4;
    }
    else if (num == 2 && end == BoardWidget::NO_PIECE)
    {
        chessType = 3;
    }
    else if (num == 2 && end != BoardWidget::NO_PIECE)
    {
        chessType = 2;
    }
    else if (num == 1 && end == BoardWidget::NO_PIECE)
    {
        chessType = 1;
    }
    else
    {
        chessType = 0;
    }
    return chessType;
}

int GomokuAi::getLinePieceNum(int x, int y, int dire, int pieceColo, int &pieceEnd)
{
    int offset[8][2] = {{1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}};
    int num = 0;
    x += offset[dire][0];
    y += offset[dire][1];
    if (isBeyond(x, y) || board[x][y] != pieceColo)
    {
        return 0;
    }
    int pieceStart = board[x][y];
    while (!isBeyond(x, y) && board[x][y] == pieceStart)
    {
        x += offset[dire][0];
        y += offset[dire][1];
        num++;
    }
    pieceEnd = board[x][y];	//终止处的棋子
    return num;
}

bool GomokuAi::isBeyond(int x, int y)
{
    return x < 0 || x >= BoardWidget::BOARD_WIDTH || y < 0 || y >= BoardWidget::BOARD_HEIGHT;
}

QPoint GomokuAi::searchAGoodPos(Board nBoard)
{
    memcpy(board, nBoard, sizeof(board));
    int bestScore = MIN_VALUE;
    for (QPoint pos : getAllDropPos())
    {
        int value = getPieceScore(pos.x(), pos.y(), AI_PLAYER);
        int oppoValue = getPieceScore(pos.x(), pos.y(), !AI_PLAYER);
        int totalValue = std::max(value, oppoValue * 4 / 5);
        if (totalValue > bestScore)
        {
            bestScore = totalValue;
            bestPos = pos;
        }
    }
    return bestPos;
}

欢迎学习交流~
源码下载:https://download.csdn.net/download/weixin_45737857/12060550

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!