人工智能实验报告井字棋.docx
- 文档编号:25921212
- 上传时间:2023-06-16
- 格式:DOCX
- 页数:20
- 大小:485.40KB
人工智能实验报告井字棋.docx
《人工智能实验报告井字棋.docx》由会员分享,可在线阅读,更多相关《人工智能实验报告井字棋.docx(20页珍藏版)》请在冰豆网上搜索。
人工智能实验报告井字棋
人工智能
实验报告
姓名:
学号:
院系:
类别:
科目:
人工智能
时间:
2017.01.04
一、实验及其界面显示
1.一字琪玩法介绍
一字棋由电脑和人轮流来下,分别用“X”和“O”来代替自身的棋子(O表示电脑落子位置,X表示人落子位置)。
棋盘分9个格,双方可以在轮到自己下的时候,可以用棋子占领其中一个空的格子。
如果双方中有一方的棋子可以连成一条直线,则这一方判胜,对方判负。
当所有的格子都被占领,但双方都无法使棋子连成一条直线的话,则判和棋。
此程序1-9分别表示棋盘上的不同位置,如下图所示:
1
2
3
4
5
6
7
8
9
2.一字棋程序所用软件
软件名称:
Dev-C++。
由于我使用的电脑是win10系统,无法兼容vc6。
所以使用Dev-C++这个可以与win10兼容的软件。
Dev-C++是一个C&C++开发工具。
软件界面如下所示:
3.实验调试
将程序进行调试,没有错误,然后运行。
调试结果如下:
4.运行程序
运行程序,有两种选择:
人先走,和电脑先走。
显示界面如下:
输入数字1:
输入数字5(表示走在中间位置):
输入数字3:
输入数字4:
输入数字2:
输入数字9:
5.可能出现的运行结果:
通过验证,发现此程序可能出现三种结果:
这局是平局、孙伟输了、恭喜孙伟赢了。
还可以终止此场游戏,但是玩家孙伟赢了,和预期有所出入,后面将具体分析。
下图是各种情况出现的截图:
二、程序分析
1.checkWin函数
应用程序主要包含checkWin函数,用来判断胜负,列出了一字棋可以赢的8种可能;
2.Search函数
Search函数主要作为估价函数,主要用于计算机落棋时来判断落子位置的。
所有的估值都是根据一字棋可能赢的8种情况来的。
对于计算机可以落子的每一种情况进行判断,所得到的的最大值,即计算机应该落子的位置。
例如:
若果计算机先走,则返回的f值如下表所示:
落子位置
1
2
3
4
5
6
7
8
9
返回的f值
3
2
3
2
4
2
3
2
3
从上表可以看出当落子位置为中间位置时,返回的f值最大为4,所以计算机会选择位置5落子。
3.Checkwinning函数
用来确定是否已经有两点成线,返回成线的位置。
4.Man函数
表示玩家落子位置
5.计算机落子位置
通过Search函数的值以及Checkwinning函数来确定落子位置。
Checkwinning函数的优先级高于Search函数。
6.Display函数
用来显示棋盘的落子位置。
7.main函数
主函数main函数,通过调用其它函数实现程序本身的功能。
三、针对玩家赢的情况对此程序进行分析:
以下这种情况是玩家赢,并且所有类似的走法都是玩家赢。
运行如下:
例如下面这种情况,当玩家先走4时,计算机优先走5。
当玩家再走的位置为3时,计算机可以走的位置只有1,2,6,7,8,9,四个位置。
但是计算机选择的位置是9,为什么计算机没有选择走位置1?
通过对程序的反复校核和思考。
终于找到了答案。
Checkwinning函数在返回f值之前并不能预测玩家下一步的位置,通过目前棋子的位置也不能满足Checkwinning函数的条件。
因此执行Search函数。
当玩家再走的位置为3时,计算机可以走的位置只有1,2,6,7,8,9,四个位置。
此时各个位置返回的f值如下:
落子位置
1
2
6
7
8
9
返回的f值
7
7
7
8
8
8
通过比较可以发现:
7,8,9三个位置的f值相同且均为最大值。
将此三个位置通过Checkwinning函数,可以判断出落子位置是9时,计算机才有赢的可能性,所以选择了9。
四、实验心得
通过这次实验发现人工智能是一个非常有意思的科学。
并且通过自己的不断尝试与努力,终于将程序运行出来,并且对运行的结果进行了分析。
感觉非常有意义,学到了很多,这次实验使我受益匪浅。
在此感谢老师的辛苦教学及精心指导!
五、附源代码:
#include
#include
#include
#include
#defineMAX1000/*定义最大值为1000*/
#defineMIN-1000/*最小值为-1000*/
#defineNONE0/*如果搜索不到结果,结果NONE*/
#defineDRAW1/*定义平局DRAW为1*/
#defineC_WIN2/*电脑赢为2*/
#defineM_WIN3/*人赢为3*/
#defineQUIT4/*放弃为4*/
#defineMAN-1/*人用-1表示*/
#defineCOM1/*电脑用1表示*/
#defineTRUE1
/*定义b[10]用来存储棋盘(board),step表示可以下的步数
,r表示结果,初始值为NONE;w表示可以赢的位置*/
intb[10]={0},step=9,r=NONE,w=0;
/*checkWin函数用来判断胜负,如果有胜负,返回胜方,否则返回NONE*/
intcheckWin(intt[],intp){
if(t[1]==p&&t[1]==t[2]&&t[2]==t[3])return(p);
if(t[4]==p&&t[4]==t[5]&&t[5]==t[6])return(p);
if(t[7]==p&&t[7]==t[8]&&t[8]==t[9])return(p);
if(t[1]==p&&t[1]==t[4]&&t[4]==t[7])return(p);
if(t[2]==p&&t[2]==t[5]&&t[5]==t[8])return(p);
if(t[3]==p&&t[3]==t[6]&&t[6]==t[9])return(p);
if(t[1]==p&&t[1]==t[5]&&t[5]==t[9])return(p);
if(t[3]==p&&t[3]==t[5]&&t[5]==t[7])return(p);
return(NONE);
}
/*search函数,搜索计算机和人可以羸的机会,用来计算评价值,*/
intsearch(intt[]){
intf=0,k=0;
k=checkWin(t,MAN);/*先判断人是否可以羸*/
if(k==MAN)returnMIN;/*如果可以返回一个最小值*/
if(t[1]>=0&&t[2]>=0&&t[3]>=0)f++;
if(t[4]>=0&&t[5]>=0&&t[6]>=0)f++;
if(t[7]>=0&&t[8]>=0&&t[9]>=0)f++;
if(t[1]>=0&&t[4]>=0&&t[7]>=0)f++;
if(t[2]>=0&&t[5]>=0&&t[8]>=0)f++;
if(t[3]>=0&&t[6]>=0&&t[9]>=0)f++;
if(t[1]>=0&&t[5]>=0&&t[9]>=0)f++;
if(t[3]>=0&&t[5]>=0&&t[7]>=0)f++;
if(t[1]<=0&&t[2]<=0&&t[3]<=0)f--;
if(t[4]<=0&&t[5]<=0&&t[6]<=0)f--;
if(t[7]<=0&&t[8]<=0&&t[9]<=0)f--;
if(t[1]<=0&&t[4]<=0&&t[7]<=0)f--;
if(t[2]<=0&&t[5]<=0&&t[8]<=0)f--;
if(t[3]<=0&&t[6]<=0&&t[9]<=0)f--;
if(t[1]<=0&&t[5]<=0&&t[9]<=0)f--;
if(t[3]<=0&&t[5]<=0&&t[7]<=0)f--;
returnf;/*计算评价值,并返回评价值*/
}
/*checkWinning函数用来搜索是否已经有两子成线,并返回成线的位置*/
intcheckWinning(intp,intt[]){
inti,k=10;
for(i=1;i<10;i++){
if(t[i]==0){
t[i]=p;
if(checkWin(t,p)==p){
t[i]=0;
k=i;
w++;
}
t[i]=0;
}
}
returnk;
}
/*display函数用来显示棋盘,并显示结果*/
voiddisplay(inttype){
printf("姓名:
\n");
printf("学号:
\n");
printf("学院:
\n");
printf("班级:
\n");
chardis[10]={""};
inti;
for(i=1;i<10;i++){
if(b[i]<0)dis[i]='X';
if(b[i]>0)dis[i]='O';
}
printf("\n%c|%c|%c\n",dis[1],dis[2],dis[3]);
printf("-----\n");
printf("%c|%c|%c\n",dis[4],dis[5],dis[6]);
printf("-----\n");
printf("%c|%c|%c\n",dis[7],dis[8],dis[9]);
if(type==NONE)printf("请继续");
if(type==DRAW)printf("这局是平局!
!
");
if(type==C_WIN)printf("孙伟输了");
if(type==M_WIN)printf("恭喜孙伟赢了!
");
if(type==QUIT)printf("孙伟停止了这场游戏!
");
}
/*人下的时候执行man函数*/
intman(){
intc;
/*提示信息*/
printf("\n请输入您想下的位置,输入0结束(输入1-9分别代表9宫格所在的位置)\n");
for(c=getche();;printf("\n"),c=getche())
if(isdigit(c)&&b[c-48]==0){
/*如果用户输入的是"0"就结束程序*/
if(c=='0'){r=QUIT;return0;}
/*下在用户输入的位置,步数减1*/
step--;b[c-48]=MAN;
/*如果步数为0,结果设为平局*/
if(step==0)r=DRAW;
/*人赢了,结果为M_WIN*/
if(checkWin(b,MAN)==MAN)
r=M_WIN;
return0;
}
}
intcom(){
inti,j,t[10];
inttemp,max=MIN-1,f=0,best=1,k,flag;
system("cls");
/*如果电脑可以赢下在该位置*/
flag=checkWinning(COM,b);
if(flag<10){b[flag]=COM;r=C_WIN;step--;return0;}
/*如果人可以赢,也下在相应的位置*/
flag=checkWinning(MAN,b);
if(flag<10){b[flag]=COM;step--;return0;}
/*用t暂时存储棋盘*/
for(i=1;i<10;i++){
t[i]=b[i];
}
for(i=1;i<10;i++){
if(t[i]==0){
t[i]=COM;
f=MAX;
k=checkWinning(COM,t);/*如果搜索到下了第i格后人可以赢*/
/*就对算法进行剪支,只返回k位置的评价值*/
for(j=1;j<10;j++){
if(k<10){
t[k]=MAN;
f=search(t);
t[k]=0;
break;
}/*否则算出每个生成的结点的评价值*/
if(t[j]==0){
t[j]=MAN;
temp=search(t);
if(temp f=temp; } t[j]=0; if(f==MIN)break; } } t[i]=0; if(f>max){/*在最大层中选择最大的评价值*/ best=i; max=f; } } } b[best]=COM;/*并下在最大层中评价值最大的位置*/ step--; if(step==0)r=DRAW; } main(){ charc; inti; system("cls"); printf("姓名: \n"); printf("学号: \n"); printf("学院: \n"); printf("班级: \n"); for(i=0;i<30;i++) printf("*"); printf("\n是否想先下? (自己先下请输入1,电脑先下请输入2)\n"); for(c=getche();c! ='1'&&c! ='2';c=getche()); if(c=='1'){man();if(step<=0||r! =NONE){system("Cls");display(r);getch();return0;}} while(TRUE){/*人与电脑轮流下*/ com();display(r);if(step<=0||r! =NONE)break;/*如果有胜负就结束程序*/ man();if(step<=0||r! =NONE){system("Cls");display(r);break; } } getch(); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 人工智能 实验 报告 井字棋