I have a chess variants engine (Nakshatra: http://nakshatrachess.blogspot.com) that plays suicide chess and losers chess along with normal chess. I might, over time, add more variants to my engine. The engine is implemented completely in C++ with proper usage of OOP. My question is related to design of such a variant engine.
Initially the project started as a suicide-only engine while over time I added other flavors. For adding new variants, I experimented using polymorphism in C++ first. For instance, A MoveGenerator abstract class had two subclasses SuicideMoveGenerator and NormalMoveGenerator and depending on the type of game chosen by user, a factory would instantiate the right subclass. But I found this to be much slower - obviously because instantiating classes containing virtual functions and calling virtual functions in tight loops are both quite inefficient.
But then it occurred to me to use C++ templates with template specialization for separating logic for different variants with maximum reuse of code. This also seemed very logical because dynamic linking is not really necessary in the context as once you choose the type of game, you basically stick with it until the end of the game. C++ template specialization provides exactly this - static polymorphism. The template parameter is either SUICIDE or LOSERS or NORMAL.
Code: Select all
enum GameType { LOSERS, NORMAL, SUICIDE };
Code: Select all
Nakshatra<SUICIDE>
On a whole, this lets me instantiate the right templatized class at the beginning and without any other if coditions anywhere, the whole thing works perfectly. The best thing is there is no performance penalty at all! (though the code size increases, its least of my concern).
The main downside with this approach however is that using templates makes your code a bit harder to read. Also template specialization if not appropriately handled can lead to major bugs.
I wonder what do other variant engine authors normally do for separation of logic (with good reuse of code)?? I found C++ template programming quite beneficial but if there's anything better out there, I would be glad to embrace. In particular, I only checked Fairymax by Dr. H G Muller but that uses config files for defining game rules. I don't want to do that because many of my variants have different extensions and by making it generic to the level of config-files the engine might not grow strong.
Any new design insights would be very useful.
Thanks,
Goutham