EFS

The EFS project

(E)valuation (F)or (S)tarters

This C-code contains (most of) the evaluation function of the Gideon chess program (aka REBEL) that won the WCCCM Vancouver 1991 and WCCC Madrid 1992.

It is my first (and only) C-program after reading the first chapters of a book about C programming because there was time pressure to port the ARM RISC assembler code from the ChessMachine to the PC. Later versions (Rebel 6.0 and on) were written in assembler. Hence the C-code might be not what you expect just in case you wonder since I am not a typical C-guy. The code can be compiled with the GNU and Digital Mars compiler.

You can use the code in 2 ways:

1. build your own search around it.

2. insert it in your own existing engine.

 

Usuage

All it needs is the board in REBEL format as described below which you can communicate in 3 ways:

 

1. Use the REBEL format.

2. Make a quick conversion as demonstrated in TSCP (Tom Kerrigan Simple Chess Program), see example.

3. Use the EPD format, see the demonstration code in MAIN.CPP

 

 

The REBEL board format (see source/tables/bgstel)

More info at: Inside REBEL

Used Name

Value

Definition

 

Used Name

Value

Definition

RR

0

Out of board

 

 

 

 

LL

1

Empty square

 

 

 

 

WP

2

White pawn

 

ZP

8

Black pawn

WN

3

White knight

 

ZN

9

Black knight

WL

4

White bishop

 

ZL

10

Black bishop

WT

5

White rook

 

ZT

11

Black rook

WD

6

White qieen

 

ZD

12

Black Queen

WK

7

White King

 

ZK

13

Black King

Short internal description

 

  1. init() initializes a few things before the evaluation of the position can start, the most important table is the piece-list veldwz in order that we don't have to scan the full board with all its empty squares, just the pieces on the board only. veldwz from the start position looks like this:

 

E1 | D1 | H1 | A1 | F1 C1 | G1 | B1 H2 | G2 | F2 | E2 | D2 | C2 | B2 | A2 | 0xff

E8 | D8 | H8 | A8 | F8 C8 | G8 | B8 H7 | G7 | F7 | E7 | D7 | C7 | B7 | A7 | 0xff

 

The area is sorted on piece-value and controlled by 4 pointers:

wpnt1 - start white pieces (0)

wpnt2 - start white pawns (8)

zpnt1 - start black pieces (17)

zpnt2 - start black pieces (25)

 

  1. evaluation() evaluates the given board posirion in 2 steps:

 

Step1 - via veldwz (see source/attack.c) it first builds the attack boards bord2 (for white) and bord3 (for black). more info at: Inside REBEL During step-1 material, PST, mobility (for knight, bishop and rook) pins, subtraction threads, bad (inactive) bishops, caught bishops, rook doubling, rook cooperation, rook open and half open files are evaluated. Furthermore it builds 2 variables called wsom and zsom for the use in step-2 for late endgame evaluation.

 

Step2 - now that bord2 and bord3 are generated we can further evaluate the position, see source/eval2.c Once again via veldwz we evaluate king safety, pawn structure, weak paws, isolated pawns, double pawns, passed pawns, pawn pressure on weak | isolated pawns and unstoppable pawns. Thereafter the final score is calculated in the variable mp and returned. Late endgame cases such as KPK, WNBK etc. are handled seperately via wsom and zsom.

 

Last but not least with the information in bord2 and bord3 we extract the 2 highest hanging pieces (SEE) from the 2 tables with a simple table lookup into the varaibles z2 and z5. These are exteremely handy for move ordering, just generate the captures on these squares first, of course after searching the move from the hash table first.

 

REBEL uses the value of 256 for a pawn so if you are using a different value (say 100) convert it back by:

your_score = (mp*100)/256;