Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: question about implementing tablebases

Author: Uri Blass

Date: 14:49:32 12/11/04

Go up one level in this thread


On December 11, 2004 at 17:11:38, Michel Langeveld wrote:

>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.
>>
>>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.
>
>field2idx64 converts my internal Nullmover fieldnumber to the Namilov format. .
>In Nullmover A1 is 21 and in Namilov 0.
>
>I use this for it:
>
>#define field2idx64(f) (((f-21)/10)*8 + ((f-21)%10))
>
>So that's what this "function" does.
>
>>I understand that I need to switch colors if black has more pieces but I do not
>>understand the use of P there.
>
>p is a global struct in Nullmover where p.moveColor is the side to move.
>As ross wrote your variable is probably called side or something similiar.
>
>>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, I forgot to tell you. P is the struct with a lot of variables.
>p.moveColor
>p.dynHash
>p.pieceCount
>p.materialWhite
>p.materialBlack
>etc
>
>Feel free to ask more questions if necesarry.
>There is also a conversion done from the namilov score, to the internal
>nullmover scores. (-9999, 9999).
>
>>Uri
>
>In Nullmover I look all positions <= EGTB into namilov tablebases.
>This is probably not smartest you can do ....
>
>because probing tablebases cost a lot of speed ... it cost so much ... that
>finally you end up with 10knps or so ... and loose games with it. I lost games
>in Leiden because of this.
>
>Dieter calculated that the difference between using egtb's and don't is 0 elo.
>Maybe if you only probe the root position, then you gain some elo .... who
>knows.
>
>And if you play against a program that doesn't use tablebases or a human you try
>to swindle.
>
>#ifdef TABLEBASES
>   if ( p.pieceCount <= EGTB )
>   {
>      tbProbes++;
>      int score = probe_tb();
>      if ( score != -1 )
>      {
>         tbHits++;
>         return score;
>      }
>   }
>#endif
>
>I am curious what kind of positions you will skip probing although you have the
>namilov tablebases of them. I think that some programs maybe probe all positions
>where:
>
>current_depth < depth_to_go / 2
>
>I am not sure...
>
>Michel

I think that I will be very careful about probing.
I guess that the main use of the tablebases will be for debugging.

I also think not to return the exact score from the tablebases but something
else in the following cases:
1)mate in more than 50 moves that may be no mate thanks to the 50 move rule.
2)draw but the opponent may blunder so it may be better to have a positive
score.

Uri



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.