Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Crafty tablebase file format (readme.tb)

Author: Dan Newman

Date: 15:25:45 05/25/98

Go up one level in this thread


Hi,
    Here is latest version that I have of SJE's readme.tb file.  (This
file doesn't seem to be included with his tbgen source code.)  As you
will see, indexing the tablebases properly is a bit tricky.  I also have
the tbt.c file mentioned in readme.tb, if anyone needs it.  It's much
too
long to post here--1654 lines.  (I don't recall actually needing it when
I put tablebase support into an earlier program though.)

-Dan.

email: dnewman@bellatlantic.net

PS.  I hope this file isn't too long to post here--it's not much longer
than some heavily quoted posts I've read recently, so I'll assume it's
OK.


/*

Tablebase Documentation

Revised: 1995.01.28

Author: Steven J. Edwards (sje@mv.mv.com)


Abstract:

A tablebase is a file of fixed length coded values for a given chess
endgame
class with each possible chess position corresponding to an entry in the
file.  The entry for a given position gives the result of "best play"
for
that position as win, draw, or loss.  If a win or loss is indicated, the
number of fullmoves to checkmate with best play is coded into the entry.


Introduction:

Here is some ANSI C header code from my chessplying program Spector that
gives the interpretation of the signed byte entries in the tablebases.
The
intended readership is assumed to be reasonably proficient with ANSI C
and
discrete matrix operations.  A sample program can be found as the ANSI C
file pub/chess/TB/tbt.c at the ics.onenet.net ftp site.  The operating
instructions are included in the C source as commentary.  An MS-DOS
executable file, tbt.exe, is also available at the same location.


Tablebase File Names:

Each tablebase file is named according to its endgame class and the side
to
move.  The endgame class is given by using the SAN piece letters
(KQRBNP) of
the White pieces followed by the letters of the Black pieces.  The side
to
move suffix is "tbb" for "Black to move" and "tbw" for "White to move".
A
single period separates the endgame class string from the side to move
suffix.  Pieces for each side appear in the order "K", "Q", "R", "B",
"N",
and "P".

If the file is compressed using the gzip program, it will have a
secondary
suffix of ".gz".  This indicates that the file will need to be
decompressed
using the gunzip program before it can be used.


Tablebase Values:

Note: because the tablebase files contain binary data, they must be
fopen'd
using the "rb" option and not "r".

This system will handle winning positions with mate lengths from 1 to
126.
Losing positions may be from "lost in 0" (checkmated) up to "lost in
125".
All draws are zero.

Note that

    mate-in-1 > mate-in-2 > ... mate-in-126 > draw
    (126)     > (125)     > ... (1)         > 0

and that

    draw > lost-in-125 > lost-in-124 > ... lost-in-0
    (0)  > (-1)        > (-2)        > ... (-126)

and so the current implementation cannot handle mates of length greater
than
126 or losses of length greater than 125.

Illegal positions have the value 127.

Markers for transition (-127) and unknown (-128) scores are used only
during
construction and should not appear in the final output.

Positions that chain to another tablebase (i.e., promotions or captures)
have
the value minimaxed (when more than one) from the secondary
tablebase(s).
All of these entries are present but are not normally indexed.  Example:
KQKR
with queen and rook on same square with WTM means that the rook just
captured
the queen and the score was taken from the appropriate slot in the KRK
tablebase.  The corresponding BTM position means that the queen just
took the
rook and so the value will be taken from the KQK tablebase.


EPD Value transformation:

For those incorporating these tables into a chessplaying program, it is
suggested that the appropriate value transformation be used to convert
from
the single byte encoding scheme to the signed sixteen bit integer EPD
(Extended Position Description) standard.  Programs that use EPD help
support
quick integeration.  Fortunately, conversion to EPD evaluations is easy
to do.

Description   Signed Byte   EPD Signed Word
-----------   -----------   ---------------
unknown       -128          <no equivalent>
transition    -127          <no equivalent>
lost-in-0     -126          -32767  (checkmated)
lost-in-1     -125          -32765
lost-in-2     -124          -32763
...
lost-in-N     (N - 126)     ((N * 2) - 32767)
...
lost-in-125   -1            -32517
draw          0             0
mate-in-126   1             32516
...
mate-in-N     (127 - N)     (32767 - (N * 2) + 1)
...
mate-in-3     125           32762
mate-in-2     125           32764
mate-in-1     126           32766
illegal       127           -32768

The EPD signed 16 bit words are usually interpreted as centipawn values.
However, scores less than -31744 are treated as forced losses while
scores
greater than 31743 are treated as forced wins.

More information about the EPD standard can be found in the appropriate
section of the Portable Game Notation standard (pub/chess/PGN/Standard
at the
ics.onenet.net ftp site).


Indexing:

Note that all the tablebases are constructed with White as the side with
more
material (e.g., better winning chances).  If Black is the side with
better
material, then the colors are reversed and, if any pawns are present,
the
piece positions have to be reflected across the X axis prior to
indexing.

In addition to reflection across the X axis (White's side vs Black's
side),
some accesses will require relection across the Y axis (kingside vs.
queenside) and the X=Y axis (the a1-h8 diagonal).

Each tablebase has its own indexing scheme, but they are all fairly
similar.
The basic idea is that the tablebase for an N man endgame will be an N
subscript array with one subscript for each man.

First, squares are given by integers from 0 to 63 in the order a1, b1,
...
h1, a2, b2, ... h2,a3, ... h8.

Second, there are three "fields" or scanning patterns.  The "all" field
ranges from 0 to 63 for squares a1 through h8.  The "tri" field takes
values
from 0 to 9 for squares a1, b1, c1, d1, b2, c2, d2, c3, d3, d4.  The
"qsf"
field takes values from 0 to 31 for squares a1, b1, c1, d1, a2, b2, c2,
d2,
a3, ... d8 (this is the "queen side flank").

Each subscript position for a given tablebase follows a given scanning
pattern.


The Tablebase List:

*** The KPK tablebase is indexed as the C array:

	signed char KPK[64][32][64];

With above scanning patterns being "all", "qsf", and "all".

The first subscript is the position of the black king.  The second
subscript
is the position of the white pawn; note that the 64 -> 32 remap must be
applied prior to indexing.  (The wP is forced to be on the queenside if
needed; if it is reflected about the Y axis, both the wK and the bK must
also
be reflected as well.)  The third subscript is the position of the white
king.

*** The KRK tablebase is indexed as the C array:

signed char KRK[10][64][64];

The scanning patterns are: "tri", "all", and "all".  The subscripts are:
bK,
wR, and wK.  The piece positions are reflected across various axes to
map the
bK into the a1-d1-d4 triangle.

*** The KQK tablebase is indexed as the C array:

signed char KQK[10][64][64];

The scanning patterns are: "tri", "all", and "all".  The subscripts are:
bK,
wQ, and wK.  The piece positions are reflected across various axes to
map the
bK into the a1-d1-d4 triangle.

*** The KBNK tablebase is indexed as the C array:

signed char KBNK[10][64][64][64];

The scanning patterns are: "tri", "all", "all", and "all".  The
subscripts
are: bK, wN, wB, and wK.  The piece positions are reflected across
various
axes to map the bK into the a1-d1-d4 triangle.

*** The KBBK tablebase is indexed as the C array:

signed char KBBK[10][64][64][64];

The scanning patterns are: "tri", "all", "all", and "all".  The
subscripts
are: bK, wB, wB, and wK.  The piece positions are reflected across
various
axes to map the bK into the a1-d1-d4 triangle.

*** The KRKN tablebase is indexed as the C array:

signed char KRKN[10][64][64][64];

The scanning patterns are: "tri", "all", "all", and "all".  The
subscripts
are: bN, bK, wR, and wK.  The piece positions are reflected across
various
axes to map the bN into the a1-d1-d4 triangle.

*** The KRKB tablebase is indexed as the C array:

signed char KRKB[10][64][64][64];

The scanning patterns are: "tri", "all", "all", and "all".  The
subscripts
are: bB, bK, wR, and wK.  The piece positions are reflected across
various
axes to map the bB into the a1-d1-d4 triangle.

*** The KQKN tablebase is indexed as the C array:

signed char KQKN[10][64][64][64];

The scanning patterns are: "tri", "all", "all", and "all".  The
subscripts
are: bN, bK, wQ, and wK.  The piece positions are reflected across
various
axes to map the bN into the a1-d1-d4 triangle.

*** The KQKB tablebase is indexed as the C array:

signed char KQKB[10][64][64][64];

The scanning patterns are: "tri", "all", "all", and "all".  The
subscripts
are: bB, bK, wQ, and wK.  The piece positions are reflected across
various
axes to map the bB into the a1-d1-d4 triangle.

*** The KQKR tablebase is indexed as the C array:

signed char KQKR[10][64][64][64];

The scanning patterns are: "tri", "all", "all", and "all".  The
subscripts
are: bR, bK, wQ, and wK.  The piece positions are reflected across
various
axes to map the bR into the a1-d1-d4 triangle.

*/

