基于Python的人机交互的五子棋博弈树搜索

article/2025/10/8 18:16:09

1. 算法原理

1.1 博弈树

博弈树针对的是二人零和博弈的问题,二人轮流行动,行动时令自己的优势最大。二人零和博弈有如下特点:

  • 确定性:二人的行动有多种选择,但最终的行动是确定的
  • 信息完备性:博弈双方知道当前局势(即空间状态)的全部信息
  • 零和性:一方的损失等于另一方的收益,二者得分相加恒为零

由以上特点,我们可以构造博弈树。因为信息完备性和确定性,可以用博弈树的每个节点表示一个确定的状态,在动作后得到的新状态作为子节点。对于每个状态都有同一个评价函数来评估双方的得分。因为零和性,一方通过决策使得自身的评价函数尽可能的大,另一方让队手的评价函数尽可能的小。因为二者是轮流行动的,在树的每一层让一方的评价函数取最大和最小交替进行。

由上述的特性,博弈树的搜索过程又被称为minimax搜索。博弈双方行动逐层交替,将评价函数值看做一方的分数,在那一方行动时要让分数尽可能的大,这样的节点被称为Max节点;在另一方行动时要让分数尽可能的小,这样的节点被称为Min节点。

要让一方的下一步采取最优的策略,需要进行树的搜索。在实际问题中,树往往非常大,因此只考虑一定的深度,而不是整个遍历。进行深入搜索时,轮流考虑Max节点和Min节点,每次都采取最优策略,最终得到本步的最优策略。

1.2 Alpha-beta剪枝

通过Alpha-beta剪枝可以对minimax搜索进行剪枝。在博弈树的每个节点保存两个值: α \alpha α表示在该节点能达到的分数的下界,初始化为 − ∞ -\infin β \beta β表示该节点能达到的分数的上界,初始化为 ∞ \infin

1.2.1 Max节点的剪枝

Max节点的 β \beta β值初始化时应该为父节点的 β \beta β值。因为Max节点的父节点是Min节点,如果Max节点的 β \beta β值大于父节点的 β \beta β值,Max节点最终得到的估值必然会大于父节点的 β \beta β值,从而表示的状态被不会被父节点选择。

之后,Max节点依次生成子节点。每生成完一个子节点就将子节点的 α \alpha α值传递回来。因为子节点为Min节点,会取到分数的最小值,因此必然会取到它的下界 α \alpha α,也就是说,Min节点最终的的 α \alpha α值就是它的估值。而Max会取子节点中估值最大的,因此,要通过子节点的 α \alpha α值来提高自身评分的下界,也就是说,如果子节点的 α \alpha α值大于自身的 α \alpha α值,则将自身的 α \alpha α值更新为更大的那一个。www.biyezuopin.vip

α > β \alpha>\beta α>β时,该节点的估值一定会大于父节点的估值上界,而父节点是Min节点,是必然不会选择当前节点的。因此所有的子节点可以停止拓展,从而实现了剪枝。

12.2 Min节点的剪枝

Min节点的 α \alpha α值初始化时应该为父节点的 α \alpha α值。因为Min节点的父节点是Max节点,如果Min节点的 α \alpha α值小于父节点的 α \alpha α值,Min节点最终得到的估值必然会小于父节点的 α \alpha α值,从而表示的状态不会被父节点选择。

之后,Min节点依次生成子节点。每生成完一个子节点就将子节点的 β \beta β值传递回来。因为子节点为Max节点,会取到分数的最大值,因此必然会取到它的上界 β \beta β,也就是说,Max节点最终的 β \beta β值就是它的估值。而Min节点会取子节点中估值最小的,因此要通过子节点的 β \beta β值来提高自身评分的上界,也就是说,如果子节点的 β \beta β值小于自身的 β \beta β值,则将自身的 β \beta β值更新为更小的那一个。

α > β \alpha>\beta α>β时,该节点的估值一定会小于父节点的估值下界,而父节点是Max节点,是必然不会选择当前节点的。因此所有的子节点可以停止拓展,从而实现了剪枝。


2. 流程图和伪代码

2.1 Minimax搜索的实现

本次实现的是人机交互的五子棋,其中五子棋的AI是通过Minimax搜索决定下棋的位置的。

