《QT实用小工具·六十九》基于QT开发的五子棋AI游戏

1、概述
源码放在文章末尾

该项目实现了五子棋对战AI,可以享受和AI下棋的快乐,项目实现思路如下:

博弈树

●Alpha-Beta剪枝(性能提高较大)

●启发式搜索(性能提高较大)

●落子区域限制(性能提高较大)

●Zobrist哈希(性能小幅提升)

●Qt多线程计算避免界面卡死

●小概率走法剔除

仅进行Alpha-Beta剪枝+落子区域限制,思考两层,计算量在3k-9k,2s内计算完毕;思考四层,计算量在9k-20w,2s~20min内计算完毕.

+启发式搜索,思考两层,思考两层,计算量在900-2k,1s内计算完毕;思考四层,计算量在3k-3w,2s~20s内计算完毕.

+小概率走法剔除,思考两层,思考两层,计算量在24-60,1s内计算完毕;思考5层,计算量在2k-3k,1s内计算完毕;思考7层,计算量在8k-3w,2min~10min内计算完毕

项目界面图如下所示:

项目部分代码如下所示:

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPainter>
#include <QPen>
#include <QDebug>
#include <QMouseEvent>
#include <QString>
#include <vector>
#include <QMessageBox>
#include <random>
#include <ctime>
#include <map>
#include <cmath>
#include <algorithm>
#include <QThread>
#include <QTime>
#include <unordered_map>
#define QOUT qDebug()

enum patternID{
  LongLink=0,
  Active4,
  Sleep4,
  Active3,
  Sleep3,
  Active2,
  Sleep2,
  Dead4,
  Dead3,
  Dead2
};

struct step{
  int x;
  int y;
  bool nowWhite;
  int score;
  step(int xx=0,int yy=0,bool nw=true){
    x=xx;
    y=yy;
    nowWhite=nw;
  }
};


struct pattern{
  std::vector<QString> whitePattern;
  std::vector<QString> blackPattern;
  int id;
  int whiteScore;
  int blackScore;
  void clear(){
    whitePattern.clear();
    blackPattern.clear();
  }
};

namespace Ui {
  class MainWindow;
}

class MainWindow;
class AI:public QObject{
  Q_OBJECT
public:
  AI();
  AI(MainWindow *p):parentWindow(p){}
  int count;
private:
  MainWindow* parentWindow;

public slots:
  void getAINextStep();
 public:

  int getChessScore(int chess[15][15],int leftEdge=0,int rightEdge=14,int upEdge=0,int downEdge=14);
  int getLineScore(QString,int whitePatternNum[10],int blackPatternNum[15]);
  std::vector<step> getPossibleSteps(int chess[15][15],bool white,int leftEdge=0,int rightEdge=14,int upEdge=0,int downEdge=14);
  int alpha_beta(int chess[15][15], int depth, int alpha, int beta);
  bool calculateScore(std::vector<step>& possibleSteps,int chess[15][15]);
  void deleteUselessStep(std::vector<step>& possibleSteps,int chess[15][15]);
  bool reserveKillStep(std::vector<step>& possibleSteps,int chess[15][15]);
  signals:
  void stepReady();
};


class MainWindow : public QMainWindow
{
  Q_OBJECT
friend class AI;
public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();
  void paintEvent(QPaintEvent *e);
  void mousePressEvent(QMouseEvent *e);
  void keyPressEvent(QKeyEvent *e);
public slots:
  void handleAIStep();
signals:
  void AIShouldMove();
private:
  QThread AIThread;
  bool gameOver;
  int searchDepth;//搜索深度,应当是偶数
  int killStepSearchDepth;
  int stepAlreadyMade;//已经走的步数
  Ui::MainWindow *ui;
  const int gap=20;
  constexpr static int boxNum=14;
  const int boxWidth=gap*boxNum;
  const int startX=30;
  const int startY=30;
  bool nowWhite;//记录当前是否是白子 白色=1 黑色=2
  int gomoku[boxNum+1][boxNum+1];
  int gomokuForPaint[boxNum+1][boxNum+1];
  bool judge(int x,int y,bool nowWhite);
  bool judge(int chess[15][15],int x, int y, bool nowWhite);
  int steps;//用于设定搜索范围的步数
  int AINextX;
  int AINextY;
  bool AIIsThinking;
  std::vector<pattern> patterns;//储存算分的模式
  std::vector<pattern> lightPatterns;//排序走法用的模式
  int zobristHash;

  std::unordered_map<int,int> scoreCache;
  bool debug;

  int basicScore[15][15]={
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
    { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0 },
    { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 4, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 4, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0 },
    { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0 },
    { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0 },
    { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
  int zobristWhite[15][15];
  int zobristBlack[15][15];
  int XStack[250];//从1开始算
  int YStack[250];//从1开始算
  void initPattern();//初始化算分模式
public slots:
  void restartGame();
  void regret();

};

#endif // MAINWINDOW_H

源码下载

相关推荐
m0_609000429 分钟前
向日葵好用吗?4款稳定的远程控制软件推荐。
运维·服务器·网络·人工智能·远程工作
开MINI的工科男1 小时前
深蓝学院-- 量产自动驾驶中的规划控制算法 小鹏
人工智能·机器学习·自动驾驶
AI大模型知识分享2 小时前
Prompt最佳实践|如何用参考文本让ChatGPT答案更精准?
人工智能·深度学习·机器学习·chatgpt·prompt·gpt-3
张人玉4 小时前
人工智能——猴子摘香蕉问题
人工智能
草莓屁屁我不吃4 小时前
Siri因ChatGPT-4o升级:我们的个人信息还安全吗?
人工智能·安全·chatgpt·chatgpt-4o
小言从不摸鱼4 小时前
【AI大模型】ChatGPT模型原理介绍(下)
人工智能·python·深度学习·机器学习·自然语言处理·chatgpt
AI科研视界5 小时前
ChatGPT+2:修订初始AI安全性和超级智能假设
人工智能·chatgpt
霍格沃兹测试开发学社测试人社区5 小时前
人工智能 | 基于ChatGPT开发人工智能服务平台
软件测试·人工智能·测试开发·chatgpt
小R资源5 小时前
3款免费的GPT类工具
人工智能·gpt·chatgpt·ai作画·ai模型·国内免费
锦亦之22337 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt