Some work on incremental attack-map update
[hachu.git] / hachu.c
diff --git a/hachu.c b/hachu.c
index 903838d..4ee9e04 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
@@ -533,13 +533,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 +550,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 +754,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 +771,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 +801,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 +818,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 +840,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 +1219,7 @@ GenCapts(int sqr, int victimValue)
 int\r
 Evaluate ()\r
 {\r
-  return 0;\r
+  return (stm ? mobilityScore : -mobilityScore);\r
 }\r
 \r
 int\r
@@ -1692,10 +1709,10 @@ SearchBestMove (int stm, int timeLeft, int mps, int timeControl, int inc, int ti
 {\r
   int score, targetTime, movesLeft = 50;\r
   if(mps) movesLeft = mps - (moveNr>>1)%mps;\r
-  targetTime = timeLeft*10 / (movesLeft + 1) + 1000 * inc;\r
+  targetTime = timeLeft*10 / (movesLeft + 2) + 1000 * inc;\r
   if(timePerMove > 0) targetTime = timeLeft * 5;\r
   startTime = GetTickCount();\r
-  tlim1 = 0.3*targetTime;\r
+  tlim1 = 0.2*targetTime;\r
   tlim2 = 1.9*targetTime;\r
   nodes = 0;\r
 MapFromScratch(attacks);\r