Add and initialize some more piece-square tables
authorH.G.Muller <hgm@hgm-xboard.(none)>
Wed, 28 Dec 2016 13:59:58 +0000 (14:59 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Wed, 28 Dec 2016 13:59:58 +0000 (14:59 +0100)
The number of PST in increased to 9 pairs, and they are initialized
to be useful for various groups of pieces (e.g. Shogi generals).

dropper.c

index f0975d5..2dcce8c 100644 (file)
--- a/dropper.c
+++ b/dropper.c
@@ -364,11 +364,15 @@ unsigned int squareKey[22*11];
 // piece-square tables. White and black tables interleave. The first two pairs are (0, center) and (hand1, ???)
 #define center   (pstData + 22*11)
 #define hand1    (pstData + 22*11)    /* beware: uses off-board part only */
-#define sparePST (pstData + 22*11)    /* on-board part still available for something else */
-#define pawnPST  (pstData + 22*11*2)  /* from here interleaved (white, black) */
-#define kingPST  (pstData + 22*11*3)
+#define kingPST  (pstData + 22*11*2)  /* King and Queen PST               */
+#define pawnPST  (pstData + 22*11*3)  /* from here interleaved (white, black) */
+#define knightPST (pstData + 22*11*4)
+#define owlPST    (pstData + 22*11*5)
+#define promoPST  (pstData + 22*11*6) /* +90 in zone, for strong promotion */
+#define generalPST (pstData + 22*11*7)/* +30 in central zone */
+#define rookPST   (pstData + 22*11*8) /* +45 in zone */
 
-signed char pstData[22*11*8];  // actual tables (for now 8 pairs)
+signed char pstData[22*11*9];  // actual tables (for now 9 pairs)
 
 int
 MyRandom ()
@@ -537,15 +541,28 @@ printf("# variant %d: %s\n", v, variants[v].name);
     }
     PST[WHITE+2] = PST[BLACK+2] = center; // Bishops
     for(f=0; f<11; f++) { // pawn tables
+       int d = (nrRanks > 8 || nrRanks == 7); // larger camp
        for(r=0; r<=zone; r++) pawnPST[22*(nrRanks - 1 - r) + f] = pawnPST[22*r + f + 11] = 1.2*pieceValues[WHITE]; // in and just before zone ('7th rank')
        pawnPST[22*(nrRanks - 2 - zone) + f] = pawnPST[22*(zone + 1) + f + 11] = 0.6*pieceValues[WHITE]; // ('6th rank')
        pawnPST[22*(nrRanks - 2) + f + 11] = pawnPST[22 + f] = 10; // discourage leaving 2nd rank
-       for(r=2; r<nrRanks-2; r++) kingPST[22*r+f] = -127; kingPST[f] = kingPST[22*(nrRanks-1)+f] = 90;
-       for(r=2; r<nrRanks-2; r++) kingPST[22*r+f+11] = -40;
+       for(r=0; r<nrRanks; r++) pawnPST[22*(nrRanks - 1 - r) + f] = pawnPST[22*r + f + 11] -= (r - nrRanks/2)*3 +10;
+       for(r=2+d; r<nrRanks-2-d; r++) kingPST[22*r+f] = -127; kingPST[f] = kingPST[22*(nrRanks-1)+f] = 80; kingPST[22*d+f] = kingPST[22*(nrRanks-1-d)+f] = 90;
+       for(r=2+d; r<nrRanks-2-d; r++) kingPST[22*r+f+11] = -40;
+       knightPST[22*3+f] = knightPST[22*4+11+f] = 12; // only used for zh
+       knightPST[22*4+f] = knightPST[22*3+11+f] = 20;
+       knightPST[22*5+f] = knightPST[22*2+11+f] = 17;
     }
     PST[WHITE] = pawnPST; PST[BLACK] = pawnPST + 11;
     PST[WHITE+31] = PST[BLACK+31] = kingPST;
 
+    for(f=0; f<nrFiles; f++) for(r=0; r<nrRanks; r++) {
+       int xr = nrRanks - 1 - r; double mr = (nrRanks - 1.)/2., mf = (nrFiles - 1.)/2.;
+       generalPST[22*r+f] = generalPST[22*xr+f+11] = (r-mr)*5 - r*(f-mf)*(f-mf) + 10*(xr < zone) - 20*(xr == 0);
+       owlPST[22*r+f]     = owlPST[22*xr+f+11]     = (r == 1)*10 + (xr < zone ? 90 : -90) + 90*(xr == zone);
+       promoPST[22*r+f]   = promoPST[22*xr+f+11]   = 90*(xr < zone);
+       rookPST[22*r+f]    = rookPST[22*xr+f+11]    = 45*(xr < zone);
+    }
+
     InitCaptureCodes(variants[v].codes);
     pinCodes = (v == 3 ? 0xFF2C : 0xFF1F); // rays along which pinning ispossible
 }
@@ -803,6 +820,52 @@ AllDrops (int stm)
 }
 
 int