棋盘为11*11大小,棋子使用列表chesses存储,每个元素为一个元组(x, y, color),表示棋子的位置坐标和颜色。

生成Max节点的过程如下:

生成Min节点的过程如下:

容易看出,二者具有相当的对称性。Min节点和Max节点的生成和剪枝可以用同一个函数通过递归实现。

input:type, state, depth, last_a, last_b
/* 输入:节点类型、 当前状态、深度(越大则越浅)、父节点的α和β值 */
output: act, a, b
/* 输出:当前节点取到极值的动作、当前节点的α和β值 */
def NodeSummon(type, state, depth, last_a, last_b):/* 生成叶子节点则直接打分 */if depth == 0 then return Null, getScore(state),getScore(state)/* 依据节点类型初始化α和β值 */a = -infinb = infinif type == Max then b = last_belse a = last_a/* 遍历每个可行的动作 */for eachAct that possiblenewState = changeState(state, eachAct)		/* 依据动作改变当前状态 */_, next_a, next_b = NodeSummon(type, chesses, depth-1, a, b)	/* 递归生成子节点 *//* 依据节点类型更新α或β值,保存取极值的状态 */if type == Max && a<next_a thenact = eachActa = next_aif type == Min && b>next_b thenact = eachActb = next_b/* 剪枝判断 */if a>b then return act, a, bendreturn act, a, b

需要注意的是,根节点没有父节点,故父节点的α和β值分别设置为负无穷和正无穷。叶子节点不需要向下拓展,而是直接进行打分。打分同时作为该叶子节点的 α \alpha α β \beta β值即可将叶子节点也视作中间节点,方便统一处理。

2.2 分数标准(评价函数的设计)

那么如何给五子棋的棋局打分呢?考虑针对每种颜色进行打分,某一方的分数为:自身颜色的得分减去对手颜色的得分。这样一来就实现了博弈的“零和”条件。五子棋通常是场上连续的相同颜色的子的优势更大,更容易连成五个子,而有时棋手也会有“飞棋”的策略,也就是说,将两部分连续的棋子中间断开一格,当下到这一格将两边连起来时,优势会大幅增加。因此考虑的范围必须必简单的五子棋的“五子”更大。因此这里我每次取六个格子进行评分依据。

对一个棋盘的某种颜色进行打分时,策略如下:依次遍历所有横向、竖向、斜向的连续的六个位置。判断这六个位置的布局,每种布局对应一个分数。以AI为黑色棋子为例,分数具体标准分为如下几个标准:

2.2.1 第一标准:下一步获胜

当AI能够下一步直接制胜时,不要考虑其他任何局势,直接取胜即可。这样一来,取胜的分数就要设置得非常高。同时,要考虑到多层迭代下去,有可能使得连续的子不止五个,应该也给予相当高的分数。

棋子状态(下划线表示为空,不列出对称状况)●●●●●●○●●●●●_●●●●●
给分100001000010000

2.2.2 第二标准:防止敌方下一步获胜

当敌方下一步要获胜且自己不能一步制胜时,需要优先拦截对方的棋,而不是自己造棋势。要注意直接相连的棋和飞棋(隔空的棋)。

棋子状态●○○○○●○○●○○_○○●○○○○○○○●_○○○●○__○○○●○○○○○●○○○○●○○
给分80008000800080008000800080008000

总的来说,就是对方再下一个子,就能形成五连或者六连,需要将对方封住。

2.2.3 第三标准:下一步造出必胜棋

如果自己和地方都下一步不能制胜,那么考虑下一步造出必胜棋,即下了之后没有获胜,但可以预期之后就能获胜的棋。也就是两端为空四连。在不同的方向进行联动可以造出其他必胜棋的棋型,这里不进行考虑,只考虑单行/列/斜角的一个方向。

棋子状态_●●●●_
给分6000

2.2.4 第四标准:破坏对方造必胜棋的条件

如果自己造不出必胜棋,且对方已经出现了活三或者2+1的飞棋形式,两端又为空,则需要防止对方造出活四的必胜棋。

棋子状态_●○○○__○○●○__○○_○●●○○_○_
给分4000400020002000

2.2.5 第五标准:连棋和堵棋

