C++实现基于博弈树的5x5一子棋人机对战

article/2025/10/8 18:19:31

基于博弈树的5x5一子棋人机对战

919106840637实验2
这是智能计算三个课程实验的第二个实验,即博弈树搜索 。我之前对博弈树的了解不多,所以实现起来比较的简略,仅仅是基本达到了要求

实验语言

C++

实验内容

实践博弈树搜索——“5x5格子的一字棋问题”,即五子棋,参照课件PPT上的例子来实现。 (课件PPT上是3x3)。 要求是Max方和Min方都用博弈树来决策,或者一方使用博弈树决策,一方随机或手工走棋,并使用alpha和beta减枝。

实验内容部分我只较好完成了博弈树实现下棋部分,由于博弈树深度较浅,广度也不多,故不剪枝也能拥有较好的性能。剪枝暂时没很好完成,剪枝之后AI貌似变蠢了 出了点问题。

实验思想及部分代码

开始照例贴头文件

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstring>
#include <windows.h>
#include <vector>
#include <algorithm>

完成这个实验我分成了两步

  1. 创建一个棋盘
  2. 开始下棋

其中第一步非常简单,棋盘直接用一个二维数组即可表示:

int realBoard[5][5];

其中规定,棋盘格的值为0代表空,棋盘格值为1代表AI下在这,棋盘格值为-1代表玩家下在这。

第二步就涉及到下棋的算法了。先简单介绍下博弈树的思想。博弈树就是通过对现有状态进行分析,得到若干个可能的子状态,然后再从若干个子状态出发去分析子状态的子状态…不断迭代就可以形成一棵树。博弈树的概念呢就是这棵树的不同节点会有不同的权值,我们需要根据一定算法去选择最优节点。
在对弈游戏中,轮到自己下时,棋手会将当前棋盘状态当成博弈树的根节点,然后将自己落子不同位置时的棋盘状态当成根节点的子节点,再在此基础上将对手落子不同位置时的棋盘状态当成下一层子节点…可想而知,博弈树的深度越深,棋手考虑的越多越全面。不过过深的博弈树势必会增加计算的时空开销。
除了如何形成一棵博弈树,我们还需要掌握的是如何利用博弈树来选取最佳的落子地点。这里以三层的博弈树为例,即除根节点外,只考虑棋手下一步以及对手下一步的情况。

  • 我们首先要为博弈树中的每个状态附上一个权值,这个权值在不同状况下有不同的含义。在对弈游戏中,可以将权值视为对棋手的有利影响因子,即权值越大,棋手越有可能获胜。在这里很容易想到,棋手希望目标状态的权值越大越好,而对手则希望将权值降到最低
  • 先不去考虑权值h是如何得到的。我们来看看如何得到棋手所期望的最佳状态呢?棋盘当前状态在根节点也就是第一层,棋手期望下一步能够胜率最大,即选取权值最大的第二层状态。而第二层状态的权值可以被第三层的状态权值所影响,即对手下一步不同的下法会影响到棋手上一步的胜率,显而易见如果对手是个世外高人,招招致命,第二层状态的权值就应该等于对应子状态的最小值(对手下棋的目的是让你胜率尽可能小)。一个三层的博弈树就结束了,如果是更深的博弈树,则第三层的权值还要受到棋手进一步下棋即第四层状态的影响,循环往复,这过于复杂所以姑且不论。这个方法叫做极小极大分析法,父状态取该层最大权值的状态层叫MAX层,父状态取该层最小权值的状态层叫MIN层。

在这里插入图片描述

  • 举个例子,如上图。棋手在根节点代表的状态时有三种下法,分别对应三个第二层子状态。棋手想要知道哪种下法更容易赢,就要找到权值最大的子状态。现在对于三个子状态的权值我们还不知道。要求第二层状态的权值,我们就要考虑如果棋手下了这步棋,对手会去怎么下,即分解出第三层的状态。由于第三层是最终层,我们无法通过第四层来获取第三层的权值,所以我们需要利用估值算法来对第三层状态的权值进行估计。通过估值算法求出每个第三层状态权值后,我们就可以选择其中最低的权值作为第二层节点的对应状态的权值(对手肯定不想棋手好过)。然后棋手想要最大胜率,则应该选择权值最大的第二层状态所代表的下法。
  • 自此,棋手就通过简单的三层博弈树算法算出了他下一步该走哪最好。可以说,棋圣的脑子都是计算机,里面装了棵庞大的博弈树用来和对手勾心斗角 。
  • 至于上文提到的估值算法,有很多种,我就不赘述了。

