α-β剪枝实现的一字棋实验报告

  • 格式:doc
  • 大小:305.50 KB
  • 文档页数:10

下载文档原格式

  / 10
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

人工智能大作业——极大极小算法和α -β剪枝实现一字棋

学院:

班级:

姓名:

学号:

辅导老师:

日期:

目录

一、实验目的 (3)

二、实验环境 (3)

三、实验原理 (3)

3.1 游戏规则 (3)

3.2 极小极大分析法 (3)

3.3 α -β剪枝算法 (4)

3.4 输赢判断算法设计 (5)

四、数据结构 (5)

4.1 程序流程 (5)

4.2 主要成员函数 (5)

4.2.1 估值函数 (5)

4.2.2 Alpha-Beta 剪枝算法 (6)

4.2.3 判断胜负 (6)

4.2.4 鼠标左键响应 (6)

4.2.5 Draw 系列函数 (6)

4.2.6 COMPUTER or PLAYER 先走 (7)

五、实验内容 (7)

5.1 基本功能简介 (7)

5.2 流程图 (8)

5.2.1 估价函数 (8)

5.2.2 Alpha-Beta 剪枝 (9)

六、实验小结 (10)

七、实验源代码 (10)

一、实验目的

(1) 学习极大极小搜索及α-β剪枝。

(2) 利用学到的算法实现一字棋。

二、实验环境

(1) 硬件环境:网络环境中的微型计算机。

(2) 软件环境:Windows 操作系统,Microsoft Visual C++语言。

三、实验原理

3.1 游戏规则

"一字棋"游戏(又叫"三子棋"或"井字棋"),是一款十分经典的益智小游戏。"井字棋" 的棋盘很简单,是一个3×3 的格子,很像中国文字中的"井"字,所以得名"井字棋"。"井字棋"游戏的规则与"五子棋"十分类似,"五子棋"的规则是一方首先五子连成一线就胜利;"井字棋"是一方首先三子连成一线就胜利。

井字棋(英文名Tic-Tac-Toe)

井字棋的出现年代估计已不可考,西方人认为这是由古罗马人发明的;但我们中国人认为,既然咱们都发明了围棋、五子棋,那发明个把井字棋自然是不在话下。这些纯粹是口舌之争了,暂且不提。

3.2 极小极大分析法

设有九个空格,由MAX,MIN 二人对弈,轮到谁走棋谁就往空格上放一只自己的棋子,谁先使自己的棋子构成"三子成一线"(同一行或列或对角线全是某人的棋子),谁就取得了胜利。

用圆圈表示MAX,用叉号代表MIN。

比如左图中就是MAX 取胜的棋局。

估价函数定义如下:

设棋局为P,估价函数为e(P)。

(1) 若P 对任何一方来说都不是获胜的位置,则e(P)=e(那些仍为MAX 空着的完全的行、列或对角线的总数)-e(那些仍为MIN 空着的完全的行、列或对角线的总数)

(2) 若P 是MAX 必胜的棋局,则e(P)=+∞(实际上赋了60)。

(3) 若P 是B 必胜的棋局,则e(P)=-∞(实际上赋了-20)。

比如P 如下图示,则e(P)=5-4=1

需要说明的是,+∞赋60,-∞赋-20的原因是机

器若赢了,则不论玩家下一步是否会赢,都会走这

步必赢棋。

3.3 α -β剪枝算法

上述的极小极大分析法,实际是先生成一棵博弈树,然后再计算其倒推值,至使极小极大分析法效率较低。于是在极小极大分析法的基础上提出了α-β剪枝技术。

α-β剪枝技术的基本思想或算法是,边生成博弈树边计算评估各节点的倒推值,并且根据评估出的倒推值范围,及时停止扩展那些已无必要再扩展的子节点,即相当于剪去了博弈树上的一些分枝,从而节约了机器开销,提高了搜索效率。

具体的剪枝方法如下:

(1) 对于一个与节点MIN,若能估计出其倒推值的上确界β,并且这个β值不大于MIN 的父节点(一定是或节点)的估计倒推值的下确界α,即α≥β,则就不必再扩展该MIN 节点的其余子节点了(因为这些节点的估值对MIN 父节点的倒推值已无任何影响了)。这一过程称为α剪枝。

(2) 对于一个或节点MAX,若能估计出其倒推值的下确界α,并且这个α值不小于MAX 的父节点(一定是与节点)的估计倒推值的上确界β,即α≥β,则就不必再扩展该MAX 节点的其余子节点了(因为这些节点的估值对MAX 父节点的倒推值已无任何影响了)。这一过程称为β剪枝。

从算法中看到:

(1) MAX 节点(包括起始节点)的α值永不减少;

(2) MIN 节点(包括起始节点)的β值永不增加。

在搜索期间,α和β值的计算如下:

(1) 一个MAX 节点的α值等于其后继节点当前最大的最终倒推值。

(2) 一个MIN 节点的β值等于其后继节点当前最小的最终倒推值。

3.4 输赢判断算法设计

因为每次导致输赢的只会是当前放置的棋子,输赢算法中只需从当前点开始扫描判断是否已经形成三子。对于这个子的八个方向判断是否已经形成三子。如果有,则说明有一方胜利,如果没有则继续搜索,直到有一方胜利或者搜索完整个棋盘。

四、数据结构

4.1 程序流程

4.2 主要成员函数

4.2.1 估值函数

估价函数:int CTic_MFCDlg::evaluate(int board[])

完成功能:根据输入棋盘,判断当前棋盘的估值,估价函数为前面所讲:

若是MAX 的必胜局,则e = +INFINITY,这里为+60

若是MIN 的必胜局,则e = -INFINITY,这里为-20,这样赋值的原因是机器若赢了,则不考虑其它因素。

其它情况,棋盘上能使CUMPUTER 成三子一线的数目为e1

棋盘上能使PLAYER成三子一线的数目为e2,

e1-e2 作为最终权值

参数:board:待评估棋盘

返回:评估结果

4.2.2 Alpha-Beta 剪枝算法

AlphaBeta 剪枝主函数:

int CTic_MFCDlg::AlphaBeta(int Board[], int Depth, int turn, int Alpha, int Beta, int *result) 完成功能:根据输入棋盘,搜索深度,及其他参数,给出一个相应的最优解,存入result 中。参数:board :待评估棋盘

Depth :搜索深度

turn :当前是机器走(MAX 结点)还是玩家走(MIN 结点)

Alpha :alpha 值,第一次调用默认-100

Beta :beta 值,第一次调用默认+100

result :输出结果

返回:若当前点为MAX 节点,则返回alpha 值;

若当前点为MIN 节点,则返回beta 值

4.2.3 判断胜负

int CTic_MFCDlg::isWin(int curPos)

完成功能:根据输入棋盘,判断当前棋盘的结果,COMPUTER 胜?PLAYER 胜?平局?参数:board:待评估棋盘

返回:-1 表示:尚未结束

0 表示:平局

1 表示:PLAYER 胜

2 表示:COMPUTER 胜

4.2.4 鼠标左键响应

void CTic_MFCDlg::OnLButtonDown(UINT nFlags, CPoint point)

完成功能:鼠标左键相应,在点击的那格放置玩家棋子,之后再相应计算机走下一步

4.2.5 Draw 系列函数

void CTic_MFCDlg::DrawBoard(CDC *pDC)

完成功能:根据Chess 棋盘数组画出棋盘