小编Gou*_*ham的帖子

基于C++的变体国际象棋引擎设计问题

我有一个国际象棋变种引擎,与正常的国际象棋一起玩自杀国际象棋和输家国际象棋.随着时间的推移,我可能会为我的引擎添加更多变种.该引擎完全用C++实现,并正确使用OOP.我的问题与这种变型引擎的设计有关.

最初这个项目最初只是一个自杀式引擎,而且随着时间的推移,我添加了其他风味.为了添加新的变体,我首先尝试在C++中使用多态.例如,MoveGenerator抽象类有两个子类SuicideMoveGenerator,NormalMoveGenerator并且根据用户选择的游戏类型,工厂将实例化正确的子类.但我发现这要慢得多 - 显然是因为实例化包含虚函数的类并在紧密循环中调用虚函数都是非常低效的.

但后来我发现使用带有模板特化的C++模板来分离不同变体的逻辑,并最大限度地重用代码.这似乎也很合乎逻辑,因为动态链接在上下文中并不是必需的,因为一旦你选择了游戏类型,你基本上坚持它直到游戏结束.C++模板专业化提供了这种 - 静态多态性.模板参数是SUICIDELOSERSNORMAL.

enum GameType { LOSERS, NORMAL, SUICIDE };
Run Code Online (Sandbox Code Playgroud)

因此,一旦用户选择游戏类型,就会实例化适当的游戏对象,并且从那里调用的所有内容都将被适当地模板化.例如,如果用户选择自杀象棋,让我们说:

ComputerPlayer<SUICIDE>
Run Code Online (Sandbox Code Playgroud)

对象被实例化,并且该实例化基本上静态地链接到整个控制流.函数in ComputerPlayer<SUICIDE>将使用MoveGenerator<SUICIDE>,Board<SUICIDE>等等,而相应的函数NORMAL将适当地工作.

总的来说,这让我在开始时实例化正确的模板化专业课程,在任何if地方都没有任何其他条件,整个过程完美无瑕.最好的是没有性能损失!

然而,这种方法的主要缺点是使用模板会使您的代码更难阅读.如果处理不当,模板专业化也会导致严重错误.

我想知道其他变种引擎作者通常做什么来分离逻辑(好的代码重用)?我发现C++模板编程非常合适,但如果有更好的东西,我会很高兴拥抱.特别是,我检查了Dr. HG Muller的Fairymax引擎,但它使用配置文件来定义游戏规则.我不想那样做,因为我的许多变种都有不同的扩展,并且通过使它成为配置文件级别的通用,引擎可能不会变强.另一个受欢迎的引擎Sjeng到处乱七八糟,if我个人觉得这不是一个好的设计.

任何新的设计见解都非常有用.

c++ templates chess

5
推荐指数
2
解决办法
1233
查看次数

标签 统计

c++ ×1

chess ×1

templates ×1