C++黑白棋实验报告文档格式.docx
- 文档编号:16010429
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:25
- 大小:24.14KB
C++黑白棋实验报告文档格式.docx
《C++黑白棋实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《C++黑白棋实验报告文档格式.docx(25页珍藏版)》请在冰豆网上搜索。
下面一一介绍各自功能的作用和实现方式。
3、悔棋
悔棋功能即为返回上一步下棋之前的状态,通过数组记录前一步棋盘状态,悔棋时返回上一步棋盘状态。
悔棋功能可以无穷悔棋,如果已经是开局状态会提示无发悔棋。
4、存档与读档
存档和读档通过二进制文件流实现,共有三个存档位置,存在游戏安装目录下,存档时可选择三个存档中的一个存档。
读档是若读取的是未存储的存档位置,会提示重新读档。
5、提示功能
提示功能是这个程序比较独特的功能之一,主要是在玩家不知道该怎么下时可以由AI代替玩家下一步棋,实现较为简单。
一、AI部分介绍
1、最大最小值搜索
AI部分的主干采取的是博弈问题中常见的敌对搜索,原理较为简单,不在过多赘述。
模拟自己下棋以及对手下棋,当到达一定深度时通过估值函数给出对局面的估价。
然后再对手下棋层取子节点中的最小值(对手不想让“我”赢),自己下棋的层取子节点最大值。
2、剪枝:
α-β剪枝和节点排序
Alpha-beta剪枝是敌对搜索中较为常见的最优性剪枝,由于每层中先搜索的节点(为简单,以下称为兄节点)的返回值实际上给出了本层同父节点(上一个节点相同)的界限,例如在最小值节点A的子节点中a的返回值为5,那么A的返回值至多为5。
若A的兄节点B的返回值为6,则AB的父节点X必定不会取A的值。
故A节点的其他子节点的搜索已经无意义。
此时A节点直接返回5。
我们发现在α-β剪枝中剪枝的效率同节点搜索顺序有极大关系,如果最先搜索的是最优解,那么剪枝效率极高。
如果在最糟糕的情形下,先搜索的节点总比后搜索的节点糟糕,那么实际上不会进行剪枝。
由此产生了对剪枝的进一步优化:
节点排序。
节点排序是在搜索之前先对所有待搜索的点做一步预搜索(本程序中采用的是直接估值的方式),按照大小顺序排序之后。
按顺序进行搜索。
这样先搜索的枝则有较大可能为较优枝,而预搜索层数很少,所以在时间上代价并不大。
3、估价函数
估价函数是决定棋力高低的重要因素,较常见的估价包括行动力(可以下棋的位置)、稳定子、内部子(相对稳定子),外部子(危险子)、奇偶性(最后一步谁下)。
因为估价函数的复杂性会使得AI思考时间迅速上升,故在折中考虑以及多次实践之后,我采取了以行动力为主,同时对于绝对稳定子(四个角上的子)和最大危险子(2,22,77,27,7)进行考虑。
在试验多次后和考虑全部稳定子相比差距并不大,而时间上略有减少。
因此采用这种方式。
4、残局搜索(终局搜索)
黑白棋在即将结束时的考虑因素和中局不太相同,中局时主要考虑稳定子和行动力。
但是在残局时应该考虑最多的是最终棋子数目,而且残局是可下棋位置逐渐变少,搜索层数限制的不大,因此在残局时直接搜索至游戏结束,从中选出必胜策略。
代码:
文件1:
“MyFunction,h”
#include<
iostream>
iomanip>
fstream>
string>
cstdio>
cstring>
cstdlib>
ctime>
queue>
conio.h>
windows.h>
usingnamespacestd;
/*引用外部变量*/
externHANDLEhout;
externHANDLEhin;
externINPUT_RECORDmouseRec;
//控制台输入信息
externDWORDres;
externstringsidestr[3];
//输出字符
externintturn_side[2];
//表示走棋次序对应黑棋/白棋
externintdir[8][2];
//方向
externintboard[9][9];
//棋盘
externintformer_board[64][9][9];
//记录历史棋盘
externintstep;
//步数
externintdepth;
//搜索深度
externintplayerside;
//玩家的颜色
externintaput_x,aput_y;
//每次AI走的棋子
externintturn[2];
//表示走棋次序对应玩家/AI
/*-------------------------------------------基本功能函数-------------------------------------------*/
/*清屏函数*/
inlinevoidclear_screen()
{
COORDhome={0,0};
DWORDdummy;
CONSOLE_SCREEN_BUFFER_INFOcsbi;
GetConsoleScreenBufferInfo(hout,&
csbi);
FillConsoleOutputCharacter(hout,'
'
csbi.dwSize.X*csbi.dwSize.Y,home,&
dummy);
SetConsoleCursorPosition(hout,home);
}
/*隐藏光标*/
inlinevoidhide()
CONSOLE_CURSOR_INFOcursor_info={1,0};
SetConsoleCursorInfo(hout,&
cursor_info);
/*光标定位*/
inlinevoidlocate(intx,inty)
COORDcoord;
//光标位置
coord.X=x;
coord.Y=y;
SetConsoleCursorPosition(hout,coord);
//光标定位
/*读取当前鼠标点击位置*/
inlineCOORDget_mouse()
while
(1){
COORDpos;
ReadConsoleInput(hin,&
mouseRec,1,&
res);
if(mouseRec.EventType==MOUSE_EVENT)
{
if(mouseRec.Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED)
{
pos=mouseRec.Event.MouseEvent.dwMousePosition;
returnpos;
}
}
/*鼠标定位(功能选择)*/
inlineintmouse_locate(COORDpos)
intx=pos.X,y=pos.Y;
if(y==0&
&
x>
11&
x<
16)return1;
//1表示点击的是存档键
16&
21)return2;
//2表示点击的是读档键
21&
26)return3;
//3表示点击的是悔棋
26&
30)return5;
//5表示点击退出键
30)return6;
//表示点击的是作弊键
if(y>
2&
y<
18&
y%2)
if(x>
1&
34)return4;
//4表示点击的是落子区域
return0;
//0表示点击非法区域
/*复制棋盘*/
voidcopy(intorg_board[9][9],intcopy_board[9][9])//复制棋盘
for(inti=1;
i<
9;
i++)
for(intj=1;
j<
j++)
copy_board[i][j]=org_board[i][j];
/*求棋子数*/
intsum(intnow_board[9][9],intmy_side)//求棋子数
ints=0;
if(now_board[i][j]==my_side)s++;
returns;
/*翻转棋盘*/
voidchange(intx,inty,intmy_side){
board[y][x]=my_side;
for(intj=0;
8;
j++)//八个方向
inttempx=x+dir[j][0],tempy=y+dir[j][1],i=1;
while(tempx>
0&
tempx<
9&
tempy>
tempy<
9)//不超过边界
if(board[tempy][tempx]==0)break;
//遇到空位置跳出
elseif(board[tempy][tempx]==my_side)
{
for(intk=1;
k<
i;
k++)
board[y+k*dir[j][1]][x+k*dir[j][0]]=my_side;
break;
}
i++;
tempx+=dir[j][0];
tempy+=dir[j][1];
/*判断该位置是否合法*/
boolcheck(intx,inty,intmy_side)
if(x==0||y==0||x>
8||y>
8)return0;
if(board[y][x]!
=0)return0;
if(i>
1)return1;
//如果遇到己方子并且中间至少有一个对方子,说明可以下
//遇到己方子跳出
/*----------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 白棋 实验 报告