然后就贴一贴代码吧。
实现的估值函数

int e(int board[5][5]){	//估值函数int eplus = 0;int eminus = 0;int index_p = 0;int index_m = 0;for(int i=0;i<5;i++){//行index_m = 0;index_p = 0;for(int j=0;j<5;j++){if(board[i][j] == 1) index_p++;else if(board[i][j] == -1) index_m++;}if(index_p == 5){eplus = 9999;break;}else if(index_m == 5){eminus = 9999;break;}else if(index_p != 0 && index_m == 0) eplus+=index_p*index_p;else if(index_m != 0 && index_p == 0) eminus+=index_m*index_m;//列index_m = 0;index_p = 0;for(int j=0;j<5;j++){if(board[j][i] == 1) index_p++;else if(board[j][i] == -1) index_m++;}if(index_p == 5){eplus = 9999;break;}else if(index_m == 5){eminus = 9999;break;}else if(index_p != 0 && index_m == 0) eplus+=index_p*index_p;else if(index_m != 0 && index_p == 0) eminus+=index_m*index_m;}//对角线index_m = 0;index_p = 0;for(int i=0;i<5;i++){if(board[i][i] == 1) index_p++;else if(board[i][i] == -1) index_m++;}if(index_p == 5){eplus = 9999;}else if(index_m == 5){eminus = 9999;}else if(index_p != 0 && index_m == 0) eplus+=index_p*index_p;else if(index_m != 0 && index_p == 0) eminus+=index_m*index_m;//负对角线index_m = 0;index_p = 0;for(int i=0;i<5;i++){if(board[i][4-i] == 1) index_p++;else if(board[i][4-i] == -1) index_m++;}if(index_p == 5){eplus = 9999;}else if(index_m == 5){eminus = 9999;}else if(index_p != 0 && index_m == 0) eplus+=index_p*index_p;else if(index_m != 0 && index_p == 0) eminus+=index_m*index_m;return eplus-eminus;
}

AI下棋逻辑

//AI下棋statue* nowBoard = new statue;for(int i=0;i<5;i++){for(int j=0;j<5;j++){nowBoard->hypoBoard[i][j] = realBoard[i][j];}}//生成所有AI可能的下法(未剪枝)for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(nowBoard->hypoBoard[i][j] == 0){statue* p = new statue;for(int m=0;m<5;m++){for(int n=0;n<5;n++){p->hypoBoard[m][n] = nowBoard->hypoBoard[m][n];}}p->hypoBoard[i][j] = 1;p->max_min = true;p->father = nowBoard;nowBoard->sons.push_back(p);}}}//进一步预测玩家的下法(未剪枝)for(int a=0;a<(int)nowBoard->sons.size();a++){statue* t = nowBoard->sons[a];for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(t->hypoBoard[i][j] == 0){statue* p = new statue;for(int m=0;m<5;m++){for(int n=0;n<5;n++){p->hypoBoard[m][n] = t->hypoBoard[m][n];}}p->hypoBoard[i][j] = -1;p->max_min = true;p->father = t;p->consum = e(p->hypoBoard);t->sons.push_back(p);}}}}//倒推MAX层的代价值for(int a=0;a<(int)nowBoard->sons.size();a++){statue* t = nowBoard->sons[a];int min = 9999;for(int i=0;i<(int)t->sons.size();i++){if(min > t->sons[i]->consum) min = t->sons[i]->consum;}t->consum = min;}//选择模式int max = -9999;int index = -1;for(int a=0;a<(int)nowBoard->sons.size();a++){if(max < nowBoard->sons[a]->consum){max = nowBoard->sons[a]->consum;index = a;}}//下棋for(int i=0;i<5;i++){for(int j=0;j<5;j++){realBoard[i][j] = nowBoard->sons[index]->hypoBoard[i][j];}}//清空指针for(int a=0;a<(int)nowBoard->sons.size();a++){statue* t = nowBoard->sons[a];for(int i=0;i<(int)t->sons.size();i++){delete t->sons[i];}t->sons.clear();delete t;}nowBoard->sons.clear();

总结

