#define C_DISTANT 0xFF00
#define C_CONTACT 0x00FF
+#define REPLEN 20
+#define REPKEY ~(-1 << REPLEN)
+
typedef long long int Key;
int ply, nodeCount, forceMove, choice, rootMove, lastGameMove, rootScore, abortFlag, postThinking=1; // some frequently used data
for(i=0; *ip >= 0; i++) pieceValues[WHITE+i] = pieceValues[BLACK+i] = *ip++; // basic
for(i=16,ip++; *ip >= 0; i++) pieceValues[WHITE+i] = pieceValues[BLACK+i] = *ip++; // promoted
for(i=0, ip++; *ip >= 0; i++) handVal[WHITE+i] = handVal[BLACK+i] = *ip++; // in hand
- pawn = 2*handVal[WHITE] << 20; // used for detection of material-loosing loop
- queen = v ? 0 : 2*handVal[WHITE+4] << 20; // losing two Queens overflows
+ pawn = 2*handVal[WHITE] << REPLEN; // used for detection of material-loosing loop
+ queen = v ? 0 : 2*handVal[WHITE+4] << REPLEN; // losing two Queens overflows
for(i=0; i<16; i++) {
int demoted = dropType[handSlot[WHITE+i+16]]-1; // piece type after demotion (could be Pawn, in Chess)
handVal[WHITE+i+16] = handVal[BLACK+i+16] = pieceValues[WHITE+i+16] + handVal[demoted]; // gain by capturing promoted piece
// repetition checking
int index = (unsigned int)f.newKey >> 24 ^ stm << 2; // uses high byte of low (= hands-free) key
- while(repKey[index] && (repKey[index] ^ (int)f.newKey) & 0xFFFFF) index++;
+ while(repKey[index] && (repKey[index] ^ (int)f.newKey) & REPKEY) index++;
int oldRepKey = repKey[index], oldRepDep = repDep[index];
if(oldRepKey && ff->mutation != -2) { // key present in table: (quasi-)repetition
- int gain = (f.newEval << 20) - (repKey[index] & 0xFFF00000);
+ int gain = (f.newEval << REPLEN) - (repKey[index] & ~REPKEY);
if(gain == 0) { // true repeat
score = 0;
if(perpLoses) { // repetitions not always draw
}
}
- else if(gain == pawn || gain == queen || gain >= (400<<20)) score = INF-1; // quasi-repeat with extra piece in hand
- else if(gain == -pawn || gain == -queen || gain <= (-400<<20)) score = 1-INF; // or with one piece less
+ else if(gain == pawn || gain == queen || gain >= (400<<REPLEN)) score = INF-1; // quasi-repeat with extra piece in hand
+ else if(gain == -pawn || gain == -queen || gain <= (-400<<REPLEN)) score = 1-INF; // or with one piece less
else goto search;// traded one hand piece for another; could still lead somewhere
f.lim = score; f.depth = (score >= beta ? highDepth+1 : iterDepth); // minimum required depth
*pvPtr = 0; // fake that daughter returned empty PV
lmr = (curMove >= m.late) + (curMove >= m.drops);
f.tpGain = f.newEval + ff->pstEval; // material gain in last two ply
if(ply==0 && randomize && moveNr < 10) ran = (alpha > INF-100 || alpha <-INF+100 ? 0 : (f.newKey*ranKey>>24 & 31)- 16);
- repKey[index] = (int)f.newKey & 0xFFFFF | f.newEval << 20; repDep[index] = ply + moveNr; // remember position
+ repKey[index] = (int)f.newKey & REPKEY | f.newEval << REPLEN; repDep[index] = ply + moveNr; // remember position
// recursion
deprec[ply] = (f.checker != CK_NONE ? f.checker : 0)<<24 | maxDepth<<16 | depth<< 8 | iterDepth; path[ply++] = moveStack[curMove] & 0xFFFF;
score = -Search(stm, -beta, -alpha+ran, &f, iterDepth-1, lmr, highDepth);
// store in game history hash table
index = (unsigned int)undoInfo.newKey >> 24 ^ stm << 2; // uses high byte of low (= hands-free) key
while(repKey[index] && (repKey[index] ^ (int)undoInfo.newKey) & 0xFFFFF) index++; // find empty slot
- repKey[index] = (int)undoInfo.newKey & 0xFFFFF | undoInfo.newEval << 20; // remember position
+ repKey[index] = (int)undoInfo.newKey & REPKEY | undoInfo.newEval << REPLEN; // remember position
repDep[index] = moveNr;
stm ^= COLOR; moveNr++;
return 1;