#define pageL 256
typedef signed char tiT, *tiptrT; /* tiny integer */

/* tablebase byte entry semispan length */

#define tbbe_ssL ((pageL - 4) / 2)

/* the signed byte evaulation type */

typedef tiT bevT, *bevptrT;

/* tablebase signed byte entry values */

#define bev_broken  (tbbe_ssL + 1)  /* illegal or busted */

#define bev_mi1     tbbe_ssL        /* mate in 1 move */
#define bev_mimin   1               /* mate in 126 moves */

#define bev_draw    0               /* draw */

#define bev_limax   (-1)            /* mated in 125 moves */
#define bev_li0     (-tbbe_ssL)     /* mated in 0 moves */

#define bev_trans   (-tbbe_ssL - 1) /* transition */
#define bev_unknown (-tbbe_ssL - 2) /* unknown */

/* signed byte entry range testing macros */

#define tbe_winning(bev) \
    (((bev) >= bev_mimin) && ((bev) <= bev_mi1))

#define tbe_losing(bev) \
    (((bev) >= bev_li0) && ((bev) <= bev_limax))

/* signed byte entry marker testing macros */

#define tbm_b(bev) ((bev) == bev_broken)
#define tbm_d(bev) ((bev) == bev_draw)
#define tbm_t(bev) ((bev) == bev_trans)
#define tbm_u(bev) ((bev) == bev_unknown)

/* reflectors */

#define reflect_x(sq) ((sq) ^ 0x0038)
#define reflect_y(sq) ((sq) ^ 0x0007)

#define reflect_xy(sq) ((((sq) & 0x0007) << 3) | (((sq) >> 3) & 0x0007))

/* end of tablebase header */



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.