我觉得博弈树还是挺简单的算法吧,然后也不知不觉写了这么长篇大论的。网上的教程也挺多,不过当初看得有点迷糊。理解了原理自己就能写了。

我自己也半桶水,剪枝都没搞太明白╮(╯▽╰)╭。


http://chatgpt.dhexx.cn/article/Ojj3WasQ.shtml

相关文章

人工智能作业——搜索树博弈树一阶逻辑表达式CNF范式

1. 人工智能定义 1. 简述什么是人工智能 人工智能可分为两个维度:一个维度是从思维推理过程到行为结果(过程与结果);另一个维度是与人类表现的逼真度到数学与工程结合后的精确性(主观与客观)。 像人—样行动&#xff1a;图灵测试的途径&#xff1b;像人—样思考&#xff1a;认…

AlphaBeta剪枝算法求解博弈树最优选择 头歌实验平台

AlphaBeta剪枝算法求解博弈树最优选择 头歌实验平台 前言一、AlphaBeta剪枝是什么&#xff1f;1.由来, 最大最小决策树2.发展3. AlphaBeta剪枝 二、实验算法伪代码三、实验算法代码四、实验结果在这里插入图片描述 五、感谢 前言 产生本文的缘由 人工智能原理课程 可选实验 “…

并行博弈树搜索算法-第3篇 优秀的园丁:Alpha-Beta算法

3.1 Alpha-Beta算法 虽然博弈树的状态是有限的,但是状态个数却非常多.假设博弈树的深度为d,每个结点有b个分支,即分支因子&#xff08;branchingfactor&#xff09;为b,那么使用Min-Max方法搜索这个博弈树需要搜索个结点. 然而幸运的是,Min-Max方法的一些搜索是没有必要的,…

利用α-β搜索的博弈树算法编写一字棋游戏 python

游戏规则 “一字棋"游戏&#xff08;又叫"三子棋"或"井字棋”&#xff09;&#xff0c;是一款十分经典的益智小游戏。“井字棋"的棋盘很简单&#xff0c;是一个 33 的格子&#xff0c;很像中国文字中的"井"字&#xff0c;所以得名"井字…

博弈树 极小极大分析法

一、博弈概述 博弈特点&#xff1a; &#xff08;1&#xff09;博弈的初始格局是初始节点 &#xff08;2&#xff09;在博弈树中&#xff0c;“或”和“与”是交替出现的。自己一方的扩展节点是“或”关系&#xff0c;对方扩展的节点是“与”关系。双方轮流扩展节点。 &…

第6-2课:决策树、博弈树和行为树

在以各种“XX学习”为代表的人工智能技术普及之前,游戏里常见的角色 AI 都是各种预设的行为逻辑,比如博弈树和行为树,当然也会用到各种专家知识库。当这些预设的行为逻辑足够复杂的时候,往往会让游戏玩家觉得游戏里的人物很“智能”。从本质上来说,这些都还不算是真正的 A…

并行博弈树搜索算法-第4篇 更上一层楼:Alpha-Beta算法的改进

在Alpha-Beta算法被广泛运用后,对该算法的很多改进算法也相继被提出.这些改进算法主要在以下几个方面对Alpha-Beta算法进行改进[7]: 1. 择序&#xff08;ordering&#xff09;.在搜索博弈树时,内部结点有多个可能的移动.择序指的是搜索这些分支的顺序.择序影响着搜索叶结点的个…

博弈树的启发式搜索

什么是博弈树 在博弈过程中, 任何一方都希望自己取得胜利。因此,当某一方当前有多个行动方案可供选择时, 他总是挑选对自己最为有利而对对方最为不利的那个行动方案。 此时,如果我们站在A方的立场上,则可供A方选择的若干行动方案之间是“或”关系, 因为主动权操在A方手里,他或…

博弈树 α-β剪枝

由于搜索的复杂度有点高&#xff0c;所以在树上减少计算量肯定是剪枝了&#xff0c;这里我们把剪枝的办法称作的&#xff1a;α-β剪枝 我们在前面的文章中谈到&#xff0c;当第一次运作的是A&#xff0c;则所有的奇数深度的节点都是A做的选择&#xff0c;所有偶数深度的节点都…

博弈树优化

