Home / rodent
Name Modified Size InfoDownloads / Week
Parent folder
search 2013-02-02
eval 2013-02-02
move 2013-02-02
bitboard 2013-02-02
trans.h 2013-02-02 1.5 kB
util.c 2013-02-02 3.8 kB
trans.c 2013-02-02 4.7 kB
timer.c 2013-02-02 5.0 kB
timer.h 2013-02-02 1.9 kB
setboard.c 2013-02-02 2.9 kB
swap.c 2013-02-02 2.5 kB
selector.h 2013-02-02 1.3 kB
selector.c 2013-02-02 8.2 kB
rodent.h 2013-02-02 7.5 kB
readme.txt 2013-02-02 13.2 kB
parser.h 2013-02-02 1.3 kB
pst.c 2013-02-02 12.8 kB
parser.c 2013-02-02 15.0 kB
main.c 2013-02-02 2.2 kB
learn.h 2013-02-02 1.3 kB
init.h 2013-02-02 1.1 kB
learn.c 2013-02-02 3.1 kB
hist.h 2013-02-02 1.3 kB
init.c 2013-02-02 1.9 kB
hist.c 2013-02-02 3.1 kB
data.h 2013-02-02 3.6 kB
gen.c 2013-02-02 9.6 kB
data.c 2013-02-02 7.3 kB
Copying.txt 2013-02-02 35.8 kB
book_internal.c 2013-02-02 93.6 kB
changelog.txt 2013-02-02 7.0 kB
book.h 2013-02-02 2.1 kB
attacks.c 2013-02-02 2.0 kB
book.c 2013-02-02 15.7 kB
rodent.ncb 2013-01-11 6.6 MB
rodent.sln 2013-01-11 890 Bytes
new_engine.vcproj 2013-01-11 7.7 kB
new_engine.vcproj.PAWEL.euro.user 2013-01-11 1.4 kB
Totals: 38 Items   6.9 MB 3
Rodent, a UCI chess playing engine derived from Sungorus 1.4
Copyright (C) 2009-2011 Pablo Vazquez (Sungorus author)
Copyright (C) 2011-2012 Pawel Koziol
http://www.pkoziol.cal24.pl/rodent/rodent.htm
https://github.com/nescitus/rodent_code

I. GPL License

Rodent is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published 
by the Free Software Foundation, either version 3 of the License, 
or (at your option) any later version.

Rodent is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty 
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

II. Acknowledgments

Rodent is an open source chess program derived from Sungorus 1.4 
by Pablo Vazquez. Seeing the simplicity of his code I instantly
fell in love with it, started adding chess knowledge and advanced
search algorithms. Hopefully code quality didn't deteriorate too
much because of that attempt at learning by emulation.

The second most important source is excellent document called
"Toga LOG user manual" by josephd, which is accessible from
http://members.aon.at/josefd/Toga%20LOG.html . It describes 
evaluation function of Fruit/Toga in a natural language. First
draft of Rodent evaluation function relied heavily on this
document. Currently at least king safety code is different, 
but for example weak pawn evaluation remains basically the same.

Open source programming makes most sense as a collaborative effort.
Rodent would be clearly weaker without the following contributions:

*Kestutis Gasaitis* has made a thorough inspection of Rodent's code,
pointing out many bugs and suggesting several improvements. See
changelog and github tickets for details.

*Dann Corbit* supplied fast population count functions 
making use of advanced 64-bit instructions and first bit intrinsics
(used since version 0.11 onwards)

*Denis Mendoza* and *Graham Banks* independently pointed out 
an important time management bug in version 0.12, 
affecting repeated time controls.

*Dann Corbit* and *Denis Mendoza* supplied me with 64-bit compiles.

III. Project goals:

1. Creating a didactic bitboard engine of reasonable strength, 
   using object-oriented design, modern search techniques and
   relatively small codebase. There are many superb open source
   engines, like Fruit, Crafty, Stockfish, to name but a few,
   and Rodent is unlikely to compete with them on equal footing
   for some time to come. One thing it can give, however, is 
   a search function that can be read at one sitting (thank You,
   Pablo Vazquez, it would not be possible without Your work!)
   
