A variants chess engine design question

Discussion of anything and everything relating to chess playing software and machines.

Moderators: bob, hgm, Harvey Williamson

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Post Reply
nphard

A variants chess engine design question

Post by nphard » Fri Sep 10, 2010 6:26 pm

Hello all,

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 };
So once user selects a game type, appropriate game object is instantiated and everything called from there will be appropriately templatized. For instance if user selects suicide chess,

Code: Select all

Nakshatra<SUICIDE>
is instantiated and that instantiation basically creates the whole control flow statically. Functions in Nakshatra<SUICIDE> would work with MoveGenerator<SUICIDE>, Board<SUICIDE> and so on while corresponding NORMAL one will appropriately work.

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

User avatar
hgm
Posts: 24096
Joined: Fri Mar 10, 2006 9:06 am
Location: Amsterdam
Full name: H G Muller
Contact:

Re: A variants chess engine design question

Post by hgm » Fri Sep 10, 2010 7:41 pm

Fairy-Max was designed for Chess-like games that only differ from orthodox Chess because (some of) the pieces move in un-orthodox ways. That is a much more homogeneous group than {suicide, normal}, and it would be logical to use the same extensions and reductions.

In fact this was part of its design goal: I needed something that could compare the values of different pieces, by playing them against each other using the same search algorithm, and no special knowledge about strategies for using these pieces (like tuned piece-square tables), to make sure there would be no bias in favor of the orthodox pieces.

I agree with your conclusion that it would be a bad idea to play variants as different as suicide and normal by merely changing engine parameters. I know Sjeng is an engine that plays a very diverse set of variants, and it is open source. I never looked at it myself. Pulsar is another variant engine that is not open source, but if I understood the author correctly, he basically has a different search engine in there foreach variant.

I don't know C++, so I cannot help you with that...

nphard

Re: A variants chess engine design question

Post by nphard » Fri Sep 10, 2010 10:46 pm

Thanks for pointing at Sjeng. I just downloaded the code and browsed for a while. The code is completely in C so polymorphism or templates are out of question. Design-wise, the variant separation is merely by use of (variant == Normal|Suicide|Losers|...) conditions. These conditions are literally everywhere. One of the text files in the source package mentions that the code has become very hard to maintain. I can understand why :)

tmokonen
Posts: 1084
Joined: Sun Mar 12, 2006 5:46 pm
Location: Vancouver

Re: A variants chess engine design question

Post by tmokonen » Fri Sep 10, 2010 11:29 pm

You may want to take a look at the open source GPL program ChessV (http://samiam.org/chessv/), which is written in C++. I haven't done C++ in years, but taking a quick look at the source I can see ChessV makes use of templates and inheritance. It is not just strictly an engine, but also has a GUI component.

Perhaps this thread should be in the programming section...?

Post Reply