前言:   对弈类游戏的智能算法, 网上资料颇多, 大同小异. 然而书上得来终觉浅, 绝知此事要躬行. 结合了自己的工程实践, 简单汇总整理下. 一方面是对当年的经典<<PC游戏编程(人机博弈)>>表达敬意, 另一方面, 也想对自己当年的游戏编程人生做下回顾.   承接上两…

博弈树中关于α-β剪枝树要点

目录 一&#xff0c;α-β剪枝树搜索方法&#xff1a;深度优先&#xff08;DFS&#xff09;&#xff0c;一般从博弈树最左边开始一直搜索到最右边。 人工智能导论复习&#xff1a;| 一&#xff0c;α-β剪枝树搜索方法&#xff1a;深度优先&#xff08;DFS&#xff09;&#…

(只此一篇便绝b能懂的)五子棋AI算法原理,博弈树、极大极小搜索、αβ剪枝

我在最近撰写五子棋AI程序设计报告时&#xff0c;翻阅了很多的资料博客&#xff0c;但却发现大佬们的博客&#xff0c;没有一篇是能让我只看它就能理解全部的AI算法。在看了众多博客后&#xff0c;我终于对博弈树、极大极小搜索、αβ剪枝恍然大悟&#xff0c;其实这些看似高大…

五子棋智能算法-博弈树算法思想详解(一)

学习这个算法之前必会链表 关于链表看这两篇博文 https://blog.csdn.net/viafcccy/article/details/84502334 https://blog.csdn.net/viafcccy/article/details/85041942 在五子棋下棋中 我们最容易想到的算法就是对于棋局的推演 从而找到一种最佳的情况去使棋局向这个方向发…

基于博弈树的五子棋 AI 算法及其 C++ 实现

基于博弈树的五子棋 AI 算法及其 C 实现 摘要一 五子棋的游戏规则二 五子棋对弈的算法描述2.1 博弈树搜索算法2.2 α ─ β 剪枝2.3 估价函数 三 五子棋对弈的算法实现3.1 Node类3.1.1 成员变量3.1.2 成员函数 3.2 GameTree类3.2.1 成员变量3.2.2 成员函数 四 五子棋对…

博弈与博弈树

博弈与博弈树 博弈 博弈双方根据事先制定的规则&#xff0c;轮流交替在对应的棋局上做出自己的选择&#xff0c;然后根据规则判定那一方获胜。 博弈树&#xff08;一种特殊的与或树&#xff09; 目标&#xff1a;将当前棋局作为根节点&#xff0c;选出最有利于自己获胜的一步…

博弈树搜索算法

即使满腹经纶&#xff0c;但没有好的口才来授课&#xff0c;也会让学生听得昏昏欲睡、不知所云呢&#xff01;即使满腔热血&#xff0c;没有好的口才来凝聚共识&#xff0c;也会让这份理想温暖黯淡无光。但是&#xff0c;好的说话之道&#xff0c;也要有一颗赤诚的心、诚恳的情…

博弈树-BIT

博弈树-BIT 下棋属于一种博弈游戏&#xff0c;博弈过程可以用树&#xff08;博弈树&#xff09;来表示。假设游戏由两个人&#xff08; A 和 B &#xff09;玩&#xff0c;开始由某个人从根结点开始走&#xff0c;两个人轮流走棋&#xff0c;每次只能走一步&#xff0c; 下一步…

第四章 博弈树game tree

这里写目录标题 perfect-information game从博弈树得到收益表subgamebackward induction 反向推导一个值得思考的例子&#xff1a; 另一个例子umperfect information extensive混合策略和行为策略&#xff08;mexed and behavioral strategies)不完美信息博弈的求解 博弈树用于…

人工智能—— 博弈树的启发式搜索

一、概述 博弈的概念 博弈是一类具有智能行为的竞争活动&#xff0c;如下棋、战争等。 博弈的类型 双人完备信息博弈&#xff1a;两位选手&#xff08;例如MAX和MIN &#xff09;对垒&#xff0c;轮流走步&#xff0c;每一方不仅知道对方已经走过的棋步&#xff0c;而且还能…

博弈树与α-β剪枝

一、评价函数&#xff08;Evaluation function&#xff09; 绝大部分的游戏&#xff0c;决策空间都相当庞大。 即使是最简单的三子棋&#xff08;又叫做“井”字棋&#xff0c;一字棋&#xff09;。它的第一步有9种决策&#xff0c;然后对面有9*872种决策&#xff0c;....&…