Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: question about implementing tablebases

Author: Ross Boyd

Date: 13:56:44 12/11/04

Go up one level in this thread


On December 11, 2004 at 15:41:22, Uri Blass wrote:

>On December 11, 2004 at 04:34:03, Michel Langeveld wrote:
>
>>To probe a tablebase you need to setup some arrays.
>>
>>You need to fill the following array:
>>
>>int rgiCounters[10] = {0,0,0,0,0,0,0,0,0,0};
>>
>>This arrays contains of each piecetype the number.
>>Fill it as follows:
>>
>>// white:
>>// rgiCounters[0] == number of pawns
>>// rgiCounters[1] == number of knights
>>// rgiCounters[2] == number of bishops
>>// rgiCounters[3] == number of rooks
>>// rgiCounters[4] == number of queens
>>
>>// black:
>>// rgiCounters[5] == number of pawns
>>// rgiCounters[6] == number of knights
>>// rgiCounters[7] == number of bishops
>>// rgiCounters[8] == number of rooks
>>// rgiCounters[9] == number of queens
>>
>>This is doable, isn't it?
>>
>>Then you need to setup the arrays W, and B as follows:
>>
>>squaret W[C_PIECES * 5 + 1];
>>squaret B[C_PIECES * 5 + 1];
>>
>>   // piecetypes (1 .. 5):     fieldtypes (0 to 63):
>>   // 0 == PAWN                A1(0), A2(1) ... A8(7)
>>   // 1 == KNIGHT              B1(8) ...........B8(15)
>>   // 2 == BISHOP              ...................
>>   // 3 == ROOK                ...................
>>   // 4 == QUEEN               .................H8(63)
>>   // 5 == KING
>>   //
>>   // W[0] = 1st pawn   W[1] 2nd pawn   W[2] 3rd pawn
>>   // W[3] = 1st knight W[4] 2nd knight W[5] 3rd knight
>>   // W[6] = 1st bishop W[7] 2nd bishop W[8] 3rd bishop
>>   // W[9] = 1st rook   W[10] 2nd rook   W[11] 3rd rook
>>   // W[12] = 1st queen  W[13] 2nd queen  W[14] 3rd queen
>>   // W[15] = contains always white king
>>
>>Also doable, isn't it?
>>If this is doable ... then you are over 50%!
>>
>>You need also an enpassant field as follows:
>>
>>   if (p.epField == INVAL_FIELD)
>>      sqEnP = 127;  //ep field
>>   else
>>      sqEnP = field2idx64(p.epField
>>
>>If you get this ... then you are almost there.
>>
>>The namilov tables are so that white is always the won with more pieces as
>>black. So then you need to do:
>>
>>   //If black is the "winning" side (more pieces) then we need
>>   //to "invert" the pieces in the lists.
>>
>>   if (iTb > 0) {
>>      if ( p.moveColor == WHITE ) side = 0; else side = 1;
>>      fInvert = 0;
>>      psqW = W;
>>      psqB = B;
>>   }
>>   else {
>>      if ( p.moveColor == WHITE ) side = 1; else side = 0;
>>      fInvert = 1;
>>      psqW = B;
>>      psqB = W;
>>      iTb = -iTb;
>>   }
>>
>>Then you are ready to probe the tablebases....
>>
>>   //now check to see if this particular tablebase for this
>>   //color to move is registered.
>>   if (!FRegistered(iTb, side)) return -1;
>>
>>   ind = PfnIndCalc(iTb, side) (psqW, psqB, sqEnP, fInvert);
>>
>>   //Comment this line out to load all tables in memory?
>>   //FReadTableToMemory (iTb, side, NULL);
>>
>>   //probe the table
>>   tbScore = L_TbtProbeTable (iTb, side, ind);
>>
>>   //if not found
>>   if(tbScore == bev_broken) return -1;
>>
>>   int add = (p.moveColor == BLACK ? 1 : 0);
>>
>>   //now convert to correct MATE range the value
>>   //Nullmover uses
>>   if(tbScore > 0)
>>      return (tbScore-bev_mi1)*2 + 9999 - (ply-1) - add;
>>   if(tbScore < 0)
>>      return (tbScore+bev_mi1)*2 - 9999 + (ply-1) + add;
>>
>>   return 0;
>>}
>>
>>Futher more you need some defines, and function defintions:
>>
>>#define  XX  127
>>#define  C_PIECES  3    /* Maximum # of pieces of one color OTB */
>>#define  TB_FASTCALL  __fastcall
>>
>>typedef unsigned __int64 INDEX;
>>typedef unsigned int squaret;
>>typedef int color;
>>
>>#define bev_broken 32767
>>#define bev_mi1    32766
>>
>>typedef INDEX(TB_FASTCALL * PfnCalcIndex)
>>(squaret *, squaret *, squaret, int fInverse);
>>
>>extern "C"
>>{
>>   int IDescFindFromCounters(int *);
>>   int FRegisteredFun(int, color);
>>   PfnCalcIndex PfnIndCalcFun(int, color);
>>   int TB_FASTCALL L_TbtProbeTable(int, color, INDEX);
>>   int FTbSetCacheSize(void *, unsigned long);
>>   int IInitializeTb(char *);
>>}
>>
>>#define PfnIndCalc PfnIndCalcFun
>>#define FRegistered FRegisteredFun
>>
>>void *EGTB_cache = (void*)0;
>>
>>int EGTB;
>>
>>Cheers and good luck!
>>
>>Michel
>
>Thanks for your explanations.
>
>If I understand correctly W[0]=1st pawn square when a1=0,b1=1,...h8=63
>sqnp=127 if enpassent capture is illegal.

Correct!

>
>I do not understand the meaning of field2idx64(p.epField)
>I guess that p is for position but I need to know what structure it is and I do
>not know what does field2idx64.

"field_to_idx64" is Michael's array to convert his coordinates (maybe 0x88) to
the Nalimov 64 square coordinates where a1=0 ... h8=63

>
>I understand that I need to switch colors if black has more pieces but I do not
>understand the use of P there.

p.moveColor is Michael's side-to-move flag.

Movei probably uses a global variable called 'side'. If that is true then you
must rename the locally declared 'side' variable to something else like
'side_to_move'. Then you can use something like this...

if (iTb > 0) {
   side_to_move = side;
   fInvert = 0;
   psqW    = W;
   psqB    = B;
}
else {
   side_to_move = side ^ 1;   // assuming side is either 0 or 1, (LIGHT or DARK)
   fInvert = 1;
   psqW    = B;
   psqB    = W;
   iTb     = -iTb;
}

if (!FRegistered(iTb, side_to_move)) {
   return -1;
}

etc etc...

>
>I can get the side to move based on the internal structure of movei without some
>external p and if it is not needed for the nalimov tablebases but only internal
>structure in nullmover then it is not clear from the comments.
>

Yes, that's right.

Cheers,

Ross



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.