Author: Tom Likens
Date: 14:23:10 07/11/03
Go up one level in this thread
Grzegorz, I've interspersed some comments below. Note, some of my comments are just questions and others are assumptions to clarify (at least for me) what the code is doing. Please, feel free to correct any erroneous assumptions on my part ;) On July 11, 2003 at 10:26:38, Grzegorz Sidorowicz wrote: [-snip-] >No problem! >My code is probably very unreadeble but I think for >famous people from this forum it is not big problem ;-) >(i will answer on every question) >Below are parts my original code: > >Engine.h file > >//Squares with hash_code >unsigned long pionb[BOARD_SIZE][BOARD_SIZE];//for pown white >unsigned long pionc[BOARD_SIZE][BOARD_SIZE];//for pown black >unsigned long skokb[BOARD_SIZE][BOARD_SIZE];//for knight white >unsigned long skokc[BOARD_SIZE][BOARD_SIZE];//for knight white >. I'm guessing that you are using an X-by-X board representation where BOARD_SIZE == X. >unsigned long glob_troper;// hash_code for current position >unsigned long htb_siz;//transposition table size > >//Transposition table entry >unsigned long *trans_b;//Lock >bool *val_side; //side on move >int *val_gatunek; //flag >int *val_hash; //score >int *val_depth;//height Make sure you are using "height" to store the draft of this position (which is the depth of the search *below* this node) and not the current depth? >int *val_morder;//move index from move generator >BYTE *val_pt; //idx for another good move (for move ordering) >BYTE *val_age;// age of this entry > >Engine.cpp file >body of search function > >//opona it is side if opona == false it is white side > >unsigned long spr_poz=prev_hash; >spr_poz=spr_poz & htb_siz; >int height=0; >height=val_depth[spr_poz]; >if (val_gatunek[spr_poz] && val_side[spr_poz]==(bool)opona) >if (antr && trans_b[spr_poz]==prev_hash) What does "antr" represent? >{ > int myd=myord=val_morder[spr_poz]; > BYTE tstt=val_pt[spr_poz]; > another_good=tstt; > int wrpx=val_hash[spr_poz]; > if (height>=level-2 && wrpx<beta && val_gatunek[spr_poz]==UBOUND) ^^^^^^^^^^^^^^^ I wasn't sure what this was doing, it seems suspicious. > { > do_null=false; > } > else > if (val_age[spr_poz]==m_cur_age) > { > if (height>=level) Again, is "level" the current draft? > { > switch(val_gatunek[spr_poz]) > { > case VALID: > if (antr>1) > ans_hash[antr].sx=-1; > return wrpx; > break; > case LBOUND: > if (wrpx>= beta) > { > if (antr>1) > ans_hash[antr].sx=-1; > return beta; > } > myord=val_morder[spr_poz]; > break; > case UBOUND: > if (wrpx <= alpha) > { > if (antr>1) > ans_hash[antr].sx=-1; > return alpha; > } > myord=val_morder[spr_poz]; Are you sure this is correct. Normally, when you fail-low there is no move to store into the hash table. Some programs do store a move for an upper bound node (Yace does it I believe) but the more vanilla hash implementations usually don't. > break; > case NULL_MOVE: > myord=val_morder[spr_poz]; > break; > } > } > else > myord=val_morder[spr_poz]; > } > else > myord=val_morder[spr_poz]; >} > >//myord it is move from TT >. >. >. >. >for(int ct=0;ct<lcr;ct++) >{ > int crm=tb_sort[antr][ct]; > int ssx=guns[antr][crm][0]; > int ssy=guns[antr][crm][1]; > int ttx=guns[antr][crm][2]; > int tty=guns[antr][crm][3]; > if ((ssx || ssy || ttx || tty) && (bestvalue<beta || (level==depth && !antr))) > { > MakeMove(...); > unsigned long fr_hash=NewTT(prev_hash, kopas,kopat,ssx,ssy,ttx,tty,opona); > //fr_hash it is hashcode for position after current move > //kopas - source square value, kopat - target square value > Search(...) > . > . > . > UndoMove(...); > } > else > break; >} > >. >. >. >. >if (level>=height || m_cur_age!=val_age[spr_poz]) >{ > if (!null_acitve) > { > if (bestvalue>=beta) > val_gatunek[spr_poz]=LBOUND; > else > if (bestvalue<=s_alpha) > val_gatunek[spr_poz]=UBOUND; > else > val_gatunek[spr_poz]=VALID; > } > else > val_gatunek[spr_poz]=NULL_MOVE; > > val_side[spr_poz]=opona; > val_morder[spr_poz]=myord; Is this the best move found by the search? Again if this is an upper bound position then there is (probably) no best move to store. > val_hash[spr_poz]=bestvalue; > val_depth[spr_poz]=level; > if (prev_myord!=myord && prev_myord!=-1) > val_pt[spr_poz]=prev_myord; > else > val_pt[spr_poz]=0; > trans_b[spr_poz]=prev_hash; > val_age[spr_poz]=m_cur_age; >} > >Body for NewTT function > >unsigned long CEngine::NewTT(unsigned long last_TT, int kopas, int kopat, int >sx, int sy, int tx, int ty, bool opona) >{ > unsigned long zwrot; > switch(kopas) > { > case WHITE_ROOK: > zwrot = last_TT xor wiezb[sx][sy] xor wiezb[tx][ty]; > break; > case WHITE_KNIGHT: > zwrot = last_TT xor skokb[sx][sy] xor skokb[tx][ty]; > break; > . > . > } > > if (kopat) > { > switch(kopat) > { > case WHITE_ROOK: > zwrot = zwrot xor wiezb[tx][ty]; > break; > case WHITE_KNIGHT: > zwrot = zwrot xor skokb[tx][ty]; > break; > } > . > . > } > return zwrot; >} I probably haven't solved your problem but of course these things are insidious. Also I could easily be misinterpreting some of your code, if so I apologize. Some general advice, you probably should convert to 64-bit hash keys to reduce the chance of collisions. If you don't already have it I would write a routine that generates the hash key for the current position from scratch. It should always match your current dynamic hash key. If you make it a debug option, enabled either when you compile or at the command line, then you will be able to utilize it in the future when other nasty hashing bugs make their appearance. good luck, --tom
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.