From: H.G.Muller Date: Sat, 14 Jan 2017 17:50:56 +0000 (+0100) Subject: Prune futile interpositions at d <= 1 X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=24586b6e9baa5041b757ef47e720f06517b9859f;p=crazywa.git Prune futile interpositions at d <= 1 A variable ipMask records squares attacked by board moves along the check ray, immediately after move generation. Evasion drops are then limited only to such squares, at depth <= 1. --- diff --git a/dropper.c b/dropper.c index e5883d2..825e6b9 100644 --- a/dropper.c +++ b/dropper.c @@ -851,11 +851,12 @@ CheckDrops (int stm, int king) } 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 @@ -945,6 +946,14 @@ Pinned (int stm, int fromSqr, int xking) } 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) @@ -1043,7 +1052,7 @@ Search (int stm, int alpha, int beta, StackFrame *ff, int depth, int reduction, 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 @@ -1108,8 +1117,10 @@ if(hashMove && board[hashMove>>8&255] == 0) {char s[100];sprintf(s,"bad hash mov // 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; @@ -1138,6 +1149,7 @@ if(PATH)printf("%d:%d {%d,%d} max=%d eval=%d check=%02x,%d,%d\n",ply,depth,alp 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 @@ -1175,7 +1187,7 @@ if(PATH)printf("%d:%d:%d new iter moveStack[%d..%d]\n",ply,depth,iterDepth,m.fir 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; }