Add Chess pieces
[hachu.git] / hachu.c
diff --git a/hachu.c b/hachu.c
index 176039f..bfb25f2 100644 (file)
--- a/hachu.c
+++ b/hachu.c
@@ -87,7 +87,7 @@ typedef struct {
 } UndoInfo;\r
 \r
 int bWidth, bHeight, bsize, zone, currentVariant;\r
-int stm, xstm, hashKeyH, hashKeyL, framePtr, msp, nonCapts, rootEval, retMSP, retFirst, pvPtr, level, cnt50, chuFlag=1;\r
+int stm, xstm, hashKeyH, hashKeyL, framePtr, msp, nonCapts, rootEval, retMSP, retFirst, pvPtr, level, cnt50, chuFlag=1, mobilityScore;\r
 int nodes, startTime, tlim1, tlim2;\r
 Move retMove, moveStack[10000], path[100], repStack[300], pv[1000];\r
 \r
@@ -262,6 +262,16 @@ PieceDesc taikyokuPieces[] = {
   { NULL }  // sentinel\r
 };\r
 \r
+PieceDesc chessPieces[] = {\r
+  {"Q", "",  95, { X,X,X,X,X,X,X,X } },\r
+  {"R", "",  50, { X,0,X,0,X,0,X,0 } },\r
+  {"B", "",  33, { 0,X,0,X,0,X,0,X } },\r
+  {"N", "",  30, { N,N,N,N,N,N,N,N } },\r
+  {"K", "",  28, { 1,1,1,1,1,1,1,1 } },\r
+  {"P", "Q",  8, { 0,1,0,0,0,0,0,1 } },\r
+  { NULL }  // sentinel\r
+};\r
+\r
 char chuArray[] = "L:FLCSGK:DEGSC:FLL/:RV.B.:BT:KN:PH:BT.B.:RV/:SM:VMR:DH:DK:LN:FK:DK:DHR:VM:SM/PPPPPPPPPPPP/...:GB....:GB..."\r
                  "/............/............/"\r
                  "...:gb....:gb.../pppppppppppp/:sm:vmr:dh:dk:fk:ln:dk:dhr:vm:sm/:rv.b.:bt:ph:kn:bt.b.:rv/l:flcsg:dekgsc:fll";\r
