《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

源码下载

相关推荐
美酒没故事°13 小时前
Open WebUI安装指南。搭建自己的自托管 AI 平台
人工智能·windows·ai
云烟成雨TD13 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
AI攻城狮13 小时前
用 Obsidian CLI + LLM 构建本地 RAG:让你的笔记真正「活」起来
人工智能·云原生·aigc
鸿乃江边鸟13 小时前
Nanobot 从onboard启动命令来看个人助理Agent的实现
人工智能·ai
lpfasd12313 小时前
基于Cloudflare生态的应用部署与开发全解
人工智能·agent·cloudflare
俞凡13 小时前
DevOps 2.0:智能体如何接管故障修复和基础设施维护
人工智能
comedate13 小时前
[OpenClaw] GLM 5 关于电影 - 人工智能 - 的思考
人工智能·电影评价
财迅通Ai13 小时前
6000万吨产能承压 卫星化学迎来战略窗口期
大数据·人工智能·物联网·卫星化学
liliangcsdn13 小时前
Agent Memory智能体记忆系统的示例分析
数据库·人工智能·全文检索
GISer_Jing13 小时前
Page-agent MCP结构
前端·人工智能