2. Providing a simple framework for testing new ideas and showcasing
   them (I'm planning a short paper on a "sliding LMR" concept) 
   
3. Providing an engine that is fun to play against, with adjustable
   strength and different personalities.
   
      
IV. The most important changes (comparing with Sungorus 1.4) include:

- making most of the code object-oriented (in progress)
- enabling fractional extensions and reductions
- rewriting piece/square code, so that we can use asymmetric pst tables 
  and interpolate between midgame and endgame scores
- adding futility pruning
- adding "sliding LMR" (see section on search)
- adding eval pruning (inspired by DiscoCheck)  
- adding many evaluation features and weights as described 
  in Toga LOG user manual  
- adding logarithmic king safety function  
- some speed optimizations, including pawn hash table and specialized
  PopCnt functions (many thanks to Dann Corbit for his patch making use
  of advanced 64-bit instructions)
- about 300 Elo gain over the original
- opening book in a silly proprietary format
- position learning
- weaker levels of play

V. SEARCH (featuring "sliding LMR" proof of concept)

- fail soft alpha beta with principal variation search (from Sungorus)
- transposition table (from Sungorus)
- null move with variable reduction depth (modified)
  and with threat detection in order to sort evasion higher (modified)
- futility pruning (added)
- "sliding" late move reduction (added)
- late move pruning (added)
- eval pruning (a.k.a. static null move)
- internal iterative deepening in pv nodes

Rodent uses PVS search with null move and transposition table inherited 
from Sungorus. It has been enhanced in several standard ways - by adding 
futility pruning, internal iterative deepening in pv nodes, check extension,
Stockfish-like null move pruning and using capture threats uncovered by 
null move for better move sorting.

The only non-standard solution is what I call "sliding Late Move Reduction".
Since Rodent from the very beginning uses fractional plies, it made sense
to check whether smoothly scaling reduction can help. And it certainly did.

It works as follows. Instead of a fixed one ply reduction, Rodent uses
something like:

QUARTER_PLY * ( (moves_tried / 5)+3 )

where moves_tried counts moves accepted by search as legal. Thus the first 
reduction occurs much later under normal scheme, but as the search proceeds, 
the effect of accumulated quarter ply reductions more than compensates for 
it, without hurting the playing strength. This kind of reduction has a chance 
of being much less detrimental to the tactical ability of the engine. After 
all, it is geared towards reducing more deeply when the engine encounters 
a series of moves that have low probability of changing the node value 
(move ordering, especially using history heuristic, is a measure of 
that probability).

Imagine a tactical shot requiring two quiet moves, the rest being
forcing and therefore exempt from reduction. Both are sorted around
move 20. Under normal scheme both would get reduced, the new one 
reduces just one. Instead, it trims the lines where many moves are 
sorted down the list. It's true that finding really deep combintations, 
full of quiet moves, is equally difficult under both schemes. However,
probability of such a combination is  

P(one_move_cuts) * P(next_move_cuts) ... * P(last_required_move_cuts) 

IIRC (I've never been much into maths, much less into the English math 
terminology) the right word for this kind of function is "exponential". 
If we manage to keep the growth of a reduction factor just a bit slower, 
we'll have a beautifully scalable reduction algorithm.

VI. EVALUATION

- Fruit-like piece/square tables and mobility values
- Fruit-like weak pawns eval
- passed pawns eval
- strong squares (B, N, even R)
- logaritmic, and therefore dynamic King safety evaluation

Creating version 0.13 I looked for more aggressive King safety function,
using Rebel-like additive table approach. I also wanted my function to 
ne initialized at startup using some relatively simple mathematical formula.
After some experiments with logistic function, I settled for an addition
of logarithmic and linear function. I'd like to express my gratitude
to Agnieszka Ziomek for discussing these mathematical matters with a noob
like me.

Mobility evaluation is sometimes inexact due to the concept of "transparent 
pieces". For example, own queen is considered transparent for the bishop. 
This might cause occasional error in evaluating whether a bishop can check 
enemy king, or force the engine to rely on search in order to avoid certain
blockages. However, tests has shown that this solution is better than more
exact mobility calculation.

VII. OPENING BOOK

Since version 0.14 Rodent uses its own opening book, encoded in a rather
inefficient manner. At startup, it reads two files: book.txt written in
a human readable format, and bigbook.wtf using Rodent's own ugly format
(hence the file extension). 

Rodent first looks for moves from the book.txt, and if none is found, it 
falls back to big main book.

book.txt encodes one opening in each line, and its format looks like that:

e2e4 a7a6? d2d4 b7b5 a2a4 c8b7 b1d2
e2e4 d7d5!! e4d5 d8d5 b1c3 d8d6!

It allows users to write down their own book preferences if they for example 
want to practice Ruy Lopez or Pirc Defense or force Rodent to play unusual 
openings. Moves may be followed by punctuation marks: ? (frequency -= 100),
! (frequency += 100), ?? (frequency -= 5000), !! (frequency += 5000). 
Additionally, a move with "xx" appended will be deleted from the main book
permanently.

A really desperate user might even create main opening book. All he needs
is any of files called feed.txt, feedwhite.txt and feedblack.txt placed 
in the program directory, Rodent opened in the console mode and manually 
typed command "feedbook". Program first reads bigbook.wtf (if found), then 
supplements it with the lines froom feed files, then chokes itself on shaker 
sort algorithm while displaying number of its iterations, and finally saves 
a file called newbook.wtf. At this stage user MUST RENAME newbook.wtf 
to bigbook.wtf. This is a precaution allowing to save old book in case that
user considers feed files corrupt.

Rodent contains small utility reformatting book files from something like:

e2e4e7e6d2d4d7d5b1c3f8b4

to version with spaces between the moves. In order to do this, one needs
to copy "dense" opening book into the file "dense.txt", open Rodent in the
console mode and type command "split". Result will be saved in "loose.txt".

Another additional command is "bookdoctor". This command causes Rodent to
investigate its main book file and stop at first point where it finds
either an infrequent move or missing transposition into book line. In both
cases it would be prudent to decide whether a move should be upgraded
or marked as unplayable.

Rodent may use big book in two modes: it may pick moves according to their 
frequency or conduct short verification search. The latter causes it to play
moves that it likes and to reject errors that are likely to be found in the 
big book. The second mode can be turned on using UCI option "VerifyBook"

VIII. WEAKENING

Rodent has a feature allowing to reduce its playing strength. For now, it is
still in the experimental phase and still undergoes tweaking and tuning, but 
basic infrastructure is already in place. It consists of three parts:

1. Weaker levels play slower. On starting a new iteration or changing a move
   Rodent "freezes" for a moment, depending on its Elo command.
   
2. Weaker levels add random value to evaluation score.

3. Weaker levels are more likely to blunder, because they forget 
   about calculating consequences of certain moves.

As You can probably guess, tuning the third element of the algorithm presents
the hardest challenge. Engine forgetting about certain moves (like captures
by a pawn or (re)captures of recently moved piece) would look unnatural, except
of the lowest levels. Engine forgetting about escapes from check would happily
sack material for false checkmates. Engine not missing tactical moves would not
be weak enough.

IX. INI FILE

rodent.ini file contains the following information

- panel type, determined by string "user nomal" or "user power"
- list of available strength levels
- list of available playing styles
- list of available opening books

Normal user panel lists available levels, strength and personalities, registered
in the ini file. Power user obtains the ability to manually set internal engine 
parameters via UCI options.

X. CONVENTIONS AND STRUCTURAL DECISIONS

Naming conventions:

- an asterisk before a comment announcing a code segment
  means that this part of code is undergoing modification 
  and testing
- variable names start with small letters
- function names start with captital letters
- variables treated as flags have "f" prefix, i.e. f_in_check
- bitboard variables have "bb" prefix, i.e. bbControl 
  in piece evaluators
- struct definitions have "s" prefix,  i.e. sEvaluator

Classes:

- sParser       - UCI parser  
- sTransTable   - transposition table (no functional change vs Sungorus)
- sHistory      - global history and killer tables
- sGenCache     - caching generated bitboards for minimal speedup
- sTimer        - setting and enforcing time controls
- sSelector     - picks moves in an ordered fashion
- sSearcher     - implements classical alpha-beta pvs search algorithm
- sEvaluator    - implements valuation function
- sData         - globally accessible configurable data; in the target version, 
                  if someone wants to concentrate on just one facet 
                  of a program, he will have to know just sData 
                  and the relevant class.

Structural decisions:

- we use the same square ordering as Crafty and Stockfish (A1 = 0)
- we DO NOT split Search function into pv and non-pv, 
  since resulting complexity isn't worth small speed gain.
Source: readme.txt, updated 2013-02-02