@@ -533,13 +543,13 @@ Compactify (int stm)
 int\r
 AddPiece (int stm, PieceDesc *list)\r
 {\r
-  int i, j, *key;\r
+  int i, j, *key, v;\r
   for(i=stm+2; i<=last[stm]; i += 2) {\r
     if(p[i].value < 10*list->value || p[i].value == 10*list->value && (p[i].promo < 0)) break;\r
   }\r
   last[stm] += 2;\r
   for(j=last[stm]; j>i; j-= 2) p[j] = p[j-2];\r
-  p[i].value = 10*list->value;\r
+  p[i].value = v = 10*list->value;\r
   for(j=0; j<8; j++) p[i].range[j] = list->range[j^4*(WHITE-stm)];\r
   switch(Range(p[i].range)) {\r
     case 1:  p[i].pst = BH; break;\r
@@ -550,6 +560,7 @@ AddPiece (int stm, PieceDesc *list)
   if(!*key) *key = ~(myRandom()*myRandom());\r
   p[i].pieceKey = *key;\r
   p[i].promoFlag = 0;\r
+  p[i].mobWeight = v > 600 ? 0 : v >= 400 ? 1 : v >= 300 ? 2 : v > 150 ? 3 : v >= 100 ? 2 : 0;\r
   for(j=stm+2; j<= last[stm]; j+=2) {\r
     if(p[j].promo >= i) p[j].promo += 2;\r
   }\r
@@ -753,11 +764,12 @@ report (int x, int y, int i)
 {\r
 }\r
 \r
-void\r
+int\r
 MapOneColor (int start, int last, int *map)\r
 {\r
-  int i, j, k;\r
+  int i, j, k, totMob = 0;\r
   for(i=start+2; i<=last; i+=2) {\r
+    int mob = 0;\r
     if(p[i].pos == ABSENT) continue;\r
     for(j=0; j<8; j++) {\r
       int x = p[i].pos, v = kStep[j], r = p[i].range[j];\r
@@ -769,7 +781,7 @@ MapOneColor (int start, int last, int *map)
        } else\r
        if(r >= S) { // in any case, do a jump of 2\r
          if(board[x + 2*v] != EMPTY && board[x + 2*v] != EDGE)\r
-           map[2*(x + 2*v) + start] += one[j];\r
+           map[2*(x + 2*v) + start] += one[j], mob += (board[x + 2*v] ^ start) & 1;\r
          if(r < J) { // Lion power, also single step\r
            if(board[x + v] != EMPTY && board[x + v] != EDGE)\r
              map[2*(x + v) + start] += one[j];\r
@@ -799,12 +811,16 @@ MapOneColor (int start, int last, int *map)
       }\r
       while(r-- > 0) {\r
         if(board[x+=v] != EMPTY) {\r
-         if(board[x] != EDGE) map[2*x + start] += one[j];\r
+         mob += dist[x-v-p[i].pos];\r
+         if(board[x] != EDGE) map[2*x + start] += one[j], mob += (board[x] ^ start) & 1;\r
          break;\r
        }\r
       }\r
     }\r
+    totMob += mob * p[i].mobWeight;\r
   }\r
+if(!level) printf("# mobility %d = %d\n", start, totMob);\r
+  return totMob;\r
 }\r
 \r
 void\r
@@ -812,14 +828,14 @@ MapFromScratch (int *map)
 {\r
   int i;\r
   for(i=0; i<2*bsize; i++) map[i] = 0;\r
-  MapOneColor(0, last[BLACK], map);\r
-  MapOneColor(1, last[WHITE], map);\r
+  mobilityScore  = MapOneColor(1, last[WHITE], map);\r
+  mobilityScore -= MapOneColor(0, last[BLACK], map);\r
 }\r
 \r
 void\r
 Connect (int sqr, int piece, int dir)\r
 { // scan to both sides along ray to elongate attacks from there, and remove our own attacks on there, if needed\r
-  int x, step = kStep[dir], r1 = p[piece].range[dir], r2 = p[piece].range[dir+4], piece1, piece2;\r
+  int x, step = kStep[dir], r1 = p[piece].range[dir], r2 = p[piece].range[dir+4], r3, r4, piece1, piece2;\r
   int d1, d2, r, y, c;\r
 \r
   if((attacks[2*sqr] + attacks[2*sqr+1]) & attackMask[dir]) {         // there are incoming attack(s) from 'behind'\r
@@ -834,16 +850,27 @@ Connect (int sqr, int piece, int dir)
       d2 = dist[y-sqr]; piece2 = board[y];\r
       attacks[2*y+stm] -= -(d2 <= r1) & one[dir];                     // remove our attack on it if in-range\r
       // we have two pieces now shooting at each other. See how far they get.\r
-      if(d1 + d2 <= (r1 = p[piece1].range[dir])) {                    // 1 hits 2\r
+      if(d1 + d2 <= (r3 = p[piece1].range[dir])) {                    // 1 hits 2\r
        attacks[2*y + (piece1 & WHITE)] += one[dir];                  // count attack\r
        UPDATE_MOBILITY(piece1, d2);\r
-      } else UPDATE_MOBILITY(piece1, r1 - d1);                        // does not connect, but could still gain mobility\r
-      if(d1 + d2 <= (r2 = p[piece2].range[dir+4])) {                  // 2 hits 1\r
+      } else UPDATE_MOBILITY(piece1, r3 - d1);                        // does not connect, but could still gain mobility\r
+      if(d1 + d2 <= (r4 = p[piece2].range[dir+4])) {                  // 2 hits 1\r
        attacks[2*x + (piece2 & WHITE)] += one[dir+4];                // count attack\r
        UPDATE_MOBILITY(piece2, d1);\r
-      } else UPDATE_MOBILITY(piece2, r2 - d2);                        // does not connect, but could still gain mobility\r
+      } else UPDATE_MOBILITY(piece2, r4 - d2);                        // does not connect, but could still gain mobility\r
       // if r1 or r2<0, moves typically jump, and thus cannot be unblocked. Exceptions are FF and BS distant moves.\r
       // test for d1+d2 > 2 && rN == F && d== 3 or rN == S\r
+      if(d1 <= 2) { // could be jump interactions\r
+       if(d1 == 2) {\r
+         if(r2 <= J) attacks[2*x + stm] -= one[dir+4];\r
+         if(r1 <= J) attacks[2*y + stm] -= one[dir];\r
+       } else { // d1 == 1\r
+         if(r2 < J) attacks[2*x + stm] -= one[dir+4];\r
+         if(r1 < J) attacks[2*y + stm] -= one[dir];\r
+         if(board[x-step] != EMPTY && board[x-step] != EDGE)\r
+           attacks[2*(x-step) + stm] -= one[dir+4];\r
+       }\r
+      }\r
 \r
     } else { // we were only attacked from behind\r
 \r
@@ -1202,7 +1229,7 @@ GenCapts(int sqr, int victimValue)
 int\r
 Evaluate ()\r
 {\r
-  return 0;\r
+  return (stm ? mobilityScore : -mobilityScore);\r
 }\r
 \r
 int\r