基于极大极小分析法的井字棋对弈Word下载.doc
- 文档编号:14328348
- 上传时间:2022-10-22
- 格式:DOC
- 页数:12
- 大小:775.50KB
基于极大极小分析法的井字棋对弈Word下载.doc
《基于极大极小分析法的井字棋对弈Word下载.doc》由会员分享,可在线阅读,更多相关《基于极大极小分析法的井字棋对弈Word下载.doc(12页珍藏版)》请在冰豆网上搜索。
如图所示为井字棋的一个格局,而格局之间的关系是由比赛规则决定的.通常,这个关系不是线性的,因为从一个棋盘格局可以派生出几个格局.例如图左侧所示的格局可以派生出5歌格局.例如图右侧所示,而从每一个新的格局又可派生出4个可能出现的格局.因此,若将从对弈开始到结束的过程中所有可能出现的格局都画在一张图上,则可以得到一颗倒长的”树”.
图1对弈问题中格局之间的关系
设计思路
设有九个空格,由MAX,MIN二人对弈,轮到谁走棋谁就往空格上放一只自己的棋子,谁先使自己的棋子构成“三子成一线”(同一行或列或对角线全是某人的棋子),谁就取得了胜利。
用叉号表示MAX,用圆圈代表MIN。
为了不致于生成太大的博弈树,假设每次仅扩展两层。
估价函数定义如下:
设棋局为P,估价函数为e(P)。
(1)若P对任何一方来说都不是获胜的位置,则e(P)=e(那些仍为MAX空着的完全的行、列或对角线的总数)-e(那些仍为MIN空着的完全的行、列或对角线的总数。
(2)若P是MAX必胜的棋局,则e(P)=+∞。
(3)若P是B必胜的棋局,则e(P)=-∞。
要注意利用棋盘位置的对称性,在生成后继节点的位置时,下列博弈结局都是相同的棋局(在博弈中,一宇棋的分枝系数比较小起初是由于对称性,而后是由于棋盘上未布子的空格减少所致)。
现在我们假设MAX走了这一步,而MIN的回步是直接在X上方的空格里放上一个圆圈(对MAX来说这是一步坏棋,他一定没有采用好的搜索策略)。
下一步,MAX又在新的格局下搜索两层.
现在图中MAX有两个可能“最好的”优先走步,假设MAX走了图上指明的那一步。
而MIN为了避免立即败北被迫走了另一步,从而产生如下棋局:
MAX再次搜索.
在这棵树中某些端节点(例如其中一个标记着A)代表MIN获胜,因此它们的估值为—∞。
当这些估值被倒推回去时,可看到MAX的最好的也是唯一能使他避免立即失败的一个走步。
现在,MIN可以看出MAX必然在他的下一走步中获胜,因此,MIN只好认输。
流程图
设计步骤
(1)选定博弈算法;
(2)建立一个简单的应用程序(如字符界面程序)来测试算法;
(3)选定图形界面中要实现的其他功能;
(4)实现图形界面的井字棋程序。
算法测试程序
功能的函数:
(1)可能胜利的方法:
structCHESS_MAN
(2)显示棋盘边框:
voiddisp_chess_board(void)
(3)打印棋盘函数:
voidinit_chess_board(void)
(4)用户输入落子位置函数:
intenter_chess_man
(5)判断函数:
intchk_winner(intplayer)
(6)评估函数值计算函数:
intget_best_chess
(判断哪一方获胜包含在5和6中)
总程序:
#include"
stdio.h"
malloc.h"
#defineSIZE3
#ifndefFALSE
#defineFALSE0
#endif
#ifndefTRUE
#defineTRUE1
#defineNONE0
#definePLAYER_A1
#definePLAYER_B2
#defineWARNNING255
#defineCOMPETITOR200
#defineWINNER-1
charchessboard[SIZE][SIZE];
structCHESS_MAN
{
introw;
intcol;
};
/*PLAYER可能胜利的方法*/
intget_value(intplayer)
{
inti,j,ret=0;
introw,col,inc;
intbNONE=FALSE;
/*检查所有行*/
for(i=0;
i<
SIZE;
i++)
{
row=SIZE;
bNONE=FALSE;
for(j=0;
j<
j++)
{
if(chessboard[i][j]==player)row--;
/*如果该位置有player的棋子占据*/
if(chessboard[i][j]==NONE)bNONE=TRUE;
/*如果该位置还没有棋子占
据,则返回bNONE为TRUE*/
}
if(row==1&
&
bNONE==TRUE)returnWARNNING;
/*电脑:
该行中有一个
空位且有对手下的2个旗子,则可能会输掉该局,返回WARNNING值)*/
elseif(row==SIZE)ret++;
/*电脑:
该行中没有player的棋子,
ret+1*/
}
/*检查所有列*/
col=SIZE;
j++)
{
if(chessboard[j][i]==player)col--;
if(chessboard[j][i]==NONE)bNONE=TRUE;
}
if(col==1&
该列中有一个
空位且有对手下的2个旗子,则可能会输掉该局,返回WARNNING值*/
elseif(col==SIZE)ret++;
该列中没有player的棋子,
/*检查左对角线*/
inc=SIZE;
bNONE=FALSE;
for(i=0,j=0;
i++,j++)
if(chessboard[i][j]==player)inc--;
/*如果该位置有player的棋子占据*/
if(chessboard[i][j]==NONE)bNONE=TRUE;
/*如果该位置还没有棋子占
据,则返回bNONE为TRUE*/
}
if(inc==1&
/*电脑:
左对角线中有
一个空位且有对手下的2个旗子,可能会输掉该局,返回WARNNING值*/
elseif(inc==SIZE)ret++;
左对角线中没有player的棋子,
ret+1*/
/*检查右对角线*/
for(i=0,j=SIZE-1;
i++,j--)
右对角线中有
右对角线中没有player的棋子,
returnret;
/*显示棋盘图形边框*/
voiddisp_chess_board(void)
inti,j;
/*显示棋盘最顶层边框*/
SIZE*4+1;
printf("
-"
);
printf("
\n"
/*显示3层棋盘格落子情况及其左、右和下边框*/
|"
j++)
if(chessboard[i][j]==PLAYER_A)printf("
o|"
/*如果是PLAYER_A落
子则用o表示棋子*/
elseif(chessboard[i][j]==PLAYER_B)printf("
x|"
/*如果是PLAYER_B
落子则用x表示棋子*/
elseprintf("
|"
/*输出该层下边框*/
printf("
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 极大 极小 分析 井字棋 对弈