diff --git a/CuckooChessEngine/src/chess/ComputerPlayer.java b/CuckooChessEngine/src/chess/ComputerPlayer.java index cdc7533..91977cd 100644 --- a/CuckooChessEngine/src/chess/ComputerPlayer.java +++ b/CuckooChessEngine/src/chess/ComputerPlayer.java @@ -30,7 +30,7 @@ public class ComputerPlayer implements Player { public static final String engineName; static { - String name = "CuckooChess 1.13a6"; + String name = "CuckooChess 1.13a7"; String m = System.getProperty("sun.arch.data.model"); if ("32".equals(m)) name += " 32-bit"; diff --git a/CuckooChessEngine/src/chess/Search.java b/CuckooChessEngine/src/chess/Search.java index cd08c40..04d39e8 100644 --- a/CuckooChessEngine/src/chess/Search.java +++ b/CuckooChessEngine/src/chess/Search.java @@ -554,8 +554,15 @@ public class Search { } // Reverse futility pruning - if (!inCheck && (depth < 5*plyScale) && (posExtend == 0)) { - if ((Math.abs(alpha) <= MATE0 / 2) && (Math.abs(beta) <= MATE0 / 2)) { + if (!inCheck && (depth < 5*plyScale) && (posExtend == 0) && + (Math.abs(alpha) <= MATE0 / 2) && (Math.abs(beta) <= MATE0 / 2)) { + boolean mtrlOk; + if (pos.whiteMove) { + mtrlOk = (pos.wMtrl > pos.wMtrlPawns) && (pos.wMtrlPawns > 0); + } else { + mtrlOk = (pos.bMtrl > pos.bMtrlPawns) && (pos.bMtrlPawns > 0); + } + if (mtrlOk) { int margin; if (depth <= plyScale) margin = 204; else if (depth <= 2*plyScale) margin = 420; @@ -615,15 +622,12 @@ public class Search { if ((searchTreeInfo[ply-1].lmr > 0) && (depth < 5*plyScale)) { Move m1 = searchTreeInfo[ply-1].currentMove; Move m2 = searchTreeInfo[ply+1].bestMove; // threat move - if (m1.from != m1.to) { - if ((m1.to == m2.from) || (m1.from == m2.to) || - ((BitBoard.squaresBetween[m2.from][m2.to] & (1L << m1.from)) != 0)) { - // if the threat move was made possible by a reduced - // move on the previous ply, the reduction was unsafe. - // Return alpha to trigger a non-reduced re-search. - if (log != null) log.logNodeEnd(sti.nodeIdx, alpha, TTEntry.T_LE, evalScore, hKey); - return alpha; - } + if (relatedMoves(m1, m2)) { + // if the threat move was made possible by a reduced + // move on the previous ply, the reduction was unsafe. + // Return alpha to trigger a non-reduced re-search. + if (log != null) log.logNodeEnd(sti.nodeIdx, alpha, TTEntry.T_LE, evalScore, hKey); + return alpha; } } } @@ -844,6 +848,16 @@ public class Search { return bestScore; } + /** Return true if move m2 was made possible by move m1. */ + private final boolean relatedMoves(Move m1, Move m2) { + if ((m1.from == m1.to) || (m2.from == m2.to)) + return false; + if ((m1.to == m2.from) || (m1.from == m2.to) || + ((BitBoard.squaresBetween[m2.from][m2.to] & (1L << m1.from)) != 0)) + return true; + return false; + } + /** Return true if move should be skipped in order to make engine play weaker. */ private final boolean weakPlaySkipMove(Position pos, Move m, int ply) { long rndL = pos.zobristHash() ^ Position.psHashKeys[0][m.from] ^ diff --git a/CuckooChessEngine/test/chess/SearchTest.java b/CuckooChessEngine/test/chess/SearchTest.java index 8ebf112..2c4bfc3 100644 --- a/CuckooChessEngine/test/chess/SearchTest.java +++ b/CuckooChessEngine/test/chess/SearchTest.java @@ -83,7 +83,7 @@ public class SearchTest { sc = new Search(pos, nullHist, 0, tt); score = sc.negaScout(-mate0, mate0, 0, 3*plyScale, -1, MoveGen.inCheck(pos)); assertTrue(Math.abs(score) < 50); // Stale-mate trap - score2 = idSearch(sc, 9).score; + score2 = idSearch(sc, 5).score; assertEquals(score, score2); pos = TextIO.readFEN("8/8/2K5/3QP3/P6P/1q6/8/k7 w - - 31 51");