《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

源码下载

相关推荐
minstbe3 分钟前
AI开发:使用支持向量机(SVM)进行文本情感分析训练 - Python
人工智能·python·支持向量机
月眠老师6 分钟前
AI在生活各处的利与弊
人工智能
四口鲸鱼爱吃盐22 分钟前
Pytorch | 从零构建MobileNet对CIFAR10进行分类
人工智能·pytorch·分类
苏言の狗23 分钟前
Pytorch中关于Tensor的操作
人工智能·pytorch·python·深度学习·机器学习
bastgia1 小时前
Tokenformer: 下一代Transformer架构
人工智能·机器学习·llm
菜狗woc1 小时前
opencv-python的简单练习
人工智能·python·opencv
15年网络推广青哥1 小时前
国际抖音TikTok矩阵运营的关键要素有哪些?
大数据·人工智能·矩阵
白乐天_n1 小时前
腾讯游戏安全移动赛题Tencent2016A
安全·游戏
这是我581 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
weixin_387545642 小时前
探索 AnythingLLM:借助开源 AI 打造私有化智能知识库
人工智能