当自己和对手都不能造出必胜棋和一棋制胜,则尽量连自己更多的子、堵对方的连起来的子。标准较杂,不一一列举。

2.2.6 第六标准:其他

若不符合上述所有标准,则直接打分为0。


3. 代码展示

为了实现用户图形界面,我使用pygame库来展示。

首先定义一些基本的游戏参数:trace为列表,按时间顺序依次记录落棋的位置。chesses为所有的棋子,每个元素的格式为(第几行,第几列,颜色),其中颜色为0(纯黑)或255(纯白),初始化为-1,即没有棋。cross_num表示棋盘交叉点的个数,即棋盘大小。depth为minimax树的大小。

# 游戏参数
trace = []      # 记录下棋的位置
chesses = {}    # 记录所有的落子
cross_num = 11     # 交叉点的个数
depth = 2#int(input())
for x in range(cross_num):for y in range(cross_num):chesses[(x,y)] = -1

4. 实验结果及分析

依据实验题目要求,棋盘落子情况初始化为下:

下面尝试玩家执黑棋先行。一回合之后结果如下:

我尝试做了一个活三(三个连续的黑子,两端为空),AI下了右下的白子。这看上去的确是合理的。AI落子的位置一方面堵住了玩家的活三,同时AI下的位置上两格有一个白子,便于它之后连接成活三。

第二回合结果如下:

我连成一个一端有空的四个连起来的黑子,如此一来,如果AI不拦截的话我下一步就能直接胜利。可以看到,AI的确拦截了。

第三回合:

AI优先做了一个活三。

第四回合:

第五回合:

可以看到,在第五回合我落子后,如果在中点的左上角再下一子,连成两个活三,就必胜了,因此AI必须提前拦住我。它选择了我落子的下方进行落子,这样一来即破坏了我的两个连续的活三,又能制造一个自己的活三。

这五回合AI的得分分别为:

第一回合我有一个活三,因此拉低了AI的得分。而AI通过堵我的活三得到了一些分。第二回合我做出了连续的四个子,AI要马上拦截连续的四个子防止我获胜,于是按照设定,拦截可以拿到很高的分。在第二回合通过拦截,AI的分数急剧提高了。之后的几回合没有出现“马上要获胜”的情况,因此分数没有急剧上升。而被堵住的连续的四个黑子一直都在场上,会重复计算分数,因此分数会一直在较高的水平。

下面尝试让AI先手,并让AI取得胜利。

第一步AI下棋:

第二回合:

我造出了三个活二,因此AI选择进行拦截。

第三回合:

我造了一个2+1的飞棋,AI在拦截飞棋的同时又去拦截上方的活二。

第四回合:

我造了2+2的飞棋,AI必须进行拦截,否则我将胜利。AI的确拦截了。

第五回合:

AI有个活三,我故意不去拦截让AI造出了活四。

第六回合:

我造了个活三,AI优先取得胜利而不是来拦截我的活三。

这五步AI的得分为:

我造了2+2的飞棋,AI必须进行拦截,否则我将胜利。AI的确拦截了。

第五回合:

AI有个活三,我故意不去拦截让AI造出了活四。

第六回合:

我造了个活三,AI优先取得胜利而不是来拦截我的活三。

第二步我一次性造了三个活二,而在评价函数中活二可以出现在多个六个相邻位置的排列中,因此AI的分数骤降。第三个回合我造了2+1的飞棋,如果AI不拦截则会输,所以拦截的分数很高。AI拦截了,分数也提高了很多。之后我连成了四个子,AI不拦截则会输。拦截后AI又提高了很多分。第五回合AI造了活四,得了很高的分,最后一步取得胜利,直接取得胜利的得分比拦截活三高得多,因此AI选择直接取胜而不是拦截我的活三。


http://chatgpt.dhexx.cn/article/1ftiybWB.shtml

相关文章

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

基于博弈树的5x5一子棋人机对战 919106840637实验2 这是智能计算三个课程实验的第二个实验&#xff0c;即博弈树搜索 。我之前对博弈树的了解不多&#xff0c;所以实现起来比较的简略&#xff0c;仅仅是基本达到了要求 实验语言 C 实验内容 实践博弈树搜索——“5x5格子的一…

人工智能作业——搜索树博弈树一阶逻辑表达式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;而且还能…