首页 百科知识 棋盘模块的构成

棋盘模块的构成

时间:2022-10-01 百科知识 版权反馈
【摘要】:在棋盘模块的设计上,我们将其主体分为3层,即棋盘、全棋盘和对局。“棋盘”是整个围棋程序的基础,它保留着对弈过程中棋子的各种基本信息。综合考虑,为了能兼顾到不同的需求,在棋盘相关模块的设计上,需要考虑到不同功能分配的层次关系。使得在每次需要棋盘功能的时候,只让所需要的内容被计算,避免计算多余的内容而浪费计算资源。

15.4.1 棋盘模块的构成

在棋盘模块的设计上,我们将其主体分为3层,即棋盘、全棋盘和对局。这主要是从面向对象的角度进行考虑,保证每一子模块都是一个独立的功能单元,不仅可以应用在对弈过程中,在局面的评估上也可以很方便地拿来使用。

1.棋盘

“棋盘”是整个围棋程序的基础,它保留着对弈过程中棋子的各种基本信息。就像真实的棋盘一样,它需要保留棋盘上各个位置的棋子信息;除此之外,由于围棋本身所具有的特性,其各个棋子并不是单独发生作用,而是由于棋子和其他棋子间的相互位置,以及互相之间的连接关系才使之变得有意义,所以,为了提高引擎在对弈时的效率,避免在对弈过程中不断去计算一些和棋子之间的相互关系有关的信息而浪费计算效率,棋盘还需要记录如可下点、棋块、气、眼、打吃状态等信息,并且在每次棋盘状态发生变化时对这些常用信息进行动态更新,以此来获得更高的对弈效率。

2.全棋盘

给我们一份棋谱,我们可以还原出这盘棋的结果,但是,反过来讲,如果只有一个终局状态,我们却无法得到这盘棋的棋谱。究其原因,就是棋盘状态本身并不包含有关落子顺序的信息,给我们一个状态,我们只能看到一个结果,看到各个位置是什么颜色的棋子,看到各个棋子间的连接关系,但是,关于各个棋子的顺序关系单从棋盘上却看不出来。

从面向对象这个角度来看,将棋子的顺序信息放到棋盘上并不是那么的合适。并且,从程序结构的灵活性以及性能的需求上考虑,由于在进行局面评估时,很多时候需要在一个临时的棋盘上进行模拟,这个临时的棋盘可以是棋盘类的一个实例,也可以是棋盘类子类的实例,这就要看实际的需求;但是,其不可避免的都要包涵盖棋盘的全部信息。而在盘面评估时,并非所有时候都需要棋子顺序的信息,有时需要很快的速度,有时则又对准确性有较高要求。记录棋子顺序不但不会帮忙,在需要速度的时候反倒会拖后腿。综合考虑,为了能兼顾到不同的需求,在棋盘相关模块的设计上,需要考虑到不同功能分配的层次关系。使得在每次需要棋盘功能的时候,只让所需要的内容被计算,避免计算多余的内容而浪费计算资源。从这个角度上看,将棋子顺序的信息从基本的棋盘上分离出来也是有其实际的需要。

“全棋盘”这个概念就是从这里产生的,由于其要包含棋盘的全部信息,并且要可以像棋盘本身一样可以灵活的使用这些信息,所以我们将其设计成棋盘的子类。除此之外,就是要额外包含棋子顺序的信息,有了棋子顺序的信息之后,保存棋谱的功能也是随之而来的。

3.对局

到了现在,我们已经有了棋盘,但是,我们却无法在这个棋盘上下棋,因为目前棋盘还无法和对局者发生关联。因而,我们需要一个机制,通过这个机制来将棋盘和对局者联系起来,这个机制就是就是“对局”。

当两个对弈者想下棋时,他们便通过对局来连接起来,通过对局,便可以将两个对弈者放到棋盘上,控制对弈双方根据指定的颜色来轮流落子,以及当棋局结束时返回对弈结果。

通过上述分析,我们可以发现,要想形成一个对局,需要一个全棋盘和两个对弈引擎来共同配合,并且,还需要记录对弈双方的颜色以及当前轮到哪一方落子等与对局相关的信息。由此可以看出,对局是以全棋盘为基础,需要用到棋盘的众多基础信息,由此,将其作为全棋盘的子类更加合适;而对于对弈引擎来说,对局只是需要在必要的时候来让对弈引擎返回一个坐标即可,故而,对局和对弈引擎的关系则更多是一种调用关系。

如图15.2所示是棋盘模板的UML图,其中,除了前面介绍的3个基本类以外,还有Episode_Game和Node两个类,这两个均是在蒙特卡洛博弈树搜索中需要使用到的类,由于这两个类均需要使用到棋盘信息,所以它们也都作为棋盘类的一个子类。

img187

图15.2 棋盘模板UML图

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