15.5.2 对弈引擎的实现
引擎可作为整个围棋程序中最重要的部分,决定着着法的生成,是整个程序的水平的高低的决定因素。
在程序的设计上,首先需要一个引擎的基类,在这个基类中,提供一个纯虚的用于生成落子点的接口函数;在前面棋盘和对局类的实现中,我们已经可以见到对该基类的使用,主要是通过对虚函数的调用来实现的。而我们需要程序来实现的对弈策略,只需要实现一个继承该基类的子类并用具体的策略来实现该虚函数即可。比如,前面章节提到的蒙特卡洛博弈树搜索的策略,就可以设计成一个继承自该基类的子类,然后用蒙特卡洛博弈树搜索的策略来实现其虚函数。
在图15.1中,黑白双方均为一对弈引擎,这个引擎既可以是人,也可以是某个对弈策略,甚至也可以是网络另一侧传过来的对弈信息。为了让程序具有较高的灵活性,可以较容易地构建新引擎并加入到博弈过程中。
如图15.3所示是引擎模块的UML图,其中,Engine作为抽象类,是整个引擎模块的基类,纯虚函数play作为其成员函数,起接口的作用。play函数有两个参数,分别是棋局状态和当前一方的颜色,而其返回值就是该颜色需要落子的位置坐标。继承自Engine的子类所需要做的就是实现该play函数,将具体的下棋逻辑和策略封装在该函数里。
图15.3中的UCT_Engine、Human_Engine、Net_Engine就分别是其子类,其play函数的策略则分别对应UCT算法、接受终端输入、接受来自网络的对弈信息;除此之外,其他的任何可行的策略也都可以作为实现Engine的子类的play函数的策略。
图15.3 对弈引擎UML图
Listing15.6是与下棋引擎相关的伪码实现,第1~3行是对下棋引擎基类的定义,其中,第3行中的play函数尤为重要,该函数就是整个引擎模块的接口函数。第5~21行分别是Figure15.3中提到的3个继承自该基类的子类,其中,第5~9行是一个供人类棋手使用的的对弈引擎,这个引擎负责接收从终端传过来的输入,然后将其转换成坐标信息并返回;第11~15行是用来支持网络对弈功能的引擎,用于接收从网络另一侧传递过来的棋局信息,然后将其转换成程序可识别的位置坐标传递给对局,比如第13章提到的和CGOS服务器的连接就可以通过一个这样的引擎来实现;第17~21行是一个实现了UCT策略的引擎,它不向前两个引擎需要从终端或者从网络来接收输入,而是自己具有逻辑判断能力,通过使用UCT算法来对当前棋盘局势进行分析,然后产生所需的对弈方的落子位置。
Listing15.6 引擎伪码
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。