Chess Programming Tutorial...[]


iCE is the outcome of a little recreational programming project. I find the aspects of chess engine programming very fascinating because it covers many aspects of computer science from low level hardware dependant CPU instructions up to high level abstract algorithms.

The engine is the final prove point whether an idea or implementation works. But the stronger the engine becomes the more difficult it becomes to improve it. Many ideas that look good at first fail so when you consider a try at chess programming yourself make sure your frustration level is high enough.

Probably there are only a few 1000 people worldwide that possess the skill to write a chess program, good thing is they are organized very well and form an active community.

And you don't have to be very good at chess to build an engine; you should know the basics however. So you have to know the exact rules of chess as you are going to implement a move generator and you should have some basic positional knowledge like where is the king safe, rooks belong on open files and behind passed pawns, don't place your knight at the edge etc. Unless you are a extremely strong player this knowledge will be enough to build an engine that beats you consistently at some point in time.

How it works

The core of the engine is a search algorithm that searches a tree of possible future chess positions from the given board. It tries to determine what move will give you the best result if your opponent always makes his best move. This algorithm is called MiniMax. The are several implementations and improvements over the plain algorithm and iCE is using a PVS (principal variation search) implementation of MiniMax.

As the search tree growths very quickly different techniques are used by chess engine to spend more time on positions that are likely to happen and less time on the others.

iCE is written in C++ and consists currently of about 15.000 lines of code. It compiles under Visual C++, gnu C compiler (with mingw) and the Intel C Compiler. Currently it is developed and tested under windows only and from version 1.0 onwards exists a 32bit and two 64 bit versions of it (a generic one and one relying on modern CPU instructions). Prior versions were only available as 32 bit.

iCE implements most of the known techniques

  • The heart of its search is a PVS framework using a traditional Fail Hard approach
  • It's opening books are in a internal format and assembled using a large set of games.
  • From version 1 on iCE has some limited use of Piece Square Tables to evaluate centralization.
  • From version 2 iCE now implements razoring where complete branches of the tree might be cut-off
  • From version 2 iCE now uses history heuristics to improve its move ordering
  • iCE does not access external databases with endgame knowledge, it calculates its moves up to the end himself
  • iCE uses only a very conservative lazy eval with a big safety margin
  • iCE does not rely on CLOP for tuning its weights or parameters. It's using its own tuning algorithm for that.

Its evaluation is based on about 60 positional terms. Each term has a certain weight associated with it. The weight of the pawn material score is set to a fix value of 100. All other weights are relative to this. So to value a knight as 3 pawns the material weight of a knight would be 300.

From version 1.0 onwards all weights are tuned using genetic algorithms by a self developped tuning framework.

The evaluator scans for the presence of a term and just summarizes the weighted terms that are present. This is the score that the position gets assigned.


ELO Ratings are based on the CCRL 40/40 rating list Mar 2016.

iCE 3

3046 ELO - Division 1 player

Jan 3, 2016

UCI Options Cleanup The UCI options of iCE are restructured and renamed. Details can be found here: iCE 3 UCI Options

Multi PV support iCE is now supporting Multi PV mode.

Bugfix The ponder protocol implementation is fixed. In Shredder GUI it did not work.

Evaluation: A bit of weight tuning was perfromed. However most changes failed or had only minor impact.

Search Changes: iCE 2 added History Heuristics, Late Move Pruning, Razoring and Counter Move Heuristics. For iCE 3 I optimized the conditions a bit further to make smarter pruning decisions.

Books: I finally touched my book code again. It was necessary as the books contained some errors coming from changes to the internal move format. I also improved the book building framework to use perfromance data of iCE in certain lines.

Time Management: I changed the algorithm for time allocation to not use all available time on the last move before TC.

iCE 2

2885 ELO - Division 2 player

Sept 6, 2014

Bugfixes: Bugs related to recognizing a trapped rook and to the 50 move rule were fixed

Pawn Hash Handling: King position is now stored into the pawn hash which allows the hashing of additional eval terms while the hit rate goes down a bit.

Endgame Knowledge: Some special code to handle certain 5 piece endgames was added

Evaluation: Some changes to the evaluation to understand certain positions better. An example are positions with an isolated queens pawn. Tests showed only limited impact on the strength. I kept them because I hope the overall playing style of iCE looks more natural now in those positions.

Table Bases: iCE is not using external table bases during play. iCE 1 had the DTM data for all the 3-men TB built into the executable. Those tables were removed in iCE 2. They are calculated on the fly when the engine starts. The calculation is fairly optimized and takes less than 100 ms on a decent 1 core system.

Search Changes: Added History Heuristics, Late Move Pruning, Razoring and Counter Move Heuristics. Change LMR to be less aggressive. Lazy eval removed. Added LMR at the root node.

Code Cleanup: A lot of code was refactored and simplified. Especially similar code for WHITE and BLACK was merged using C++ templates. Overall from iCE 1 to iCE 2 5600 lines of code were removed while 3800 lines were added.

iCE 1

2707 ELO - Division 3 player

Jul 10, 2013

The complete evaluation has been rewritten. The old version used constant weights to evaluate certain features in a position. This helped the compiler to generate efficient code however every change to a weight required a recompliation of the program. For my later tuning efforts this was to inflexible.

Added endgame knowledge. Knowledge that helps iCE to understand drawn positions in KRKP and KQKP endgames.

Evaluation of passed pawns The potential of passed pawns is now better evaluated. iCE 0.3 was here to optimistic and often traded its pieces to get a passed pawn that had little chances of promoting. Additionally a recognizer to spot unstoppable passers is now part of the evaluation.

Evaluation Tuning All earlier prototypes used evaluation weights that were not tuned. If a new term was not able to improve the engine with an untuned weight it was removed again. This was against the principle of only adding features if you can't improve the engine with existing ones anymore. For the tuning itself I implemented my own tuning framework using a genetic algorithm that worked on all weights in parallel. Some tests with positional EPD testsets showed that the positional understanding of iCE was improved by this.

Search Parameter Tuning The same framework was used to tune the search control parameter. The framework itself was not changed. However as most of the control parameters were set to new values it behaves now completely different.

64 bit Versions All prototype versions were only available as 32 bit versions. Some code changes were necessary to implement 64 bit versions of basic bit operations. The 64 bit version (/w popcount) runs about 70% faster than the 32 bit version on the same HW.

Unchanged iCE is still a CLOP free zone and does not access endgame tablebases in play. However the new endgame knowledge was verified against Gaviota table bases. Tribut and thanks for providing them goes to Miguel Ballicora. Also everything related to opening books is unchanged and still works the same with 1.0

iCE worked its way up from division 5 to division 3 of the CCRL amateur engines tournaments and it played several times in there. It finished usally in the lower ranks.

iCE 0.3

2460 ELO - Division 5 player

Jul 10, 2012

This is a new major version. It adds major new functionality.

  • Some new evaluation terms (e.g. pawns islands)
  • Understands the draw by fifty move rule and tries to avoid it when leading
  • Improved endgame knowledge. Better understandig of drawn positions.
  • Implements a small internal opening book if no external book is supplied.
  • Support for external opening books in a proprietary format.
  • Changed node counting rule (horizon nodes not counted twice anymore)
  • Algorithm improvements to speed up the code.
  • Draw by Repetition detection bug fix (was not really working)

iCE 0.3 played the Divison 5 and finished several times somewhere in the middle. It's biggest success was its performance in the Big Freeware Tournament Group 7 in December 2012. It finished 1st place ahead of Delphil 2.9g.

iCE v0.2 Build 1085

No ELO change

Sep 07, 2011

This is a maintenance relase that addresses some problems that were reported for iCE running on 64bit systems. No change in search and eval was done.

It played several times in division 5 (from 7 divisions) of the CCRL amateur engines tournaments and finished usally in the lower ranks. It played also the Division 5 and its final playoff of WBEC Ridderkerk. It finished 2nd place and promotes to D4.

iCE v0.2 Build 1070

2367 ELO - Division 6 player

Sept 01, 2011

  • Complete rewrite of the evaluation
  • Better endgame knowledge for basic endgames
  • Activated permanent brain (engine thinks also when it's the opponents turn)
  • Using compiler optimizations when building the binaries
  • Implemented a benchmarking function that solves test positions
  • Improved quiescence search
  • A few major and lot of minor bug fixes from v0.1

The biggest bug was in quiescence search where it considered all but the last tactical move.

iCE 0.2 played in the Chess War 17 tournament. It started in division H and qualified for promotion in the next higher divisions. It finished in Divison C as 64.

iCE v0.1

2153 ELO - Division 7 player

Mar 01, 2011

This is the initial offical release. The core of the engine is translated from the pascal based mACE engine. It implements now magic bitboards instead of rotated ones and has some minor improvements in the search algorithm.

It played several times in the division 7 (the lowest) of the CCRL amateur engines tournaments and finished somewhere in the middle each time. It also played in the promotion of the Chess War 17 tournament. It finished with a 4th place (out of 200 engines) and gained the promotion to the division H. This divison was then played by ice 0.2