+DiscoTest (int stm, int fromSqr, int king, StackFrame *f)
+{
+    int vec = king - fromSqr;
+    int match = captCode[vec] & pinCodes;
+    if(match) { // from-square is aligned
+       int x = king, v = deltaVec[vec];
+       while(board[x-=v] == 0) {}   // scan ray
+       if(f->checker != x && !(board[x] & stm) && captCode[king-x] & pieceCode[board[x]]) { // discovered check
+           if(f->checker != CK_NONE) f->checker = CK_DOUBLE;
+           else f->checker = x, f->checkDir = v, f->checkDist = dist[x-king];
+       }
+    }
+}
+
+void
+CheckTest (int stm, StackFrame *ff, StackFrame *f)
+{
+       int king = location[stm+31]; // own King
+       int vec = king - ff->toSqr;
+       int match = captCode[vec] & pieceCode[ff->toPiece];
+       f->checker = CK_NONE; f->checkDist = 0; // assume not in check
+       if(match & C_DISTANT) { // moving piece is aligned
+           int x = ff->toSqr, v = deltaVec[vec];
+           while(board[x+=v] == 0) {} // scan ray
+           if(x == king) f->checker = ff->toSqr, f->checkDir = v, f->checkDist = dist[vec]; // ray is clear, distant check
+       } else if(match & C_CONTACT) f->checker = ff->toSqr, f->checkDir = 0; // contact check
+       if(ff->mutation != -1) { // board move (no drop)
+           DiscoTest(stm, ff->fromSqr, king, ff);
+           if(board[ff->captSqr] == 0) DiscoTest(stm, ff->captSqr, king, ff); // e.p. capture can discover check as well
+       }
+}
+
+int
+Pinned (int stm, int fromSqr, int xking)
+{
+    int vec = xking - fromSqr;
+    int match = captCode[vec] & pinCodes;
+    if(match) {
+       int x = xking, v = deltaVec[vec];
+       while(board[x-=v] == 0) {}
+       if(!(board[x] & stm) && captCode[xking-x] & pieceCode[board[x]]) return 1; // guards & counters tests as own piece!
+    }
+    return 0;
+}
+
+int
 NonEvade (StackFrame *f)
 {
     if((f->fromPiece & ~COLOR) != 31) { // moves non-royal (or drops)
@@ -900,21 +963,15 @@ Search (int stm, int alpha, int beta, StackFrame *ff, int depth, int reduction,
     int curEval, score;
 
     // legality
-    int earlyGen = (ff->toPiece == stm+31 || ff->toSqr != ff->captSqr); // King was moved, or e.p.
+    int earlyGen = (ff->toPiece == stm+31); // King was moved
 if(ply > 90) Dump("maxply");
     f.xking = location[stm+31]; // opponent King, as stm not yet toggled
-    if(!earlyGen) { // if other piece was moved, abort with +INF score if it was pinned
-       if(ff->mutation > 0) { // exclude drops
-           int vec = f.xking - ff->fromSqr;
-           int match = captCode[vec] & pinCodes;
-           if(match) {
-               int x = f.xking, v = deltaVec[vec];
-               while(board[x-=v] == 0) {}
-               if(!(board[x] & stm) && captCode[f.xking-x] & pieceCode[board[x]]) return INF; // guards & counters tests as own piece!
-           }
-       }
+    if(!earlyGen && ff->mutation > 0) { // if other piece was moved (not dropped!), abort with +INF score if it was pinned
+       if(Pinned(stm, ff->fromSqr, f.xking)) return INF;
+       if(board[ff->captSqr] == 0 && Pinned(stm, ff->captSqr, f.xking)) return INF; // also check 'e.p. pin'
     }
 
+
     // some housekeeping
     stm ^= COLOR;
     f.hashKey =  ff->newKey;
@@ -962,41 +1019,7 @@ if(hashMove && board[hashMove>>8&255] == 0) {char s[100];sprintf(s,"bad hash mov
 
 
     // check test
-    if(f.checker == CK_UNKNOWN) { // hash did not supply it
-       int king = location[stm+31]; // own King
-       int vec = king - ff->toSqr;
-       int match = captCode[vec] & pieceCode[ff->toPiece];
-       f.checker = CK_NONE; f.checkDist = 0; // assume not in check
-       if(match & C_DISTANT) { // moving piece is aligned
-           int x = ff->toSqr, v = deltaVec[vec];
-           while(board[x+=v] == 0) {} // scan ray
-           if(x == king) f.checker = ff->toSqr, f.checkDir = v, f.checkDist = dist[vec]; // ray is clear, distant check
-       } else if(match & C_CONTACT) f.checker = ff->toSqr, f.checkDir = 0; // contact check
-       if(ff->mutation != -1) { // board move (no drop)
-           vec = king - ff->fromSqr;
-           match = captCode[vec] & pinCodes;
-           if(match) { // from-square is aligned
-               int x = king, v = deltaVec[vec];
-               while(board[x-=v] == 0) {}   // scan ray
-               if(f.checker != x && !(board[x] & stm) && captCode[king-x] & pieceCode[board[x]]) { // discovered check
-                   if(f.checker != CK_NONE) f.checker = CK_DOUBLE;
-                   else f.checker = x, f.checkDir = v, f.checkDist = dist[x-king];
-               }
-           }
-           if(board[ff->captSqr] == 0) { // e.p. capture can discover check as well
-               vec = king - ff->captSqr;
-               match = captCode[vec] & pinCodes;
-               if(match) { // from-square is aligned
-                   int x = king, v = deltaVec[vec];
-                   while(board[x-=v] == 0) {}   // scan ray
-                   if(f.checker != x && !(board[x] & stm) && captCode[king-x] & pieceCode[board[x]]) { // discovered check
-                       if(f.checker != CK_NONE) f.checker = CK_DOUBLE;
-                       else f.checker = x, f.checkDir = v, f.checkDist = dist[x-king];
-                   }
-               }
-           }
-       }
-    }
+    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 = 0; // extend check evasions
     else if(depth > 3) {
        if(depth - reduction < 3) reduction = depth - 3; // never reduce to below 3 ply