Author: Dann Corbit
Date: 15:49:08 07/11/01
Go up one level in this thread
On July 11, 2001 at 18:35:48, Dan Homan wrote: >On July 11, 2001 at 16:37:38, Dann Corbit wrote: > >>On July 11, 2001 at 16:16:29, Artem Pyatakov wrote: >> >>>I was just in the process of making my own program hash, and I was looking at >>>the Gerbil 01 source code for some guidance, but I noticed something strange. >>> >>>Does Gerbil at this point NOT hash En Passant squares? >>>Am I correctly thinking that this information should be hashed? >> >>Gerbil has the smartest e.p. hashing of any program I have ever seen. I intend >>to brashly copy it, as soon as I find the time. >> >>Gerbil hashes ONLY those e.p. information points where the pawn can *actually* >>be taken which is just plain brilliant. It will result in a lot more hash hits >>for no apparent penalty. >> >>An example of the genius of Bruce Moreland. > >I think this idea has been around for a while... although I might just think so >because Bruce Moreland mentioned it somewhere else... One wrinkle is that I >thought most programs did this in their make-move routine (which, of course, >updates the hash signature of a position). I am surprised that it would be a >bigger savings to do this when actually retrieving or storing the hash entry, >but I haven't looked at Gerbil's code yet (it is on my todo list), so I don't >know. Reading Bruce's code is fun. His comments read like a novel. That's where Bruce does it too [in makemove]. The e.p. part is variable isqEnP: void VMakeMove(PCON pcon, PSTE pste, PCM pcm) { PSQ psqFrom; PSQ psqTo; (pste + 1)->isqEnP = isqNIL; // By default, no en-passant square. #ifdef NULL_MOVE (pste + 1)->fNull = fFALSE; // By default, null-move is allowed. #endif (pste + 1)->cf = pste->cf & // Some castling flags might get turned s_argcf[pcm->isqFrom] & // off if I'm moving a king or rook. s_argcf[pcm->isqTo]; // // Initialize various values for the next ply. // (pste + 1)->plyFifty = pste->plyFifty + 1; (pste + 1)->hashkPc = HashkSwitch(pste->hashkPc); (pste + 1)->hashkPn = pste->hashkPn; (pste + 1)->valPcUs = pste->valPcThem; (pste + 1)->valPcThem = pste->valPcUs; (pste + 1)->valPnUs = pste->valPnThem; (pste + 1)->valPnThem = pste->valPnUs; // // This section handles cleaning up a captured piece. The nastiest stuff // is in the en-passant section. // psqTo = &pcon->argsq[pcm->isqTo]; if (pcm->cmf & cmfCAPTURE) { int isqTook; if (pcm->cmf & cmfMAKE_ENP) { // This is gross. Assert(pste->isqEnP != isqNIL); isqTook = pste->isqEnP + ((pste->coUs == coWHITE) ? -filIBD : filIBD); pste->ppiTook = pcon->argsq[isqTook].ppi; Assert(pste->ppiTook != NULL); Assert(pste->ppiTook->pc == pcPAWN); Assert(pste->ppiTook->co != pste->coUs); pcon->argsq[isqTook].ppi = NULL; } else { isqTook = pcm->isqTo; // This is normal. pste->ppiTook = psqTo->ppi; // This field will be used } // when it's time to unmake. Assert(pste->ppiTook != NULL); pste->ppiTook->fDead = fTRUE; // <-- Mark it dead. (pste + 1)->hashkPc ^= // XOR the piece out of the s_arghashkPc[pste->ppiTook->pc][ // hash key. pste->ppiTook->co][isqTook]; if (pste->ppiTook->pc == pcPAWN) // Remove a captured pawn (pste + 1)->hashkPn ^= // from the pawn hash key. s_arghashkPc[pcPAWN][ pste->ppiTook->co][isqTook]; (pste + 1)->plyFifty = 0; // Capture resets this. (pste + 1)->valPcUs -= s_argvalPcOnly[pste->ppiTook->pc]; (pste + 1)->valPnUs -= s_argvalPnOnly[pste->ppiTook->pc]; } // The next few lines move the piece, and clear out the "from" square, // modify the new hash key, and deal with the fifty-move counter if this // is a pawn move. // psqFrom = &pcon->argsq[pcm->isqFrom]; if (psqFrom->ppi->pc == pcPAWN) (pste + 1)->plyFifty = 0; psqTo->ppi = psqFrom->ppi; psqFrom->ppi = NULL; psqTo->ppi->isq = pcm->isqTo; (pste + 1)->hashkPc ^= s_arghashkPc[psqTo->ppi->pc][ pste->coUs][pcm->isqFrom]; (pste + 1)->hashkPc ^= s_arghashkPc[psqTo->ppi->pc][ pste->coUs][pcm->isqTo]; if (psqTo->ppi->pc == pcPAWN) { (pste + 1)->hashkPn ^= s_arghashkPc[pcPAWN][pste->coUs][pcm->isqFrom]; (pste + 1)->hashkPn ^= s_arghashkPc[pcPAWN][pste->coUs][pcm->isqTo]; } // The rest of the function handles dumb special cases like castling // and promotion and setting the en-passant square behind a two-square // pawn move. // if (pcm->cmf & cmfCASTLE) { int isqRookFrom; int isqRookTo; PSQ psqRookFrom; PSQ psqRookTo; PPI ppiRook; switch (pcm->isqTo) { case isqC1: isqRookFrom = isqA1; isqRookTo = isqD1; break; case isqG1: isqRookFrom = isqH1; isqRookTo = isqF1; break; case isqC8: isqRookFrom = isqA8; isqRookTo = isqD8; break; default: Assert(fFALSE); case isqG8: isqRookFrom = isqH8; isqRookTo = isqF8; break; } psqRookFrom = &pcon->argsq[isqRookFrom]; psqRookTo = &pcon->argsq[isqRookTo]; ppiRook = psqRookFrom->ppi; Assert(ppiRook != NULL); ppiRook->isq = isqRookTo; Assert(psqRookTo->ppi == NULL); psqRookTo->ppi = ppiRook; psqRookFrom->ppi = NULL; (pste + 1)->hashkPc ^= s_arghashkPc[pcROOK][pste->coUs][isqRookFrom]; (pste + 1)->hashkPc ^= s_arghashkPc[pcROOK][pste->coUs][isqRookTo]; } else if (pcm->cmf & cmfPR_MASK) { int pcTo = (int)(pcm->cmf & cmfPR_MASK); psqTo->ppi->pc = pcTo; psqTo->ppi->val = s_argvalPc[pcTo]; (pste + 1)->valPcThem += s_argvalPcOnly[pcTo]; (pste + 1)->valPnThem -= valPAWN; // // Reflect the pawn's promotion in the hash key. // (pste + 1)->hashkPc ^= s_arghashkPc[pcPAWN][pste->coUs][pcm->isqTo]; (pste + 1)->hashkPc ^= s_arghashkPc[pcTo][pste->coUs][pcm->isqTo]; // // In the pawn hash key, the pawn is just XOR'd out -- it's gone. // (pste + 1)->hashkPn ^= s_arghashkPc[pcTo][pste->coUs][pcm->isqTo]; } else if (pcm->cmf & cmfSET_ENP) { int isq; // I'm only going to set the en-passant square if there is a pawn // that could conceivably execute an en-passant capture. // isq = pcm->isqTo; if ((!((isq + 1) & 0x88)) && (pcon->argsq[isq + 1].ppi != NULL) && (pcon->argsq[isq + 1].ppi->pc == pcPAWN) && (pcon->argsq[isq + 1].ppi->co != pste->coUs)) (pste + 1)->isqEnP = isq + ((pste->coUs == coWHITE) ? -filIBD : filIBD); else if ((!((isq - 1) & 0x88)) && (pcon->argsq[isq - 1].ppi != NULL) && (pcon->argsq[isq - 1].ppi->pc == pcPAWN) && (pcon->argsq[isq - 1].ppi->co != pste->coUs)) (pste + 1)->isqEnP = isq + ((pste->coUs == coWHITE) ? -filIBD : filIBD); } }
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.