int killers[MAXPLY][2];
int path[MAXPLY], deprec[MAXPLY];
int history[1<<16], mateKillers[1<<17];
+int anaSP;
unsigned char checkHist[MAXMOVES+MAXPLY];
int repKey[512+20];
Search (int stm, int alpha, int beta, StackFrame *ff, int depth, int reduction, int maxDepth)
{
MoveStack m; StackFrame f; HashEntry *entry;
- int oldSP = moveSP, *pvStart = pvPtr, oldLimit = depthLimit;
+ int oldSP = moveSP, *pvStart = pvPtr, oldLimit = depthLimit, oldAna;
int killer1 = killers[ply][0], killer2 = killers[ply][1], hashMove;
int bestNr, bestScore, startAlpha, startScore, resultDepth, iterDepth=0, originalReduction = reduction;
int hit, hashKeyH, ran=0, ipMask=0;
- int curEval, score;
+ int curEval, anaEval, score;
// legality
int earlyGen = (ff->toPiece == stm+31); // King was moved
depth -= reduction;
} else reduction = originalReduction = 0;
checkHist[moveNr+ply+1] = f.checker;
+ oldAna = anaSP; anaSP += (ff->checker != CK_NONE); // node after evasion: accept new analogy
+ anaEval = curEval;
+
// stand pat or null move
startAlpha = alpha; startScore = -INF;
if(depth <= 0) { // QS
- int anaEval = curEval;
if(ff->checker != CK_NONE && ff->tpGain > 0) anaEval = 50-INF; // forbid stand pat if horizon check tossed material
if(anaEval > alpha) {
if(anaEval >= beta) { ff->depth = 1; moveSP = oldSP; return anaEval; } // stand-pat cutoff
if(maxDepth <= 0) {
if(board[toDecode[hashMove&255]] == 0) hashMove = 0;
#ifdef IDQS
- if(ply >= depthLimit) { ff->depth = 1; moveSP = oldSP; return curEval + 150; } // hit depth limit; give hefty stm bonus
+ if(ply >= depthLimit) { ff->depth = 1; moveSP = oldSP; anaSP = oldAna; return anaEval + 150; } // hit depth limit; give hefty stm bonus
if(depthLimit == MAXPLY) depthLimit = ply+10; // we just entered pure QS; set up depth limit
#endif
}
deprec[ply] = maxDepth << 16 | depth << 8; path[ply++] = 0;
score = -Search(stm, -beta, 1-beta, &f, nullDepth, 0, nullDepth);
ply--;
- if(score >= beta) { ff->depth = f.depth + originalReduction + 3; moveSP = oldSP; return beta + 1; }
+ if(score >= beta) { ff->depth = f.depth + originalReduction + 3; moveSP = oldSP; anaSP = oldAna; return beta + 1; }
}
// move generation
bonus += bonus >> 1;
int newEval = curEval + bonus;
if(newEval > alpha) {
- if(newEval >= beta) { ff->depth = 1; moveSP = oldSP; depthLimit = oldLimit; return newEval; } // stand-pat cutoff
+ if(newEval >= beta) { ff->depth = 1; moveSP = oldSP; depthLimit = oldLimit; anaSP = oldAna; return newEval; } // stand-pat cutoff
alpha = startScore = newEval; maxDepth = 0; // we will not fail low, so no extra iterations
}
}
printf("%d:%d:%d %2d. %08x %c%d%c%d %6d %6d %6d\n",ply,depth,iterDepth,curMove,m,(m>>8&255)%22+'a',(m>>8&255)/22+1,toDecode[m&255]%22+'a',toDecode[m&255]/22+1,f.pstEval,score,bestScore);
}
- if(abortFlag) { moveSP = oldSP; depthLimit = oldLimit; return -INF; }
+ if(abortFlag) { moveSP = oldSP; depthLimit = oldLimit; anaSP = oldAna; return -INF; }
// minimaxing
if(f.depth < resultDepth) resultDepth = f.depth;
if(PATH || f.hashKey == 0x1348708590)printf("%d:%d Hash store %16llx, d=%d, checker=%x move=%s\n",ply,depth,f.hashKey,resultDepth,entry->checker,MoveToText(entry->move));
// return results
- moveSP = oldSP; pvPtr = pvStart; depthLimit = oldLimit;
+ moveSP = oldSP; anaSP = oldAna; pvPtr = pvStart; depthLimit = oldLimit;
ff->depth = resultDepth + 1 + originalReduction; // report valid depth as seen from parent
return bestScore;
}