《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

源码下载

相关推荐
深度学习实战训练营30 分钟前
基于CNN-RNN的影像报告生成
人工智能·深度学习
昨日之日20062 小时前
Moonshine - 新型开源ASR(语音识别)模型,体积小,速度快,比OpenAI Whisper快五倍 本地一键整合包下载
人工智能·whisper·语音识别
浮生如梦_2 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
深度学习lover2 小时前
<项目代码>YOLOv8 苹果腐烂识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果腐烂识别
热爱跑步的恒川3 小时前
【论文复现】基于图卷积网络的轻量化推荐模型
网络·人工智能·开源·aigc·ai编程
阡之尘埃5 小时前
Python数据分析案例61——信贷风控评分卡模型(A卡)(scorecardpy 全面解析)
人工智能·python·机器学习·数据分析·智能风控·信贷风控
PandaQue6 小时前
《怪物猎人:荒野》游戏可以键鼠直连吗
游戏
孙同学要努力7 小时前
全连接神经网络案例——手写数字识别
人工智能·深度学习·神经网络
Eric.Lee20217 小时前
yolo v5 开源项目
人工智能·yolo·目标检测·计算机视觉
徒步僧8 小时前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc