Skip to content

Releases: likeawizard/tofiks

Tofiks 1.3.0

22 Oct 16:42
Compare
Choose a tag to compare

New release not even a full month after the last one.

I am happy that my engine is now being tested and ranked in CCRL Blitz. It's currently ranked quite low #544 out of 699 but that has given me even more motivation and another goal to strive for.

What's new?

New looks!

Given GoLang's Gopher mascot I commissioned some custom artwork for Tofiks the chess playing dog engine.
Tofiks
I think it looks absolutely adorable and compared to the old AI generated logo this guy seems like he knows what he is doing. Which is fair given how much it has grown ever since.

Score from 32bit to 16bit and Move from 16bit to 32bit

I decided to change up the types of the data my engine uses internally. I shifted 16bits from evaluation score used by the search towards the move type. 16bits is plenty to calculate scores for search with more than sufficient granularity. However, certain actions like finding the bitboard of the piece moved or determining if the move is a capture take significant calculation. This information is now also included in the Move type along with flags for isCastling, isDoublePawnPush.

While this change significantly slowed down my move generation it did speed up the make move functionality. The trade-off advantage for now seems minor but there are probably more potential speed up's available to be discovered. Also I still have 10bits unused from the 32.

Threefold repetition downgraded to twofold repetition

Threefold repetition I believe is just a human rule so that games do not accidentally and abruptly end in a draw when they shouldn't. But logically it does not make sense. If we assume we always play the best moves and the best moves only then if a position repeated itself twice there should be no logical reason it should not repeat itself thrice. Checking for 2-fold repetition is of course significantly cheaper than 3-fold. But I also discovered that the engine could not see three fold repetition draws from a distance because the transposition table would not permit the same position to be played out thrice. When we first repeat a position that is by definition a transposition to the initial position and a transposition table should be able to see that. So I noticed that I never hit the threefold repetition rule. I tested this in a completely lost position where the only way out is to check the enemy king any other move leads to instant mate. While the engine saw the mate and avoided it by delivering checks it could actually not determine that it was actually a draw but gave the evaluation still as favoring the opposition.

Tests, tests, tests... and fix some bugs

Like the threefold to twofold repetition bug was discovered by a test, some other bugs were too. I found a small inconsistency where white bishops would be valued more than black bishops. This is due to having a bug in eval - I entered a lot of positions which I evaluated without any further search. Flipped the colors and the side to move to represent the same position with swapped colors. And I found that in some circumstances the symmetry was broken and there was a bias in the colors.

Overall I had neglected tests for too long in my development. I have built a small and non-comprehensive list of tests:

  • Perft 6 positions from Chess Programming Wiki Perft results
  • Mate a small collection of mates from mate in 3 to mate in 6
  • PV correctness - check if the reported PV actually represents valid moves
  • Draw by repetition and forcing a draw in a otherwise lost game
  • Evaluation symmetry
  • Fuzz testing for encoding and decoding information to the transposition hash table

This is a small list and there positions in each are not exhaustive but it still has helped me with development speed due to the ability to making bold changes and simply re-running the tests and giving me a baseline confidence that it still functions mostly as it should.

Results

I played a round robin tournament with versions 1.0 through 1.3 to determine their relative strengths.

Rank Name                          Elo     +/-   Games    Wins  Losses   Draws   Points   Score    Draw   White   Black 
   1 tofiks-1.3                    182      27     600     378      89     133    444.5   74.1%   22.2%   74.8%   73.3% 
   2 tofiks-1.2                    108      25     600     315     134     151    390.5   65.1%   25.2%   69.2%   61.0% 
   3 tofiks-1.1                    -28      24     600     202     250     148    276.0   46.0%   24.7%   46.3%   45.7% 
   4 tofiks-1.0                   -304      35     600      57     479      64     89.0   14.8%   10.7%   15.3%   14.3% 

Given 3 weeks of development I am quite happy with the progress I have made.

What's Changed (auto-generated)

Full Changelog: v1.2.0...v1.3.0

Tofiks v1.2.0

29 Sep 15:29
Compare
Choose a tag to compare

It's not as major of a change as from 1.0 to 1.1 but still plenty of things have changes and without waiting for a year. I started development on a more robust test-suite. If I can think of any testable scenario to test I add it. It currently validates if a PV output by the engine is consists of valid moves (in response to a bug). It tests some basic mate positions. Also verifies the move generator against known perft positions.

I also focused on things like optimization. There were attempts made to make the make-unmake more efficient. Now it is simply done via copy-make principle. Where the current position is copied a move is made and if it needs to be taken back the position if overwritten with the copy. The idea was to save some irreversible changes (castling rights, captured pieces) and unmake the move based on the current board position, the move and the saved irreversible state. Initial testing showed a serious performance downgrade so that approach has been abandoned.

As far as chess playing goes:

  • Late Move Reductions (LMR) - try to reduce depth at which moves are being searched later in the move order.
  • Delta Pruning - in quiescence search when a side is down a lot of material there is little hope to improve so the branch is abandoned. Hopefully, pruning a lot of nodes where the difference between totally losing and completely losing makes little difference and focus can be shifted on more interesting branches.
  • Minor bug fixes and code clean up has seen some small improvements and performance gain.

Results

Rank Name                          Elo     +/-   Games    Wins  Losses   Draws   Points   Score    Draw   White   Black 
   1 tofiks-1.2                    189      34     400     260      62      78    299.0   74.8%   19.5%   76.0%   73.5% 
   2 tofiks-1.1                     53      30     400     183     122      95    230.5   57.6%   23.8%   59.8%   55.5% 
   3 tofiks-1.0                   -268      40     400      48     307      45     70.5   17.6%   11.3%   19.5%   15.8%

What's Changed

Full Changelog: v1.1.0...v1.2.0

Tofiks v1.1.0

17 Aug 07:30
5eee72c
Compare
Choose a tag to compare

Again it's been not quite a year but a lot of time has passed since v1.1.0 in November 2022. There have been a lot of bug fixes, refinements and performance tweaks. Most notably the addition of an Aspiration Window during the Iterative Deepening Search which allows for a narrower search window and increases overall performance. Improved MVV-LVA and added History and KillerMove heuristics allow for better move ordering and that enables Late Move Pruning - when at depth the search will only look at the most promising moves ignoring moves late in the order.

There were also some failed experiments. Like LazySMP or implementing some Texel tuning for Piece-Square-Tables. While failed and shelved, lessons were learnt and I hope to revisit both of them soon. There also seems to still be some bugs with the PV line sometimes containing errors. I was not able to track it down but my guess is it has to do with some Transposition Table shenanigans. Before moving onto LazySMP that needs to be fully resolved as it relies heavily of an efficient use of Transposition Tables. Texel - I want to overhaul the evaluation part before I go into investing time into optimizing its values.

I also want to add more search heuristics like Late Move Reductions - looking at moves later in the move order at reduced depth. Some search extensions for most promising moves could also be investigated.

So that's all talk. How does it actually compare to v1.0.0 in its chess playing ability?

I ran a 200 game match between the two versions with a time control of 10s+0.5s and positions from the Arasan.pgn book with 10ply depth.

Score of tofiks-v1.1 vs tofiks-v1.0: 139 - 32 - 29 [0.767]
...      tofiks-v1.1 playing White: 66 - 14 - 20  [0.760] 100
...      tofiks-v1.1 playing Black: 73 - 18 - 9  [0.775] 100
...      White vs Black: 84 - 87 - 29  [0.492] 200
Elo difference: 207.5 +/- 51.5, LOS: 100.0 %, DrawRatio: 14.5 %
200 of 200 games finished.

So that's about +200 Elo difference and a clear improvement.

Installation

Latest stable version 64-bit binaries can be found in the release section.

Compile yourself

  • Clone repository or copy files
  • Make sure you have Golang 1.19+ installed
  • make build will compile it your native architecture.
  • In the Makefile you can change the GOAMD64VERSION variable. The values range from v1 to v4 and include various sets of extended instruction sets. A higher v-value should be expected to have better performance but might have more specific architecture and instruction set extension requirements. Most modern CPUs should be AVX2 compatible which is v3, v4 requires AVX512 support.

