} 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
{ 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
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
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
{\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
} 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
}\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
{\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
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
int\r
Evaluate ()\r
{\r
- return 0;\r
+ return (stm ? mobilityScore : -mobilityScore);\r
}\r
\r
int\r
{\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