本文已参与「新人创作礼」活动.一起开启掘金创作之路。
1 游戏设计流程图
根据上节的介绍,游戏流程图设计如下:
2 UCT(信心上限树算法)的实现
position run() {
创建根节点;
初始化各种参数;
while (true) {
//选择Selection
while (已经扩展完全且游戏未结束)
选择最佳子节点;
//扩展Expansion
if (未扩展完全且游戏未结束)
拓展子节点(之后对当前扩展的子节点进行模拟);
//模拟Simulation
if (当前节点游戏未结束) {
创建模拟游戏;
while (棋盘上空位置数量不为0) {
if (黑色棋没有位置可以落子&&白色棋没有位置可以落子)
break;
确定当前下棋方;
得到当前可落子位置;
if (可落子集合不为空) {
随机选择一个可落子围住落子;
}
else 将当前角色标记为无位置可落子;
交换落子权;
}
}
//反向传播Back propagation
返回输赢, 若AI赢则为1, 反之为0;
while (节点不为空) {
更新节点的value和访问数;
节点更新为其父节点;
}
选择当前棋局下的最佳子结点;
if (搜索时间到达上限或者迭代次数到达上限) break;
迭代次数++;
}
return 最佳位置;
}
3 类设计说明
3.1 State 类
State 类是表示当前棋局状态的类, 其中包含玩家属性、棋盘当前情况、 当前情况上一步的落子位置,下一步的落子位置集合以及落子位置的个数;操作包含判断棋局是否已结束、模拟结束后返回value值等。
3.2 TreeNode 类
TreeNode 类是UCT中用到一个重要的节点类,其中包含了当前棋局的状态、节点被访问的次数、节点的总获利、节点的子节点集合和父节点;类的方法主要用到expend()和update(float delta),分别用于扩展子节点和模拟游戏后更新节点属性。
3.3 UCT 类
在UCT 类中,信心上限树算法包含在其中,包括已迭代次数,最大迭代次数属性,主要用到的方法有通过信心上限值估计值选取最佳子节点方法get_best_uct_child()、选取最高胜率子节点方法get_most_winning_rate_child()以及
UCT算法的主控方法run()。
4、程序使用说明
4.1 运行环境
本软件是在Windows 10系统开发的,利用Visual Studio 2017结合EasyX 图形库进行算法开发和图形界面设计的,在使用时也可兼容Windows 7系统。
4.2 操作手册
本软件的使用有两种方式:
(1)使用Visual Studio软件打开,此时打开的是源文件,需要进行以下配置。
首先需要在系统上安装VS2017。
然后需要在VS2017上配置EasyX图形库,本次设计采用了EasyX2018库,打开网页easyx.cn/downloads/v…
在VS2017中,需要点击项目属性,依次选择C/C++-语言,将符合模式改为否,然后点击配置属性栏下的常规,将字符集改为“使用多字节字符值”,并将SDL检查改为否。在C/C++-代码生成-运行库中,若为Release下调试改为多线程调试 (/MDd),若为Debug下调试改为多线程调试 DLL (/MDd)。在链接器-系统中,将子系统:/subsystem:console修改为/subsystem:windows。
另外,在移动工程所在文件夹后,需要对软件的logo所在位置进行修改,打开资源文件所在代码,需要将“IDI_ICON1 ICON "D:\研究生-2\人工智能\第一次作业\黑白棋_203464\pic\southeast.ico"”中的地址修改为正确地址。
(2)使用Release发布模式,打开Release文件夹,直接点击203464_黑白棋.exe即可运行本程序。
在黑白棋开始之前可以设置AI和人的先后手,在othello.cpp中的UCT_GamePlay()函数定义中设置为othello Othello = CreateNewGame_AIfist();表示AI执黑棋,先手下棋。如果设置为othello Othello = CreateNewGame_Humanfist();表示人执黑棋,先手下棋。
然后打开源文件,设置为计算机先手。点击运行,程序创建出棋盘并初始化为双方都有两枚棋子,创建出的棋局如图 5.2 所示:
图5.2中深色的部分为计算机可落子的位置,如图5.3所示为计算机落子后的界面,其中带加号的黑子为计算机刚下的棋,并在另一个界面上显示根据UCT值计算的计算机胜率、迭代次数和本次下棋所用的时间。
如下图为人落子点,带加号的白子为人刚下的棋:
如下图为人落子后,计算机根据计算所走的下一步棋:
然后依次进行人和计算机落子,直到游戏结束,如图5.5所示。
此时如果点击是,则将重新开始新一局游戏,否则将退出游戏。