Feature Overview

  • Magic Bitboard move generator
  • MVV-LVA move ordering
  • Principal Variation Search with Aspiration Window
  • Null Move pruning
  • Late Move pruning
  • Transposition table
  • History Heuristic
  • Killer Move Heuristic
  • Quiescence search
  • Draw detection - repetition, 50-move rule and insufficient material
  • Piece-Square-Table evaluation for early game and endgame.
  • Pawn structure evaluation
  • King safety-activity evaluation
  • Piece specific evaluation
  • PolyGlot opening book support
  • Supported UCI commands and options:
    • uci - 'handshake' initialization by the GUI, engine responds with its id and supported options with their defaults and ranges
    • go - with the following options: wtime, btime, winc, binc, movestogo, depth, movestime, ponder and infinite
    • setoption name <option> value <value>
      • Ponder default false
      • OwnBook default false - if there is a PolyGlot book.bin in the same directory as the executable the engine will try to load it and allow the option to be toggled.
      • Hash - Transposition Table size in MB
      • Move Overhead - lag compensation variable. Works as a negative increment to reduce the alloted thinking time. Crucial for playing over the web where the go time variables might be already outdated when receiving the command and also adjust for the time the for the GUI to receive the bestmove.
  • Non-UCI commands:
    • go perft <depth> - perft display number of leaf nodes at depth grouped by legal moves in the position also displays the nodes per second value for performance benchmarking.

Acknoledgments

  • Lichess and the Community for nuturing my love for chess and offering a free open source platform for chess. Tofiks can be found playing on lichess under its bot account.
  • The authors of Official lichess bot client. It saved a lot of time and headaches adopting a reliable solution to interact with the Lichess API instead of coding all myself.
  • The authors of Blunder engine. It is a great reference to practical examples of engine principles and algorithms with its well documented code.
  • Everyone on TalkChess.com Forums who have been helpful and patient explainging even very basic concepts to me.
  • Chess Programming Wiki and its maintainers for creating a very comprehensive resource for everything chess programming related.

What's Changed

Full Changelog: v1.0.0...v1.1.0

Tofiks v1.0.0

19 Nov 16:39
7885d5a
Compare
Choose a tag to compare

Tofiks v1.0.0 is here

It's been almost a year since I started my hobby of chess programming and this is a big milestone. By no means is my engine complete but for the first time I feel everything is in place and nothing major is broken that it can be released as a working version.

Installation

Latest stable version 64-bit binaries can be found in the release section.

Compile yourself

  • Clone repository or copy files
  • Make sure you have Golang 1.19+ installed
  • make build will compile it your native architecture.
  • In the Makefile you can change the GOAMD64VERSION variable. The values range from v1 to v4 and include various sets of extended instruction sets. A higher v-value should be expected to have better performance but might have more specific architecture and instruction set extension requirements. Most modern CPUs should be AMX2 compatible which is v3, v4 requires AMX512 support.

Feature Overview

  • Magic Bitboard move generator
  • MVV-LVA move ordering
  • Principal Variation Search
  • Null move pruning
  • Transposition table
  • Quiescence search
  • Draw detection - repetition, 50-move rule and insufficient material
  • Piece-Square-Table evaluation for early game and endgame.
  • Pawn structure evaluation
  • King safety-activity evaluation
  • Piece specific evaluation
  • PolyGlot opening book support
  • Supported UCI commands and options:
    • uci - 'handshake' initialization by the GUI, engine responds with its id and supported options with their defaults and ranges
    • go - with the following options: wtime, btime, winc, binc, movestogo, depth, movestime, ponder and infinite
    • setoption name <option> value <value>
      • Ponder default false
      • OwnBook default false - if there is a PolyGlot book.bin in the same directory as the executable the engine will try to load it and allow the option to be toggled.
      • Hash - Transposition Table size in MB
      • Move Overhead - lag compensation variable. Works as a negative increment to reduce the alloted thinking time. Crucial for playing over the web where the go time variables might be already outdated when receiving the command and also adjust for the time the for the GUI to receive the bestmove.
  • Non-UCI commands:
    • go perft <depth> - perft display number of leaf nodes at depth grouped by legal moves in the position also displays the nodes per second value for performance benchmarking.

Acknoledgments

  • Lichess and the Community for nurturing my love for chess and offering a free open source platform for chess. Tofiks can be found playing on lichess under its bot account.
  • The authors of Official lichess bot client. It saved a lot of time and headaches adopting a reliable solution to interact with the Lichess API instead of coding all myself.
  • The authors of Blunder engine. It is a great reference to practical examples of engine principles and algorithms with its well documented code.
  • Everyone on TalkChess.com Forums who have been helpful and patient explainging even very basic concepts to me.
  • Chess Programming Wiki and its maintainers for creating a very comprehensive resource for everything chess programming related.

What's Changed (auto generated)

Full Changelog: https://github.com/likeawizard/tofiks/commits/v1.0.0