}
void
-EvasionDrops (int stm, StackFrame *f)
+EvasionDrops (int stm, StackFrame *f, int mask)
{
int i, x = f->checker, v = f->checkDir, s = stm ^ COLOR;
while(board[x+=v] == 0) { // all squares on check ray
int last = maxDrop;
+ if((mask >>= 1) & 1) continue; // suppress 'futile interpositions'
i = zoneTab[x] & Z_LAST; // Pawn not on first & last rank (OK for zh)
if(perpLoses) { // but it is Shogi!
if(!(zoneTab[x] & stm)) i = 0; // outside zone, so dropping is always allowed
}
int
+SafeIP (StackFrame *f)
+{ // figure out which squares are protected on the check ray
+ int result = 0, v = f->checkDir, x = f->checker, mask = 1;
+ while(board[x+=v] == 0) result |= (mask <<= 1)*(attackKey != attacks[x]);
+ return result & ~mask;
+}
+
+int
NonEvade (StackFrame *f)
{
if((f->fromPiece & ~COLOR) != 31) { // moves non-royal (or drops)
int oldSP = moveSP, *pvStart = pvPtr;
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;
+ int hit, hashKeyH, ran=0, ipMask=0;
int curEval, score;
// legality
// check test
if(f.checker == CK_UNKNOWN) CheckTest(stm, ff, &f); // test for check if hash did not supply it
- if(f.checker != CK_NONE) depth++, maxDepth++, reduction = originalReduction = 0; // extend check evasions
- else if(depth > 3) {
+ if(f.checker != CK_NONE) {
+ depth++, maxDepth++, reduction = originalReduction = 0 /*, killers[ply][2] = -1*/; // extend check evasions
+ if(earlyGen && f.checkDist && maxDepth <= 1) ipMask = SafeIP(&f);
+ } else if(depth > 3) {
if(depth - reduction < 3) reduction = depth - 3; // never reduce to below 3 ply
depth -= reduction;
} else reduction = originalReduction = 0;
if(MoveGen(stm, &m, f.rights)) { // impossible (except for hash collision giving wrong in-check status)
Dump("King capture");
}
+ if(f.checkDist && maxDepth <= 1) ipMask = SafeIP(&f);
}
if(hashMove) moveStack[--m.firstMove] = hashMove; // put hash move in front of list (duplicat!)
if(f.checker != CK_NONE) moveSP = m.drops = m.castlings; // clip off castlings when in check
if(f.checker != CK_NONE) {
m.stage |= 4; // when in check we stop after evasion drops
if(f.checkDist == 0) continue; // but there cannot be any for contact/double checks
- EvasionDrops(stm, &f);
+ EvasionDrops(stm, &f, ipMask); // at d <= 1 suppress futile interpositions
if(moveSP <= curMove) continue; // no avail
m.stage = 3; break;
}