mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2024-11-23 11:31:33 +01:00
CuckooChess: Back-ported Texel improvements to CuckooChess. +24 ELO against previous version after 1894 games at 60/6 time control.
This commit is contained in:
parent
6861e6d266
commit
ab87bb9ae8
|
@ -20,6 +20,7 @@ package uci;
|
|||
|
||||
import chess.Book;
|
||||
import chess.ComputerPlayer;
|
||||
import chess.History;
|
||||
import chess.Move;
|
||||
import chess.MoveGen;
|
||||
import chess.Parameters;
|
||||
|
@ -51,6 +52,7 @@ public class EngineControl {
|
|||
private final Object threadMutex;
|
||||
Search sc;
|
||||
TranspositionTable tt;
|
||||
History ht;
|
||||
MoveGen moveGen;
|
||||
|
||||
Position pos;
|
||||
|
@ -120,6 +122,7 @@ public class EngineControl {
|
|||
this.os = os;
|
||||
threadMutex = new Object();
|
||||
setupTT();
|
||||
ht = new History();
|
||||
moveGen = new MoveGen();
|
||||
}
|
||||
|
||||
|
@ -163,6 +166,7 @@ public class EngineControl {
|
|||
final public void newGame() {
|
||||
randomSeed = new Random().nextLong();
|
||||
tt.clear();
|
||||
ht.init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -222,7 +226,7 @@ public class EngineControl {
|
|||
final private void startThread(final int minTimeLimit, final int maxTimeLimit,
|
||||
int maxDepth, final int maxNodes) {
|
||||
synchronized (threadMutex) {} // Must not start new search until old search is finished
|
||||
sc = new Search(pos, posHashList, posHashListSize, tt);
|
||||
sc = new Search(pos, posHashList, posHashListSize, tt, ht);
|
||||
sc.timeLimit(minTimeLimit, maxTimeLimit);
|
||||
sc.setListener(new SearchListener(os));
|
||||
sc.setStrength(strength, randomSeed);
|
||||
|
|
|
@ -116,30 +116,30 @@ public class BitBoard {
|
|||
private final static long[][] rTables;
|
||||
private final static long[] rMasks;
|
||||
private final static int[] rBits = { 12, 11, 11, 11, 11, 11, 11, 12,
|
||||
11, 10, 10, 11, 10, 10, 10, 11,
|
||||
11, 10, 10, 10, 10, 10, 10, 11,
|
||||
11, 10, 10, 10, 10, 10, 10, 11,
|
||||
11, 10, 10, 10, 10, 10, 10, 11,
|
||||
11, 10, 10, 10, 10, 10, 10, 11,
|
||||
11, 10, 10, 10, 10, 10, 10, 11,
|
||||
11, 10, 10, 11, 10, 10, 10, 11,
|
||||
10, 9, 9, 9, 9, 9, 10, 10,
|
||||
11, 10, 10, 10, 10, 11, 11, 11 };
|
||||
11, 10, 10, 10, 10, 11, 10, 11 };
|
||||
private final static long[] rMagics = {
|
||||
0x0080011084624000L, 0x1440031000200141L, 0x2080082004801000L, 0x0100040900100020L,
|
||||
0x0200020010200408L, 0x0300010008040002L, 0x040024081000a102L, 0x0080003100054680L,
|
||||
0x1100800040008024L, 0x8440401000200040L, 0x0432001022008044L, 0x0402002200100840L,
|
||||
0x4024808008000400L, 0x100a000410820008L, 0x8042001144020028L, 0x2451000041002082L,
|
||||
0x1080004000200056L, 0xd41010c020004000L, 0x0004410020001104L, 0x0000818050000800L,
|
||||
0x0000050008010010L, 0x0230808002000400L, 0x2000440090022108L, 0x0488020000811044L,
|
||||
0x8000410100208006L, 0x2000a00240100140L, 0x2088802200401600L, 0x0a10100180080082L,
|
||||
0x0000080100110004L, 0x0021002300080400L, 0x8400880400010230L, 0x2001008200004401L,
|
||||
0x0000400022800480L, 0x00200040e2401000L, 0x4004100084802000L, 0x0218800800801002L,
|
||||
0x0420800800800400L, 0x002a000402001008L, 0x0e0b000401008200L, 0x0815908072000401L,
|
||||
0x1840008002498021L, 0x1070122002424000L, 0x1040200100410010L, 0x0600080010008080L,
|
||||
0x0215001008010004L, 0x0000020004008080L, 0x1300021051040018L, 0x0004040040820001L,
|
||||
0x48fffe99fecfaa00L, 0x48fffe99fecfaa00L, 0x497fffadff9c2e00L, 0x613fffddffce9200L,
|
||||
0xffffffe9ffe7ce00L, 0xfffffff5fff3e600L, 0x2000080281100400L, 0x510ffff5f63c96a0L,
|
||||
0xebffffb9ff9fc526L, 0x61fffeddfeedaeaeL, 0x53bfffedffdeb1a2L, 0x127fffb9ffdfb5f6L,
|
||||
0x411fffddffdbf4d6L, 0x0005000208040001L, 0x264038060100d004L, 0x7645fffecbfea79eL,
|
||||
0x19a80065ff2bffffL, 0x3fd80075ffebffffL, 0x4010000df6f6fffeL, 0x0050001faffaffffL,
|
||||
0x0050028004ffffb0L, 0x7f600280089ffff1L, 0x7f5000b0029ffffcL, 0x5b58004848a7fffaL,
|
||||
0x002a90005547ffffL, 0x000050007f13ffffL, 0x007fa0006013ffffL, 0x006a9005656fffffL,
|
||||
0x007f600f600affffL, 0x007ec007e6bfffe2L, 0x007ec003eebffffbL, 0x0071d002382fffdaL,
|
||||
0x009f803000e7fffaL, 0x00680030008bffffL, 0x00606060004f3ffcL, 0x001a00600bff9ffdL,
|
||||
0x000d006005ff9fffL, 0x0001806003005fffL, 0x00000300040bfffaL, 0x000192500065ffeaL,
|
||||
0x00fff112d0006800L, 0x007ff037d000c004L, 0x003fd062001a3ff8L, 0x00087000600e1ffcL,
|
||||
0x000fff0100100804L, 0x0007ff0100080402L, 0x0003ffe0c0060003L, 0x0001ffd53000d300L,
|
||||
0x00fffd3000600061L, 0x007fff7f95900040L, 0x003fff8c00600060L, 0x001ffe2587a01860L,
|
||||
0x000fff3fbf40180cL, 0x0007ffc73f400c06L, 0x0003ff86d2c01405L, 0x0001fffeaa700100L,
|
||||
0x00fffdfdd8005000L, 0x007fff80ebffb000L, 0x003fffdf603f6000L, 0x001fffe050405000L,
|
||||
0x000fff400700c00cL, 0x0007ff6007bf600aL, 0x0003ffeebffec005L, 0x0001fffdf3feb001L,
|
||||
0x00ffff39ff484a00L, 0x007fff3fff486300L, 0x003fff99ffac2e00L, 0x001fff31ff2a6a00L,
|
||||
0x000fff19ff15b600L, 0x0007fff5fff28600L, 0x0003fffddffbfee0L, 0x0001fff5f63c96a0L,
|
||||
0x00ffff5dff65cfb6L, 0x007fffbaffd1c5aeL, 0x003fff71ff6cbceaL, 0x001fffd9ffd4756eL,
|
||||
0x000ffff5fff338e6L, 0x0007fffdfffe24f6L, 0x0003ffef27eebe74L, 0x0001ffff23ff605eL
|
||||
};
|
||||
private final static long[][] bTables;
|
||||
private final static long[] bMasks;
|
||||
|
@ -152,22 +152,22 @@ public class BitBoard {
|
|||
4, 4, 5, 5, 5, 5, 4, 4,
|
||||
5, 4, 5, 5, 5, 5, 4, 5 };
|
||||
private final static long[] bMagics = {
|
||||
0xffedf9fd7cfcffffL, 0xfc0962854a77f576L, 0x9010210041047000L, 0x52242420800c0000L,
|
||||
0x884404220480004aL, 0x0002080248000802L, 0xfc0a66c64a7ef576L, 0x7ffdfdfcbd79ffffL,
|
||||
0xfc0846a64a34fff6L, 0xfc087a874a3cf7f6L, 0x02000888010a2211L, 0x0040044040801808L,
|
||||
0x0880040420000000L, 0x0000084110109000L, 0xfc0864ae59b4ff76L, 0x3c0860af4b35ff76L,
|
||||
0x73c01af56cf4cffbL, 0x41a01cfad64aaffcL, 0x1010000200841104L, 0x802802142a006000L,
|
||||
0x0a02000412020020L, 0x0000800040504030L, 0x7c0c028f5b34ff76L, 0xfc0a028e5ab4df76L,
|
||||
0x0020082044905488L, 0xa572211102080220L, 0x0014020001280300L, 0x0220208058008042L,
|
||||
0x0001010000104016L, 0x0005114028080800L, 0x0202640000848800L, 0x040040900a008421L,
|
||||
0x400e094000600208L, 0x800a100400120890L, 0x0041229001480020L, 0x0000020080880082L,
|
||||
0x0040002020060080L, 0x1819100100c02400L, 0x04112a4082c40400L, 0x0001240130210500L,
|
||||
0xdcefd9b54bfcc09fL, 0xf95ffa765afd602bL, 0x008200222800a410L, 0x0100020102406400L,
|
||||
0x80a8040094000200L, 0x002002006200a041L, 0x43ff9a5cf4ca0c01L, 0x4bffcd8e7c587601L,
|
||||
0xfc0ff2865334f576L, 0xfc0bf6ce5924f576L, 0x0900420442088104L, 0x0062042084040010L,
|
||||
0x01380810220a0240L, 0x0000101002082800L, 0xc3ffb7dc36ca8c89L, 0xc3ff8a54f4ca2c89L,
|
||||
0xfffffcfcfd79edffL, 0xfc0863fccb147576L, 0x0050009040441000L, 0x00139a0000840400L,
|
||||
0x9080000412220a00L, 0x0000002020010a42L, 0xfc087e8e4bb2f736L, 0x43ff9e4ef4ca2c89L,
|
||||
0x0006eff5367ff600L, 0x00345835ba77ff2bL, 0x00145f68a3f5dab6L, 0x003a1863fb56f21dL,
|
||||
0x0012eb6bfe9d93cdL, 0x000d82827f3420d6L, 0x00074bcd9c7fec97L, 0x000034fe99f9ffffL,
|
||||
0x0000746f8d6717f6L, 0x00003acb32e1a3f7L, 0x0000185daf1ffb8aL, 0x00003a1867f17067L,
|
||||
0x0000038ee0ccf92eL, 0x000002a2b7ff926eL, 0x000006c9aa93ff14L, 0x00000399b5e5bf87L,
|
||||
0x00400f342c951ffcL, 0x0020230579ed8ff0L, 0x007b008a0077dbfdL, 0x001d00010c13fd46L,
|
||||
0x00040022031c1ffbL, 0x000fa00fd1cbff79L, 0x000400a4bc9affdfL, 0x000200085e9cffdaL,
|
||||
0x002a14560a3dbfbdL, 0x000a0a157b9eafd1L, 0x00060600fd002ffaL, 0x004006000c009010L,
|
||||
0x001a002042008040L, 0x001a00600fd1ffc0L, 0x000d0ace50bf3f8dL, 0x000183a48434efd1L,
|
||||
0x001fbd7670982a0dL, 0x000fe24301d81a0fL, 0x0007fbf82f040041L, 0x000040c800008200L,
|
||||
0x007fe17018086006L, 0x003b7ddf0ffe1effL, 0x001f92f861df4a0aL, 0x000fd713ad98a289L,
|
||||
0x000fd6aa751e400cL, 0x0007f2a63ae9600cL, 0x0003ff7dfe0e3f00L, 0x000003fd2704ce04L,
|
||||
0x00007fc421601d40L, 0x007fff5f70900120L, 0x003fa66283556403L, 0x001fe31969aec201L,
|
||||
0x0007fdfc18ac14bbL, 0x0003fb96fb568a47L, 0x000003f72ea4954dL, 0x00000003f8dc0383L,
|
||||
0x0000007f3a814490L, 0x00007dc5c9cf62a6L, 0x007f23d3342897acL, 0x003fee36eee1565cL,
|
||||
0x0003ff3e99fcccc7L, 0x000003ecfcfac5feL, 0x00000003f97f7453L, 0x0000000003f8dc03L,
|
||||
0x000000007efa8146L, 0x0000007ed3e2ef60L, 0x00007f47243adcd6L, 0x007fb65afabfb3b5L
|
||||
};
|
||||
|
||||
private static final long createPattern(int i, long mask) {
|
||||
|
@ -306,21 +306,21 @@ public class BitBoard {
|
|||
}
|
||||
|
||||
private static final byte dirTable[] = {
|
||||
-9, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, -7,
|
||||
0, 0, -9, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, -7, 0,
|
||||
0, 0, 0, -9, 0, 0, 0, 0, -8, 0, 0, 0, 0, -7, 0, 0,
|
||||
0, 0, 0, 0, -9, 0, 0, 0, -8, 0, 0, 0, -7, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, -9, 0, 0, -8, 0, 0, -7, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, -9, -17, -8, -15, -7, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, -10, -9, -8, -7, -6, 0, 0, 0, 0, 0,
|
||||
0, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 7, 15, 8, 17, 9, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0,
|
||||
0, 0, 0, 7, 0, 0, 0, 0, 8, 0, 0, 0, 0, 9, 0, 0,
|
||||
0, 0, 7, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 9, 0,
|
||||
0, 7, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9
|
||||
-9, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, -7,
|
||||
0, 0, -9, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, -7, 0,
|
||||
0, 0, 0, -9, 0, 0, 0, 0, -8, 0, 0, 0, 0, -7, 0, 0,
|
||||
0, 0, 0, 0, -9, 0, 0, 0, -8, 0, 0, 0, -7, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, -9, 0, 0, -8, 0, 0, -7, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, -9,-17, -8,-15, -7, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,-10, -9, -8, -7, -6, 0, 0, 0, 0, 0,
|
||||
0, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 7, 15, 8, 17, 9, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0,
|
||||
0, 0, 0, 7, 0, 0, 0, 0, 8, 0, 0, 0, 0, 9, 0, 0,
|
||||
0, 0, 7, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 9, 0,
|
||||
0, 7, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9
|
||||
};
|
||||
|
||||
static public final int getDirection(int from, int to) {
|
||||
|
@ -328,6 +328,29 @@ public class BitBoard {
|
|||
return dirTable[offs];
|
||||
}
|
||||
|
||||
private static final byte distTable[] = {
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
0, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||
0, 7, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 3, 2, 1, 1, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 3, 2, 1, 1, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7,
|
||||
0, 7, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7,
|
||||
0, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||
0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
|
||||
};
|
||||
|
||||
public static final int getDistance(int from, int to) {
|
||||
int offs = to + (to|7) - from - (from|7) + 0x77;
|
||||
return distTable[offs];
|
||||
}
|
||||
|
||||
public static final long southFill(long mask) {
|
||||
mask |= (mask >>> 8);
|
||||
mask |= (mask >>> 16);
|
||||
|
|
|
@ -30,7 +30,7 @@ public class ComputerPlayer implements Player {
|
|||
public static final String engineName;
|
||||
|
||||
static {
|
||||
String name = "CuckooChess 1.13a8";
|
||||
String name = "CuckooChess 1.13a9";
|
||||
String m = System.getProperty("sun.arch.data.model");
|
||||
if ("32".equals(m))
|
||||
name += " 32-bit";
|
||||
|
@ -80,7 +80,8 @@ public class ComputerPlayer implements Player {
|
|||
posHashList[posHashListSize++] = p.zobristHash();
|
||||
}
|
||||
tt.nextGeneration();
|
||||
Search sc = new Search(pos, posHashList, posHashListSize, tt);
|
||||
History ht = new History();
|
||||
Search sc = new Search(pos, posHashList, posHashListSize, tt, ht);
|
||||
|
||||
// Determine all legal moves
|
||||
MoveGen.MoveList moves = new MoveGen().pseudoLegalMoves(pos);
|
||||
|
@ -186,7 +187,8 @@ public class ComputerPlayer implements Player {
|
|||
// Create a search object
|
||||
long[] posHashList = new long[200];
|
||||
tt.nextGeneration();
|
||||
Search sc = new Search(pos, posHashList, 0, tt);
|
||||
History ht = new History();
|
||||
Search sc = new Search(pos, posHashList, 0, tt, ht);
|
||||
|
||||
// Determine all legal moves
|
||||
MoveGen.MoveList moves = new MoveGen().pseudoLegalMoves(pos);
|
||||
|
|
|
@ -484,61 +484,88 @@ public class Evaluate {
|
|||
score -= interpolate(pos.wMtrl - pos.wMtrlPawns, 0, 2 * phd.passedBonusB, hiMtrl, phd.passedBonusB);
|
||||
|
||||
// Passed pawns are more dangerous if enemy king is far away
|
||||
int mtrlNoPawns;
|
||||
final int highMtrl = qV + rV;
|
||||
int bestWPawnDist = 8;
|
||||
int bestWPromSq = -1;
|
||||
long m = phd.passedPawnsW;
|
||||
if (m != 0) {
|
||||
mtrlNoPawns = pos.bMtrl - pos.bMtrlPawns;
|
||||
if (mtrlNoPawns < highMtrl) {
|
||||
int mtrlNoPawns = pos.bMtrl - pos.bMtrlPawns;
|
||||
if (mtrlNoPawns < hiMtrl) {
|
||||
int kingPos = pos.getKingSq(false);
|
||||
int kingX = Position.getX(kingPos);
|
||||
int kingY = Position.getY(kingPos);
|
||||
while (m != 0) {
|
||||
int sq = BitBoard.numberOfTrailingZeros(m);
|
||||
int x = Position.getX(sq);
|
||||
int y = Position.getY(sq);
|
||||
int pawnDist = Math.min(5, 7 - y);
|
||||
int kingDistX = Math.abs(kingX - x);
|
||||
int kingDistY = Math.abs(kingY - 7);
|
||||
int kingDist = Math.max(kingDistX, kingDistY);
|
||||
int kingDist = BitBoard.getDistance(kingPos, Position.getSquare(x, 7));
|
||||
int kScore = kingDist * 4;
|
||||
if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist);
|
||||
score += interpolate(mtrlNoPawns, 0, kScore, highMtrl, 0);
|
||||
score += interpolate(mtrlNoPawns, 0, kScore, hiMtrl, 0);
|
||||
if (!pos.whiteMove)
|
||||
kingDist--;
|
||||
if ((pawnDist < kingDist) && (mtrlNoPawns == 0))
|
||||
score += 500; // King can't stop pawn
|
||||
if ((pawnDist < kingDist) && (mtrlNoPawns == 0)) {
|
||||
if ((BitBoard.northFill(1L<<sq) & (1L << pos.getKingSq(true))) != 0)
|
||||
pawnDist++; // Own king blocking pawn
|
||||
if (pawnDist < bestWPawnDist) {
|
||||
bestWPawnDist = pawnDist;
|
||||
bestWPromSq = Position.getSquare(x, 7);
|
||||
}
|
||||
}
|
||||
m &= m-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
int bestBPawnDist = 8;
|
||||
int bestBPromSq = -1;
|
||||
m = phd.passedPawnsB;
|
||||
if (m != 0) {
|
||||
mtrlNoPawns = pos.wMtrl - pos.wMtrlPawns;
|
||||
if (mtrlNoPawns < highMtrl) {
|
||||
int mtrlNoPawns = pos.wMtrl - pos.wMtrlPawns;
|
||||
if (mtrlNoPawns < hiMtrl) {
|
||||
int kingPos = pos.getKingSq(true);
|
||||
int kingX = Position.getX(kingPos);
|
||||
int kingY = Position.getY(kingPos);
|
||||
while (m != 0) {
|
||||
int sq = BitBoard.numberOfTrailingZeros(m);
|
||||
int x = Position.getX(sq);
|
||||
int y = Position.getY(sq);
|
||||
int pawnDist = Math.min(5, y);
|
||||
int kingDistX = Math.abs(kingX - x);
|
||||
int kingDistY = Math.abs(kingY - 0);
|
||||
int kingDist = Math.max(kingDistX, kingDistY);
|
||||
int kingDist = BitBoard.getDistance(kingPos, Position.getSquare(x, 0));
|
||||
int kScore = kingDist * 4;
|
||||
if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist);
|
||||
score -= interpolate(mtrlNoPawns, 0, kScore, highMtrl, 0);
|
||||
score -= interpolate(mtrlNoPawns, 0, kScore, hiMtrl, 0);
|
||||
if (pos.whiteMove)
|
||||
kingDist--;
|
||||
if ((pawnDist < kingDist) && (mtrlNoPawns == 0))
|
||||
score -= 500; // King can't stop pawn
|
||||
if ((pawnDist < kingDist) && (mtrlNoPawns == 0)) {
|
||||
if ((BitBoard.southFill(1L<<sq) & (1L << pos.getKingSq(false))) != 0)
|
||||
pawnDist++; // Own king blocking pawn
|
||||
if (pawnDist < bestBPawnDist) {
|
||||
bestBPawnDist = pawnDist;
|
||||
bestBPromSq = Position.getSquare(x, 0);
|
||||
}
|
||||
}
|
||||
m &= m-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate pawn races in pawn end games
|
||||
if (bestWPromSq >= 0) {
|
||||
if (bestBPromSq >= 0) {
|
||||
int wPly = bestWPawnDist * 2; if (pos.whiteMove) wPly--;
|
||||
int bPly = bestBPawnDist * 2; if (!pos.whiteMove) bPly--;
|
||||
if (wPly < bPly - 1) {
|
||||
score += 500;
|
||||
} else if (wPly == bPly - 1) {
|
||||
if (BitBoard.getDirection(bestWPromSq, pos.getKingSq(false)) != 0)
|
||||
score += 500;
|
||||
} else if (wPly == bPly + 1) {
|
||||
if (BitBoard.getDirection(bestBPromSq, pos.getKingSq(true)) != 0)
|
||||
score -= 500;
|
||||
} else {
|
||||
score -= 500;
|
||||
}
|
||||
} else
|
||||
score += 500;
|
||||
} else if (bestBPromSq >= 0)
|
||||
score -= 500;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
|
@ -585,7 +612,7 @@ public class Evaluate {
|
|||
|
||||
// Evaluate passed pawn bonus, white
|
||||
long passedPawnsW = wPawns & ~BitBoard.southFill(bPawns | bPawnAttacks | (wPawns >>> 8));
|
||||
final int[] ppBonus = {-1,24,26,30,36,47,64,-1};
|
||||
final int[] ppBonus = {-1,24,26,30,36,55,100,-1};
|
||||
int passedBonusW = 0;
|
||||
if (passedPawnsW != 0) {
|
||||
long guardedPassedW = passedPawnsW & (((wPawns & BitBoard.maskBToHFiles) << 7) |
|
||||
|
@ -616,11 +643,19 @@ public class Evaluate {
|
|||
}
|
||||
}
|
||||
|
||||
// Connected passed pawn bonus. Seems logical but doesn't help in tests
|
||||
// if (passedPawnsW != 0)
|
||||
// passedBonusW += 15 * Long.bitCount(passedPawnsW & ((passedPawnsW & BitBoard.maskBToHFiles) >>> 1));
|
||||
// if (passedPawnsB != 0)
|
||||
// passedBonusB += 15 * Long.bitCount(passedPawnsB & ((passedPawnsB & BitBoard.maskBToHFiles) >>> 1));
|
||||
// Connected passed pawn bonus. Seems logical but scored -8 elo in tests
|
||||
// if (passedPawnsW != 0) {
|
||||
// long mask = passedPawnsW;
|
||||
// mask = (((mask >> 7) | (mask << 1) | (mask << 9)) & BitBoard.maskBToHFiles) |
|
||||
// (((mask >> 9) | (mask >> 1) | (mask << 7)) & BitBoard.maskAToGFiles);
|
||||
// passedBonusW += 13 * Long.bitCount(passedPawnsW & mask);
|
||||
// }
|
||||
// if (passedPawnsB != 0) {
|
||||
// long mask = passedPawnsB;
|
||||
// mask = (((mask >> 7) | (mask << 1) | (mask << 9)) & BitBoard.maskBToHFiles) |
|
||||
// (((mask >> 9) | (mask >> 1) | (mask << 7)) & BitBoard.maskAToGFiles);
|
||||
// passedBonusB += 13 * Long.bitCount(passedPawnsB & mask);
|
||||
// }
|
||||
|
||||
ph.key = pos.pawnZobristHash();
|
||||
ph.score = score;
|
||||
|
@ -954,7 +989,7 @@ public class Evaluate {
|
|||
int wq = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WQUEEN]);
|
||||
int bk = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BKING]);
|
||||
int bp = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BPAWN]);
|
||||
score = evalKQKP(wk, wq, bk, bp);
|
||||
score = evalKQKP(wk, wq, bk, bp, pos.whiteMove);
|
||||
handled = true;
|
||||
}
|
||||
if (!handled && (pos.wMtrl == rV) && (pos.pieceTypeBB[Piece.WROOK] != 0)) {
|
||||
|
@ -981,7 +1016,7 @@ public class Evaluate {
|
|||
int bq = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BQUEEN]);
|
||||
int wk = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WKING]);
|
||||
int wp = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WPAWN]);
|
||||
score = -evalKQKP(63-bk, 63-bq, 63-wk, 63-wp);
|
||||
score = -evalKQKP(63-bk, 63-bq, 63-wk, 63-wp, !pos.whiteMove);
|
||||
handled = true;
|
||||
}
|
||||
if (!handled && (pos.bMtrl == rV) && (pos.pieceTypeBB[Piece.BROOK] != 0)) {
|
||||
|
@ -1031,7 +1066,7 @@ public class Evaluate {
|
|||
if (wMtrlNoPawns - bMtrlNoPawns > bV) {
|
||||
int wKnights = Long.bitCount(pos.pieceTypeBB[Piece.WKNIGHT]);
|
||||
int wBishops = Long.bitCount(pos.pieceTypeBB[Piece.WBISHOP]);
|
||||
if ((wKnights == 2) && (wMtrlNoPawns == 2 * nV) && (bMtrlNoPawns == 0)) {
|
||||
if ((wKnights == 2) && (pos.wMtrl == 2 * nV) && (bMtrlNoPawns == 0)) {
|
||||
score /= 50; // KNNK is a draw
|
||||
} else if ((wKnights == 1) && (wBishops == 1) && (wMtrlNoPawns == nV + bV) && (bMtrlNoPawns == 0)) {
|
||||
score /= 10;
|
||||
|
@ -1084,7 +1119,7 @@ public class Evaluate {
|
|||
if (bMtrlNoPawns - wMtrlNoPawns > bV) {
|
||||
int bKnights = Long.bitCount(pos.pieceTypeBB[Piece.BKNIGHT]);
|
||||
int bBishops = Long.bitCount(pos.pieceTypeBB[Piece.BBISHOP]);
|
||||
if ((bKnights == 2) && (bMtrlNoPawns == 2 * nV) && (wMtrlNoPawns == 0)) {
|
||||
if ((bKnights == 2) && (pos.bMtrl == 2 * nV) && (wMtrlNoPawns == 0)) {
|
||||
score /= 50; // KNNK is a draw
|
||||
} else if ((bKnights == 1) && (bBishops == 1) && (bMtrlNoPawns == nV + bV) && (wMtrlNoPawns == 0)) {
|
||||
score /= 10;
|
||||
|
@ -1115,7 +1150,7 @@ public class Evaluate {
|
|||
// FIXME! KRBKR is very hard to draw
|
||||
}
|
||||
|
||||
private static final int evalKQKP(int wKing, int wQueen, int bKing, int bPawn) {
|
||||
private static final int evalKQKP(int wKing, int wQueen, int bKing, int bPawn, boolean whiteMove) {
|
||||
boolean canWin = false;
|
||||
if (((1L << bKing) & 0xFFFF) == 0) {
|
||||
canWin = true; // King doesn't support pawn
|
||||
|
@ -1125,6 +1160,8 @@ public class Evaluate {
|
|||
switch (bPawn) {
|
||||
case 8: // a2
|
||||
canWin = ((1L << wKing) & 0x0F1F1F1F1FL) != 0;
|
||||
if (canWin && (bKing == 0) && (Position.getX(wQueen) == 1) && !whiteMove)
|
||||
canWin = false; // Stale-mate
|
||||
break;
|
||||
case 10: // c2
|
||||
canWin = ((1L << wKing) & 0x071F1F1FL) != 0;
|
||||
|
@ -1134,6 +1171,8 @@ public class Evaluate {
|
|||
break;
|
||||
case 15: // h2
|
||||
canWin = ((1L << wKing) & 0xF0F8F8F8F8L) != 0;
|
||||
if (canWin && (bKing == 7) && (Position.getX(wQueen) == 6) && !whiteMove)
|
||||
canWin = false; // Stale-mate
|
||||
break;
|
||||
default:
|
||||
canWin = true;
|
||||
|
@ -1141,8 +1180,7 @@ public class Evaluate {
|
|||
}
|
||||
}
|
||||
|
||||
final int dist = Math.max(Math.abs(Position.getX(wKing)-Position.getX(bPawn)),
|
||||
Math.abs(Position.getY(wKing)-Position.getY(bPawn)));
|
||||
final int dist = BitBoard.getDistance(wKing, bPawn);
|
||||
int score = qV - pV - 20 * dist;
|
||||
if (!canWin)
|
||||
score /= 50;
|
||||
|
|
|
@ -23,11 +23,15 @@ package chess;
|
|||
* @author petero
|
||||
*/
|
||||
public final class History {
|
||||
private final int countSuccess[][];
|
||||
private final int countFail[][];
|
||||
private final int score[][];
|
||||
private int countSuccess[][];
|
||||
private int countFail[][];
|
||||
private int score[][];
|
||||
|
||||
public History() {
|
||||
init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
countSuccess = new int[Piece.nPieceTypes][64];
|
||||
countFail = new int[Piece.nPieceTypes][64];
|
||||
score = new int[Piece.nPieceTypes][64];
|
||||
|
|
|
@ -64,13 +64,27 @@ public class Move {
|
|||
this.score = m.score;
|
||||
}
|
||||
|
||||
public void copyFrom(Move m) {
|
||||
public final void copyFrom(Move m) {
|
||||
from = m.from;
|
||||
to = m.to;
|
||||
promoteTo = m.promoteTo;
|
||||
// score = m.score;
|
||||
}
|
||||
|
||||
public final void clear() {
|
||||
from = 0;
|
||||
to = 0;
|
||||
promoteTo = 0;
|
||||
score = 0;
|
||||
}
|
||||
|
||||
public final void setMove(int from, int to, int promoteTo, int score) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.promoteTo = promoteTo;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
/** Note that score is not included in the comparison. */
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
|
|
@ -529,22 +529,8 @@ public class Position {
|
|||
*/
|
||||
public final void makeSEEMove(Move move, UndoInfo ui) {
|
||||
ui.capturedPiece = squares[move.to];
|
||||
boolean wtm = whiteMove;
|
||||
|
||||
int p = squares[move.from];
|
||||
long fromMask = 1L << move.from;
|
||||
|
||||
// Handle castling
|
||||
if (((pieceTypeBB[Piece.WKING] | pieceTypeBB[Piece.BKING]) & fromMask) != 0) {
|
||||
int k0 = move.from;
|
||||
if (move.to == k0 + 2) { // O-O
|
||||
setSEEPiece(k0 + 1, squares[k0 + 3]);
|
||||
setSEEPiece(k0 + 3, Piece.EMPTY);
|
||||
} else if (move.to == k0 - 2) { // O-O-O
|
||||
setSEEPiece(k0 - 1, squares[k0 - 4]);
|
||||
setSEEPiece(k0 - 4, Piece.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle en passant
|
||||
if (move.to == epSquare) {
|
||||
|
@ -558,7 +544,7 @@ public class Position {
|
|||
// Perform move
|
||||
setSEEPiece(move.from, Piece.EMPTY);
|
||||
setSEEPiece(move.to, p);
|
||||
whiteMove = !wtm;
|
||||
whiteMove = !whiteMove;
|
||||
}
|
||||
|
||||
public final void unMakeSEEMove(Move move, UndoInfo ui) {
|
||||
|
@ -566,20 +552,6 @@ public class Position {
|
|||
int p = squares[move.to];
|
||||
setSEEPiece(move.from, p);
|
||||
setSEEPiece(move.to, ui.capturedPiece);
|
||||
boolean wtm = whiteMove;
|
||||
|
||||
// Handle castling
|
||||
int king = wtm ? Piece.WKING : Piece.BKING;
|
||||
if (p == king) {
|
||||
int k0 = move.from;
|
||||
if (move.to == k0 + 2) { // O-O
|
||||
setSEEPiece(k0 + 3, squares[k0 + 1]);
|
||||
setSEEPiece(k0 + 1, Piece.EMPTY);
|
||||
} else if (move.to == k0 - 2) { // O-O-O
|
||||
setSEEPiece(k0 - 4, squares[k0 - 1]);
|
||||
setSEEPiece(k0 - 1, Piece.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle en passant
|
||||
if (move.to == epSquare) {
|
||||
|
|
|
@ -87,15 +87,16 @@ public class Search {
|
|||
public final static int UNKNOWN_SCORE = -32767; // Represents unknown static eval score
|
||||
int q0Eval; // Static eval score at first level of quiescence search
|
||||
|
||||
public Search(Position pos, long[] posHashList, int posHashListSize, TranspositionTable tt) {
|
||||
public Search(Position pos, long[] posHashList, int posHashListSize, TranspositionTable tt,
|
||||
History ht) {
|
||||
this.pos = new Position(pos);
|
||||
this.moveGen = new MoveGen();
|
||||
this.posHashList = posHashList;
|
||||
this.posHashListSize = posHashListSize;
|
||||
this.tt = tt;
|
||||
this.ht = ht;
|
||||
eval = new Evaluate();
|
||||
kt = new KillerTable();
|
||||
ht = new History();
|
||||
posHashFirstNew = posHashListSize;
|
||||
initNodeStats();
|
||||
minTimeMillis = -1;
|
||||
|
@ -519,23 +520,23 @@ public class Search {
|
|||
evalScore = ent.evalScore;
|
||||
int plyToMate = MATE0 - Math.abs(score);
|
||||
int eDepth = ent.getDepth();
|
||||
hashMove = sti.hashMove;
|
||||
ent.getMove(hashMove);
|
||||
if ((beta == alpha + 1) && ((eDepth >= depth) || (eDepth >= plyToMate*plyScale))) {
|
||||
if ( (ent.type == TTEntry.T_EXACT) ||
|
||||
(ent.type == TTEntry.T_GE) && (score >= beta) ||
|
||||
(ent.type == TTEntry.T_LE) && (score <= alpha)) {
|
||||
if (score >= beta) {
|
||||
hashMove = sti.hashMove;
|
||||
ent.getMove(hashMove);
|
||||
if ((hashMove != null) && (hashMove.from != hashMove.to))
|
||||
if (pos.getPiece(hashMove.to) == Piece.EMPTY)
|
||||
kt.addKiller(ply, hashMove);
|
||||
}
|
||||
sti.bestMove = hashMove;
|
||||
if (log != null) log.logNodeEnd(searchTreeInfo[ply].nodeIdx, score, ent.type, evalScore, hKey);
|
||||
return score;
|
||||
}
|
||||
}
|
||||
hashMove = sti.hashMove;
|
||||
ent.getMove(hashMove);
|
||||
}
|
||||
|
||||
int posExtend = inCheck ? plyScale : 0; // Check extension
|
||||
|
@ -543,6 +544,7 @@ public class Search {
|
|||
// If out of depth, perform quiescence search
|
||||
if (depth + posExtend <= 0) {
|
||||
q0Eval = evalScore;
|
||||
sti.bestMove.clear();
|
||||
int score = quiesce(alpha, beta, ply, 0, inCheck);
|
||||
int type = TTEntry.T_EXACT;
|
||||
if (score <= alpha) {
|
||||
|
@ -550,8 +552,8 @@ public class Search {
|
|||
} else if (score >= beta) {
|
||||
type = TTEntry.T_GE;
|
||||
}
|
||||
emptyMove.score = score;
|
||||
tt.insert(hKey, emptyMove, type, ply, depth, q0Eval);
|
||||
sti.bestMove.score = score;
|
||||
tt.insert(hKey, sti.bestMove, type, ply, depth, q0Eval);
|
||||
if (log != null) log.logNodeEnd(sti.nodeIdx, score, type, q0Eval, hKey);
|
||||
return score;
|
||||
}
|
||||
|
@ -628,6 +630,7 @@ public class Search {
|
|||
int epSquare = pos.getEpSquare();
|
||||
pos.setEpSquare(-1);
|
||||
searchTreeInfo[ply+1].allowNullMove = false;
|
||||
searchTreeInfo[ply+1].bestMove.clear();
|
||||
int score = -negaScout(-beta, -(beta - 1), ply + 1, depth - R, -1, false);
|
||||
searchTreeInfo[ply+1].allowNullMove = true;
|
||||
pos.setEpSquare(epSquare);
|
||||
|
@ -955,7 +958,7 @@ public class Search {
|
|||
if (score > alpha)
|
||||
alpha = score;
|
||||
int bestScore = score;
|
||||
final boolean tryChecks = (depth > -3);
|
||||
final boolean tryChecks = (depth > -1);
|
||||
MoveGen.MoveList moves;
|
||||
if (inCheck) {
|
||||
moves = moveGen.checkEvasions(pos);
|
||||
|
@ -1001,7 +1004,7 @@ public class Search {
|
|||
if (optimisticScore < alpha) { // Delta pruning
|
||||
if ((pos.wMtrlPawns > 0) && (pos.wMtrl > capt + pos.wMtrlPawns) &&
|
||||
(pos.bMtrlPawns > 0) && (pos.bMtrl > capt + pos.bMtrlPawns)) {
|
||||
if (depth -1 > -4) {
|
||||
if (depth -1 > -2) {
|
||||
givesCheck = MoveGen.givesCheck(pos, m);
|
||||
givesCheckComputed = true;
|
||||
}
|
||||
|
@ -1016,11 +1019,11 @@ public class Search {
|
|||
}
|
||||
|
||||
if (!givesCheckComputed) {
|
||||
if (depth - 1 > -4) {
|
||||
if (depth - 1 > -2) {
|
||||
givesCheck = MoveGen.givesCheck(pos, m);
|
||||
}
|
||||
}
|
||||
final boolean nextInCheck = (depth - 1) > -4 ? givesCheck : false;
|
||||
final boolean nextInCheck = (depth - 1) > -2 ? givesCheck : false;
|
||||
|
||||
pos.makeMove(m, ui);
|
||||
qNodes++;
|
||||
|
@ -1030,6 +1033,10 @@ public class Search {
|
|||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
if (score > alpha) {
|
||||
if (depth == 0) {
|
||||
SearchTreeInfo sti = searchTreeInfo[ply];
|
||||
sti.bestMove.setMove(m.from, m.to, m.promoteTo, score);
|
||||
}
|
||||
alpha = score;
|
||||
if (alpha >= beta) {
|
||||
moveGen.returnMoveList(moves);
|
||||
|
|
|
@ -71,7 +71,7 @@ public class TranspositionTable {
|
|||
this.move = (short)(move.from + (move.to << 6) + (move.promoteTo << 12));
|
||||
}
|
||||
|
||||
/** Get the score from the hash entry, and convert from "mate in x" to "mate at ply". */
|
||||
/** Get the score from the hash entry and convert from "mate in x" to "mate at ply". */
|
||||
public final int getScore(int ply) {
|
||||
int sc = score;
|
||||
if (sc > Search.MATE0 - 1000) {
|
||||
|
@ -82,7 +82,7 @@ public class TranspositionTable {
|
|||
return sc;
|
||||
}
|
||||
|
||||
/** Convert score from "mate at ply" to "mate in x", and store in hash entry. */
|
||||
/** Convert score from "mate at ply" to "mate in x" and store in hash entry. */
|
||||
public final void setScore(int score, int ply) {
|
||||
if (score > Search.MATE0 - 1000) {
|
||||
score += ply;
|
||||
|
|
|
@ -125,6 +125,19 @@ public class BitBoardTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static final int computeDistance(int from, int to) {
|
||||
int dx = Position.getX(to) - Position.getX(from);
|
||||
int dy = Position.getY(to) - Position.getY(from);
|
||||
return Math.max(Math.abs(dx), Math.abs(dy));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDistance() {
|
||||
for (int from = 0; from < 64; from++)
|
||||
for (int to = 0; to < 64; to++)
|
||||
assertEquals(computeDistance(from, to), BitBoard.getDistance(from, to));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrailingZeros() {
|
||||
System.out.println("trailingZeros");
|
||||
|
|
|
@ -277,7 +277,7 @@ public class EvaluateTest {
|
|||
score = evalWhite(pos);
|
||||
assertTrue(-score > bV * 2 + 100);
|
||||
|
||||
// KrpKn is win for white
|
||||
// KRPKN is win for white
|
||||
pos = TextIO.readFEN("8/3bk3/8/8/8/3P4/3RK3/8 w - - 0 1");
|
||||
score = evalWhite(pos);
|
||||
final int pV = Evaluate.pV;
|
||||
|
@ -287,10 +287,14 @@ public class EvaluateTest {
|
|||
pos = TextIO.readFEN("8/8/4k3/8/8/3NK3/3N4/8 w - - 0 1");
|
||||
score = evalWhite(pos);
|
||||
assertTrue(Math.abs(score) < 50);
|
||||
|
||||
|
||||
final int nV = Evaluate.nV;
|
||||
pos = TextIO.readFEN("8/8/8/4k3/N6N/P2K4/8/8 b - - 0 66");
|
||||
score = evalWhite(pos);
|
||||
assertTrue(score > nV * 2);
|
||||
|
||||
pos = TextIO.readFEN("8/8/3k4/8/8/3NK3/2B5/8 b - - 0 1");
|
||||
score = evalWhite(pos);
|
||||
final int nV = Evaluate.nV;
|
||||
assertTrue(score > bV + nV + 150); // KBNK is won, should have a bonus
|
||||
score = moveScore(pos, "Kc6");
|
||||
assertTrue(score > 0); // Black king going into wrong corner, good for white
|
||||
|
@ -412,6 +416,8 @@ public class EvaluateTest {
|
|||
assertTrue(evalWhite(pos) > winScore);
|
||||
pos = TextIO.readFEN("3Q4/8/8/8/K7/8/1kp5/8 w - - 0 1");
|
||||
assertTrue(evalWhite(pos) > winScore);
|
||||
pos = TextIO.readFEN("8/8/8/8/8/1Q6/p3K3/k7 b - - 0 1");
|
||||
assertTrue(evalWhite(pos) < drawish);
|
||||
|
||||
// Pawn on c2
|
||||
pos = TextIO.readFEN("3Q4/8/8/8/3K4/8/1kp5/8 w - - 0 1");
|
||||
|
@ -445,6 +451,29 @@ public class EvaluateTest {
|
|||
assertTrue(score2 > score1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPawnRace() throws ChessParseError {
|
||||
final int pV = Evaluate.pV;
|
||||
final int winScore = 400;
|
||||
final int drawish = 100;
|
||||
Position pos = TextIO.readFEN("8/8/K7/1P3p2/8/6k1/8/8 w - - 0 1");
|
||||
assertTrue(evalWhite(pos) > winScore);
|
||||
pos = TextIO.readFEN("8/8/K7/1P3p2/8/6k1/8/8 b - - 0 1");
|
||||
assertTrue(evalWhite(pos) > winScore);
|
||||
|
||||
pos = TextIO.readFEN("8/8/K7/1P3p2/6k1/8/8/8 b - - 0 1");
|
||||
assertTrue(Math.abs(evalWhite(pos)) < drawish);
|
||||
pos = TextIO.readFEN("8/8/K7/1P6/5pk1/8/8/8 b - - 0 1");
|
||||
assertTrue(evalWhite(pos) < -winScore);
|
||||
pos = TextIO.readFEN("8/K7/8/1P6/5pk1/8/8/8 b - - 0 1");
|
||||
assertTrue(Math.abs(evalWhite(pos)) < drawish);
|
||||
pos = TextIO.readFEN("8/K7/8/8/1PP2p1k/8/8/8 w - - 0 1");
|
||||
assertTrue(evalWhite(pos) < drawish + pV);
|
||||
assertTrue(evalWhite(pos) > 0);
|
||||
pos = TextIO.readFEN("8/K7/8/8/1PP2p1k/8/8/8 b - - 0 1");
|
||||
assertTrue(evalWhite(pos) < -winScore + pV);
|
||||
}
|
||||
|
||||
/** Return static evaluation score for white, regardless of whose turn it is to move. */
|
||||
final static int evalWhite(Position pos) {
|
||||
Evaluate eval = new Evaluate();
|
||||
|
|
|
@ -32,6 +32,7 @@ import static org.junit.Assert.*;
|
|||
public class SearchTest {
|
||||
static final long[] nullHist = new long[200];
|
||||
static TranspositionTable tt = new TranspositionTable(19);
|
||||
static History ht = new History();
|
||||
|
||||
public SearchTest() {
|
||||
}
|
||||
|
@ -53,7 +54,7 @@ public class SearchTest {
|
|||
final int mate0 = Search.MATE0;
|
||||
|
||||
Position pos = TextIO.readFEN("3k4/8/3K2R1/8/8/8/8/8 w - - 0 1");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
final int plyScale = Search.plyScale;
|
||||
int score = sc.negaScout(-mate0, mate0, 0, 2*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(mate0 - 2, score); // depth 2 is enough to find mate in 1
|
||||
|
@ -61,33 +62,33 @@ public class SearchTest {
|
|||
assertEquals(score, score2);
|
||||
|
||||
pos = TextIO.readFEN("8/1P6/k7/2K5/8/8/8/8 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
score = sc.negaScout(-mate0, mate0, 0, 4*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(mate0 - 4, score); // depth 4 is enough to find mate in 2
|
||||
score2 = idSearch(sc, 4).score;
|
||||
assertEquals(score, score2);
|
||||
|
||||
pos = TextIO.readFEN("8/5P1k/5K2/8/8/8/8/8 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
score = sc.negaScout(-mate0, mate0, 0, 5*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(mate0 - 4, score); // must avoid stale-mate after f8Q
|
||||
score2 = idSearch(sc, 5).score;
|
||||
assertEquals(score, score2);
|
||||
|
||||
pos = TextIO.readFEN("4k3/8/3K1Q2/8/8/8/8/8 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
score = sc.negaScout(-mate0, mate0, 0, 2*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(0, score); // Position is stale-mate
|
||||
|
||||
pos = TextIO.readFEN("3kB3/8/1N1K4/8/8/8/8/8 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
score = sc.negaScout(-mate0, mate0, 0, 3*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertTrue(Math.abs(score) < 50); // Stale-mate trap
|
||||
score2 = idSearch(sc, 5).score;
|
||||
assertEquals(score, score2);
|
||||
|
||||
pos = TextIO.readFEN("8/8/2K5/3QP3/P6P/1q6/8/k7 w - - 31 51");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
Move bestM = idSearch(sc, 2);
|
||||
assertTrue(!TextIO.moveToString(pos, bestM, false).equals("Qxb3"));
|
||||
}
|
||||
|
@ -105,50 +106,50 @@ public class SearchTest {
|
|||
final int mateInThree = mate0 - 6;
|
||||
|
||||
Position pos = TextIO.readFEN("8/1R2k3/R7/8/8/8/8/1K6 b - - 0 1");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
final int plyScale = Search.plyScale;
|
||||
int score = sc.negaScout(-mate0, mate0, 0, 2*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(matedInOne, score);
|
||||
|
||||
pos = TextIO.readFEN("8/1R2k3/R7/8/8/8/8/1K6 b - - 99 80");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = sc.negaScout(-mate0, mate0, 0, 2*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(0, score); // Draw by 50-move rule
|
||||
|
||||
pos = TextIO.readFEN("8/1R2k3/R7/8/8/8/8/1K6 b - - 98 80");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = sc.negaScout(-mate0, mate0, 0, 2*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(matedInOne, score); // No draw
|
||||
|
||||
pos = TextIO.readFEN("8/1R2k3/R7/8/8/8/8/1K6 b - - 99 80");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 3).score;
|
||||
assertEquals(0, score);
|
||||
|
||||
pos = TextIO.readFEN("3k4/1R6/R7/8/8/8/8/1K6 w - - 100 80");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 2).score;
|
||||
assertEquals(mateInOne, score); // Black forgot to claim draw. Now it's too late.
|
||||
|
||||
pos = TextIO.readFEN("8/7k/1R6/R7/8/7P/8/1K6 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 3).score;
|
||||
assertEquals(mateInTwo, score);
|
||||
|
||||
pos = TextIO.readFEN("8/7k/1R6/R7/8/7P/8/1K6 w - - 98 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 6).score;
|
||||
assertEquals(mateInThree, score); // Need an extra pawn move to avoid 50-move rule
|
||||
|
||||
pos = TextIO.readFEN("8/7k/1R6/R7/8/7P/8/1K6 w - - 125 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 6).score;
|
||||
assertEquals(mateInThree, score); // Need an extra pawn move to avoid 50-move rule
|
||||
|
@ -162,32 +163,32 @@ public class SearchTest {
|
|||
System.out.println("drawRep");
|
||||
final int mate0 = Search.MATE0;
|
||||
Position pos = TextIO.readFEN("7k/5RR1/8/8/8/8/q3q3/2K5 w - - 0 1");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
final int plyScale = Search.plyScale;
|
||||
int score = sc.negaScout(-mate0, mate0, 0, 3*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertEquals(0, score);
|
||||
|
||||
pos = TextIO.readFEN("7k/5RR1/8/8/8/8/q3q3/2K5 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 3).score;
|
||||
assertEquals(0, score);
|
||||
|
||||
pos = TextIO.readFEN("7k/5RR1/8/8/8/8/1q3q2/3K4 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 4).score;
|
||||
assertTrue(score < 0);
|
||||
|
||||
pos = TextIO.readFEN("7k/5RR1/8/8/8/8/1q3q2/3K4 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = sc.negaScout(-mate0, mate0, 0, 3*plyScale, -1, MoveGen.inCheck(pos));
|
||||
assertTrue(score < 0);
|
||||
|
||||
pos = TextIO.readFEN("qn6/qn4k1/pp3R2/5R2/8/8/8/K7 w - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
sc.maxTimeMillis = -1;
|
||||
score = idSearch(sc, 7).score;
|
||||
assertEquals(0, score); // Draw, black can not escape from perpetual checks
|
||||
|
@ -200,7 +201,7 @@ public class SearchTest {
|
|||
public void testHashing() throws ChessParseError {
|
||||
System.out.println("hashing");
|
||||
Position pos = TextIO.readFEN("/k/3p/p2P1p/P2P1P///K/ w - -"); // Fine #70
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
Move bestM = idSearch(sc, 28);
|
||||
assertEquals(TextIO.stringToMove(pos, "Kb1"), new Move(bestM));
|
||||
}
|
||||
|
@ -211,7 +212,7 @@ public class SearchTest {
|
|||
@Test
|
||||
public void testLMP() throws ChessParseError {
|
||||
Position pos = TextIO.readFEN("2r2rk1/6p1/p3pq1p/1p1b1p2/3P1n2/PP3N2/3N1PPP/1Q2RR1K b"); // WAC 174
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
Move bestM = idSearch(sc, 2);
|
||||
assertTrue(bestM.score < Search.MATE0 / 2);
|
||||
}
|
||||
|
@ -220,12 +221,12 @@ public class SearchTest {
|
|||
public void testCheckEvasion() throws ChessParseError {
|
||||
System.out.println("check evasion");
|
||||
Position pos = TextIO.readFEN("6r1/R5PK/2p5/1k6/8/8/p7/8 b - - 0 62");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
Move bestM = idSearch(sc, 3);
|
||||
assertTrue(bestM.score < 0);
|
||||
|
||||
pos = TextIO.readFEN("r1bq2rk/pp3pbp/2p1p1pQ/7P/3P4/2PB1N2/PP3PPR/2KR4 w - -"); // WAC 004
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
bestM = idSearch(sc, 1);
|
||||
assertEquals(Search.MATE0 - 4, bestM.score);
|
||||
assertEquals(TextIO.stringToMove(pos, "Qxh7+"), new Move(bestM));
|
||||
|
@ -235,7 +236,7 @@ public class SearchTest {
|
|||
public void testStalemateTrap() throws ChessParseError {
|
||||
System.out.println("stalemate trap");
|
||||
Position pos = TextIO.readFEN("7k/1P3R1P/6r1/5K2/8/8/6R1/8 b - - 98 194");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
Move bestM = idSearch(sc, 3);
|
||||
assertEquals(0, bestM.score);
|
||||
}
|
||||
|
@ -244,7 +245,7 @@ public class SearchTest {
|
|||
public void testKQKRNullMove() throws ChessParseError {
|
||||
System.out.println("kqkrNullMove");
|
||||
Position pos = TextIO.readFEN("7K/6R1/5k2/3q4/8/8/8/8 b - - 0 1");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
Move bestM = idSearch(sc, 10);
|
||||
assertEquals(Search.MATE0-18, bestM.score);
|
||||
}
|
||||
|
@ -286,7 +287,7 @@ public class SearchTest {
|
|||
|
||||
// Basic tests
|
||||
Position pos = TextIO.readFEN("r2qk2r/ppp2ppp/1bnp1nb1/1N2p3/3PP3/1PP2N2/1P3PPP/R1BQRBK1 w kq - 0 1");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "dxe5")));
|
||||
assertEquals(pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxe5")));
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa7")));
|
||||
|
@ -299,7 +300,7 @@ public class SearchTest {
|
|||
assertEquals(-rV, getSEE(sc, TextIO.stringToMove(pos, "Ra6")));
|
||||
|
||||
pos.setWhiteMove(false);
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertTrue(nV <= bV); // Assumed by following test
|
||||
assertEquals(pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxd4")));
|
||||
assertEquals(pV - bV, getSEE(sc, TextIO.stringToMove(pos, "Bxd4")));
|
||||
|
@ -312,7 +313,7 @@ public class SearchTest {
|
|||
|
||||
// Test X-ray attacks
|
||||
pos = TextIO.readFEN("3r2k1/pp1q1ppp/1bnr1nb1/1Np1p3/1P1PP3/2P1BN2/1Q1R1PPP/3R1BK1 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 1 1 1 3 3 3 3 3 5 5 9 5 5
|
||||
// 0 1 0 1 0 3 0 3 0 5 0 9 0 5
|
||||
assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "exd4")));
|
||||
|
@ -321,38 +322,38 @@ public class SearchTest {
|
|||
assertEquals(2 * pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxd4")));
|
||||
|
||||
pos.setPiece(TextIO.getSquare("b2"), Piece.EMPTY); // Remove white queen
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 1 1 1 3 3 3 3 3 5 5 9 5
|
||||
// 0 1 0 1 0 3 0 3 0 4 1 4 5
|
||||
assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "exd4")));
|
||||
assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "cxb4")));
|
||||
|
||||
pos.setPiece(TextIO.getSquare("b5"), Piece.EMPTY); // Remove white knight
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 1 1 1 3 3 3 3 5 5 5
|
||||
// 1 0 1 0 3 0 3 0 5 0 5
|
||||
assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "exd4")));
|
||||
|
||||
pos.setPiece(TextIO.getSquare("b2"), Piece.WQUEEN); // Restore white queen
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 1 1 1 3 3 3 3 5 5 5 9 9
|
||||
// 1 0 1 0 3 0 3 0 5 0 5 0 9
|
||||
assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "exd4")));
|
||||
|
||||
pos.setPiece(TextIO.getSquare("b6"), Piece.EMPTY); // Remove black bishop
|
||||
pos.setPiece(TextIO.getSquare("c6"), Piece.EMPTY); // Remove black knight
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(-pV, getSEE(sc, TextIO.stringToMove(pos, "a5")));
|
||||
|
||||
// Test EP capture
|
||||
pos = TextIO.readFEN("2b3k1/1p3ppp/8/pP6/8/2PB4/5PPP/6K1 w - a6 0 2");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 1 1 3
|
||||
// 0 1 0 3
|
||||
assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "bxa6")));
|
||||
|
||||
pos.setPiece(TextIO.getSquare("b7"), Piece.EMPTY); // Remove black pawn
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 1 3
|
||||
// 1 0 3
|
||||
assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "bxa6")));
|
||||
|
@ -360,14 +361,14 @@ public class SearchTest {
|
|||
|
||||
// Test king capture
|
||||
pos = TextIO.readFEN("8/8/8/4k3/r3P3/4K3/8/4R3 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 5 99
|
||||
// 1 0 99
|
||||
assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+")));
|
||||
|
||||
pos = TextIO.readFEN("8/8/8/4k3/r3P1R1/4K3/8/8 b - - 0 1");
|
||||
final int kV = Evaluate.kV;
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
// 1 5 5 99
|
||||
//-4 5 0 99
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+")));
|
||||
|
@ -376,47 +377,47 @@ public class SearchTest {
|
|||
assertEquals(pV - kV, getSEE(sc, new Move(TextIO.getSquare("e5"), TextIO.getSquare("e4"), Piece.EMPTY)));
|
||||
|
||||
pos = TextIO.readFEN("8/8/4k3/8/r3P3/4K3/8/8 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+")));
|
||||
|
||||
// Test king too far away
|
||||
pos = TextIO.readFEN("8/8/4k3/8/r3P3/8/4K3/8 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+")));
|
||||
|
||||
pos = TextIO.readFEN("8/3k4/8/8/r1K5/8/8/2R5 w - - 0 1");
|
||||
pos.setWhiteMove(false);
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(kV, getSEE(sc, new Move(TextIO.getSquare("a4"), TextIO.getSquare("c4"), Piece.EMPTY)));
|
||||
|
||||
|
||||
// Test blocking pieces
|
||||
pos = TextIO.readFEN("r7/p2k4/8/r7/P7/8/4K3/R7 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); // Ra8 doesn't help
|
||||
|
||||
pos.setPiece(TextIO.getSquare("a7"), Piece.BBISHOP);
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); // Ra8 doesn't help
|
||||
|
||||
pos.setPiece(TextIO.getSquare("a7"), Piece.BPAWN);
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); // Ra8 doesn't help
|
||||
|
||||
pos.setPiece(TextIO.getSquare("a7"), Piece.BQUEEN);
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); // Ra8 does help
|
||||
|
||||
pos = TextIO.readFEN("8/3k4/R7/r7/P7/8/4K3/8 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4")));
|
||||
|
||||
pos = TextIO.readFEN("Q7/q6k/R7/r7/P7/8/4K3/8 b - - 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4")));
|
||||
|
||||
pos = TextIO.readFEN("8/3k4/5R2/8/4pP2/8/8/3K4 b - f3 0 1");
|
||||
sc = new Search(pos, nullHist, 0, tt);
|
||||
sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
int score1 = EvaluateTest.evalWhite(sc.pos);
|
||||
long h1 = sc.pos.zobristHash();
|
||||
assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "exf3")));
|
||||
|
@ -433,7 +434,7 @@ public class SearchTest {
|
|||
public void testScoreMoveList() throws ChessParseError {
|
||||
System.out.println("SEEorder");
|
||||
Position pos = TextIO.readFEN("r2qk2r/ppp2ppp/1bnp1nb1/1N2p3/3PP3/1PP2N2/1P3PPP/R1BQRBK1 w kq - 0 1");
|
||||
Search sc = new Search(pos, nullHist, 0, tt);
|
||||
Search sc = new Search(pos, nullHist, 0, tt, ht);
|
||||
MoveGen moveGen = new MoveGen();
|
||||
MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos);
|
||||
sc.scoreMoveList(moves, 0);
|
||||
|
|
Loading…
Reference in New Issue
Block a user