From acc7029e7c2709dae402ee4d17776214e97ebcbe Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 7 Feb 2017 20:23:12 +0100 Subject: [PATCH] Implement mate killers Moves that force mate aftera check evasion are remembered in a mateKillers table, indexed by the preceding evasion. Such moves are tried in QS as reply to the same evasion. This should make it more difficult to push tsume mates over the horizon by spite checks in a hisshi situation. --- dropper.c | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-) diff --git a/dropper.c b/dropper.c index 87c0d35..155be56 100644 --- a/dropper.c +++ b/dropper.c @@ -71,7 +71,7 @@ int handVal[96], rawGain[97]; unsigned int moveStack[500*MAXPLY]; int killers[MAXPLY][2]; int path[MAXPLY], deprec[MAXPLY]; -int history[1<<16]; +int history[1<<16], mateKillers[1<<17]; unsigned char checkHist[MAXMOVES+MAXPLY]; int repKey[512+20]; @@ -703,7 +703,7 @@ typedef struct { unsigned char fromSqr, toSqr, captSqr, epSqr, rookSqr, rights; signed char fromPiece, toPiece, victim, savePiece, rook, mutation; int pstEval, newEval, bulk; - int move, depth; + int move, wholeMove, depth; int checker, checkDir, checkDist, xking; } StackFrame; @@ -1019,6 +1019,7 @@ MakeMove (StackFrame *f, int move) int to, stm; f->fromSqr = move >> 8 & 255; to = move & 255; + f->wholeMove = move; f->toSqr = f->captSqr = toDecode[to]; // real to-square for to-encoded special moves f->fromPiece = board[f->fromSqr]; // occupant or (for drops) complemented holdings count if(f->checker != CK_NONE && NonEvade(f)) return 0; // abort if move did not evade existing check @@ -1213,6 +1214,12 @@ if(hashMove && board[hashMove>>8&255] == 0) {char s[100];sprintf(s,"bad hash mov } 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(ff->checker != CK_NONE) { // last move was evasion; see if we have counter move + int move = mateKillers[(ff->wholeMove & 0xFFFF) + (stm - WHITE << 11)]; + if(move && (move>>16 & 0xFF) == f.xking && (move>>24 & 0xFF) == board[toDecode[move & 0xFF]] && PseudoLegal(stm, move)) { // counter move is pseudo-legal and matches position + moveStack[moveSP++] = moveStack[m.nonCapts]; moveStack[m.nonCapts] = move & 0xFFFF; m.late = ++m.nonCapts; // make room and put with captures (lowest sort key) + } + } do { // IID loop int curMove, highDepth; @@ -1315,6 +1322,8 @@ printf("%d:%d:%d %2d. %08x %c%d%c%d %6d %6d %6d\n",ply,depth,iterDepth,curMove,m int *tail; alpha = score; bestNr = curMove; history[moveStack[curMove] & 0xFFFF] += iterDepth*iterDepth; + if(score > INF-100 && curMove >= m.nonCapts) + mateKillers[(ff->wholeMove & 0xFFFF) + (stm - WHITE << 11)] = moveStack[curMove] & 0xFFFF | f.xking << 16 | board[f.toSqr] << 24; // store mate killers if(score >= beta) { // beta cutoff if(curMove >= m.nonCapts && moveStack[curMove] != killers[ply][1]) killers[ply][0] = killers[ply][1], killers[ply][1] = moveStack[curMove]; @@ -1730,6 +1739,7 @@ main () nodeCount = forceMove = undoInfo.move = abortFlag = 0; ReadClock(1); for(i=0;i<1<<16;i++) history[i] = 0; //>>= 1; + for(i=0;i<1<<17;i++) mateKillers[i] = 0; score = Search(stm^COLOR, -INF, INF, &undoInfo, maxDepth, 0, maxDepth); if(!undoInfo.move) { // no move, game apparently ended -- 1.7.0.4