\r
#define VERSION "0.21"\r
\r
-//define PATH level==0 || path[0] == 0x590cb && (level==1 || path[1] == 0x4c0c9 && (level == 2 || path[2] == 0x8598ca && (level == 3 /*|| path[3] == 0x3e865 && (level == 4 || path[4] == 0x4b865 && (level == 5))*/)))\r
+//define PATH level==0 || path[0] == 0x82906b && (level==1 || path[1] == 0x8790d9 && (level == 2 || path[2] == 0x8598ca && (level == 3 /*|| path[3] == 0x3e865 && (level == 4 || path[4] == 0x4b865 && (level == 5))*/)))\r
#define PATH 0\r
\r
#define HASH\r
#define N -1 /* Knight */\r
#define J -2 /* jump */\r
#define I -3 /* jump + step */\r
-#define D -4 /* linear double move */\r
+#define K -4 /* triple + range */\r
#define T -5 /* linear triple move */\r
-#define K -6 /* triple + range */\r
+#define D -6 /* linear double move */\r
#define L -7 /* true Lion move */\r
#define W -8 /* Werewolf move */\r
#define F -9 /* Lion + 3-step */\r
{"OM", "MW", 10, { 0,1,0,1,1,1,0,1 } }, // Old Monkey M'\r
{"BB", "fB", 10, { 0,1,0,1,X,1,0,1 } }, // Blind Bear B'\r
{"OR", "BA", 10, { 0,2,0,0,2,0,0,2 } }, // Old Rat O'\r
- {"LD", "G", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W!\r
+ {"LD", "G", 800, { T,T,T,T,T,T,T,T } }, // Lion Dog W!\r
{"WR", "G", 10, { 0,3,1,3,0,3,1,3 } }, // Wrestler W'\r
{"GG", "G", 10, { 3,1,3,0,3,0,3,1 } }, // Guardian of the Gods G'\r
{"BD", "G", 10, { 0,3,1,0,1,0,1,3 } }, // Budhist Devil D'\r
{"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile +Y\r
{"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone +U\r
{"EM", "", 10, { 0,0,0,0,0,0,0,0 } }, // Emperor +K\r
- {"TK", "", 10, { K,K,K,K,K,K,K,K } }, // Teaching King +I'\r
- {"BS", "", 10, { S,S,S,S,S,S,S,S } }, // Budhist Spirit +J'\r
+ {"TK", "", 1300, { K,K,K,K,K,K,K,K }, 0, 6}, // Teaching King +I'\r
+ {"BS", "", 1500, { S,S,S,S,S,S,S,S }, 0, 7}, // Budhist Spirit +J'\r
{"WS", "", 10, { X,X,0,X,1,X,0,X } }, // Wizard Stork +N'\r
{"MW", "", 10, { 1,X,0,X,X,X,0,X } }, // Mountain Witch +M'\r
- {"FF", "", 10, { F,F,F,F,F,F,F,F } }, // Furious Fiend +L!\r
+ {"FF", "", 1150, { F,F,F,F,F,F,F,F } }, // Furious Fiend +L!\r
{"GD", "", 10, { 2,3,X,3,2,3,X,3 } }, // Great Dragon +W!\r
{"GO", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird +X\r
{"fW", "", 10, { X,X,X,0,0,0,X,X } }, // Free Wolf +W\r
p2 = LookUp(p1->promoted, var);\r
m = AddPiece(color, p2);\r
if(m <= n) n += 2;\r
+ if(p2->ranking > 5) { // contageous\r
+ AddPiece(color, p2);\r
+ if(m <= n) n += 2;\r
+ }\r
p[n].promo = m;\r
p[n].promoFlag = IsUpwardCompatible(p2->range, p1->range) * DONT_DEFER + CAN_PROMOTE;\r
if(Forward(p1->range)) p[n].promoFlag |= LAST_RANK; // Pieces that only move forward can't defer on last rank\r
if(!occup & r < L) for(y=x+2*v; !NewNonCapture(x, y+=v, pFlag) && r == S; ); // BS and FF moves\r
v = nStep[j];\r
if(r != W) NewNonCapture(x, x + v, pFlag);\r
- } else if(r == T) NewNonCapture(x, x+3*v, pFlag); // Lion Dog, also triple step\r
- else if(r == K) {\r
+ } else if(r >= T) { // T or K\r
occup |= NewNonCapture(x, x+3*v, pFlag); // Lion Dog, also triple step\r
- if(!occup) for(y=x+3*v; !NewNonCapture(x, y+=v, pFlag); ); // TK moves\r
+ if(!occup && r == K) for(y=x+3*v; !NewNonCapture(x, y+=v, pFlag); ); // Teaching King distant moves\r
}\r
} else if(r == I) NewNonCapture(x, x + v, pFlag); // also do step\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], mob += (board[x + 2*v] ^ start) & 1;\r
- if(r < J) { // Lion power, also single step\r
+ if(r < J) { // more than plain jump\r
if(board[x + v] != EMPTY && board[x + v] != EDGE)\r
- map[2*(x + v) + start] += one[j];\r
- if(r < I) {\r
- if(r == T || r == K) { // Lion Dog, also jump of 3\r
+ map[2*(x + v) + start] += one[j]; // single step (completes D and I)\r
+ if(r < I) { // Lion power\r
+ if(r >= T) { // Lion Dog, also do a jump of 3\r
if(board[x + 3*v] != EMPTY && board[x + 3*v] != EDGE)\r
map[2*(x + 3*v) + start] += one[j];\r
- if(r == K) { // also range (Teaching King)\r
+ if(r == K) { // Teaching King also range move\r
int y = x, n = 0;\r
while(1) {\r
if(board[y+=v] == EDGE) break;\r
- if(board[y] != EMPTY) {\r
+ if(board[y] != EMPTY) {\r
if(n > 2) map[2*y + start] += one[j]; // outside Lion range\r
break;\r
}\r
\r
u->victim = board[u->to];\r
p[u->victim].pos = ABSENT;\r
- if(p[u->victim].ranking == 5 && p[u->piece].ranking < 4) { // contageous piece captured by non-royal\r
+ if(p[u->victim].ranking >= 5 && p[u->piece].ranking < 4) { // contageous piece captured by non-royal\r
u->booty -= p[u->new].value;\r
- u->new = u->piece & 1 | 2; // promote to it\r
+ u->new = u->piece & 1 | (u->victim - 2 & ~3) + 2; // promote to it (assumes they head the list in pairs)\r
if(p[u->new].pos != ABSENT) u->new += 2;\r
p[u->piece].pos = ABSENT;\r
u->booty += p[u->new].value;\r
while( board[x+=v] == EMPTY ); // scan towards source until we encounter a 'stop'\r
//printf("stop @ %c%d (dir %d)\n",x%BW+'a',x/BW,i);\r
if((board[x] & TYPE) == stm) { // stop is ours\r
+ static int minRange[20] = { 3, 0, 0, 0, 2, 2, 2 }; // K, T, D, L, W, F, S\r
+ static int maxRange[20] = { 36, 0, 0, 0, 3, 3, 36 }; // K, T, D, L, W, F, S\r
int attacker = board[x], d = dist[x-sqr], r = p[attacker].range[i];\r
//printf("attacker %d, range %d, dist %d\n", attacker, r, d);\r
- if(r >= d || r < L && (d > 3 && r == S || d == 3 && r >= S)) { // it has a plain move in our direction that hits us\r
+ if(r >= d || r <= K && d <= maxRange[K-r] && d > minRange[K-r]) { // it has a plain move in our direction that hits us\r
NewCapture(x, sqr + victimValue - SORTKEY(attacker), p[attacker].promoFlag);\r
att -= one[i];\r
if(!(att & attackMask[i])) continue; // no more; next direction\r
while(board[x+=v] == EMPTY);// one attack accounted for, but more to come, so skip to next stop\r
}\r
}\r
- // we get here when we are on a piece that dous not attack us through a (limited) ranging move,\r
+ // we get here when we are on a piece that does not attack us through a (limited) ranging move,\r
// it can be our own or an enemy with not (enough) range, or which is blocked\r
do {\r
//printf("scan %x-%x (%d) dir=%d d=%d r=%d att=%o jcapt=%d qval=%d\n", sqr, x, board[x], i, dist[x-sqr], p[board[x]].range[i], att, jcapt, p[board[x]].qval);\r
bestScore = curEval; resDep = QSdepth;\r
if(bestScore > alpha) {\r
alpha = bestScore;\r
-if(PATH)printf("stand pat %d\n", bestScore);\r
+if(PATH)printf("stand pat %d (beta=%d)\n", bestScore, beta);\r
if(bestScore >= beta) goto cutoff;\r
}\r
}\r
if(flag && depth>= 0) printf("phase=%d: first/curr/last = %d / %d / %d\n", phase, firstMove, curMove, msp);fflush(stdout);\r
// MOVE SOURCE\r
if(curMove >= msp) { // we ran out of moves; generate some new\r
-if(PATH)printf("new moves, phase=%d\n", phase);\r
+if(PATH)printf("new moves, phase=%d\n", phase),fflush(stdout);\r
switch(phase) {\r
case 0: // null move\r
#ifdef NULLMOVE\r
if(depth > QSdepth && curEval >= beta && !inCheck && filling > 10) {\r
int nullDep = depth - 3;\r
stm ^= WHITE;\r
+path[level++] = 0;\r
+if(PATH) printf("%d:%d null move\n", level, depth),fflush(stdout);\r
score = -Search(-beta, 1-beta, -difEval, nullDep<QSdepth ? QSdepth : nullDep, 0, promoSuppress & SQUARE, ABSENT, INF);\r
+if(PATH) printf("%d:%d null move score = %d\n", level, depth, score),fflush(stdout);\r
+level--;\r
xstm = stm; stm ^= WHITE;\r
if(score >= beta) { msp = oldMSP; retDep += 3; pvPtr = myPV; return score + (score < curEval); }\r
// else depth += lmr, lmr = 0;\r
nextVictim = xstm; autoFail = (depth == 0);\r
phase = 3;\r
case 3: // generate captures\r
-if(PATH) printf("%d:%2d:%2d next victim %d/%d\n",level,depth,iterDep,curMove,msp);\r
+if(PATH) printf("%d:%2d:%2d next victim %d/%d\n",level,depth,iterDep,curMove,msp),fflush(stdout);\r
while(nextVictim < last[xstm]) { // more victims exist\r
int group, to = p[nextVictim += 2].pos; // take next\r
if(to == ABSENT) continue; // ignore if absent\r
if(bestScore < 2*group + curEval + 30) bestScore = 2*group + curEval + 30;\r
goto cutoff;\r
}\r
-if(PATH) printf("%d:%2d:%2d group=%d, to=%c%d\n",level,depth,iterDep,group,to%BW+'a',to/BW+ONE);\r
+if(PATH) printf("%d:%2d:%2d group=%d, to=%c%d\n",level,depth,iterDep,group,to%BW+'a',to/BW+ONE),fflush(stdout);\r
GenCapts(to, 0);\r
-if(PATH) printf("%d:%2d:%2d first=%d msp=%d\n",level,depth,iterDep,firstMove,msp);\r
+if(PATH) printf("%d:%2d:%2d first=%d msp=%d\n",level,depth,iterDep,firstMove,msp),fflush(stdout);\r
while(nextVictim < last[xstm] && p[nextVictim+2].value == group) { // more victims of same value exist\r
to = p[nextVictim += 2].pos; // take next\r
if(to == ABSENT) continue; // ignore if absent\r
if(!attacks[2*to + stm]) continue; // skip if not attacked\r
-if(PATH) printf("%d:%2d:%2d p=%d, to=%c%d\n",level,depth,iterDep,nextVictim,to%BW+'a',to/BW+ONE);\r
+if(PATH) printf("%d:%2d:%2d p=%d, to=%c%d\n",level,depth,iterDep,nextVictim,to%BW+'a',to/BW+ONE),fflush(stdout);\r
GenCapts(to, 0);\r
-if(PATH) printf("%d:%2d:%2d msp=%d\n",level,depth,iterDep,msp);\r
+if(PATH) printf("%d:%2d:%2d msp=%d\n",level,depth,iterDep,msp),fflush(stdout);\r
}\r
-if(PATH) printf("captures on %d generated, msp=%d, group=%d, threshold=%d\n", nextVictim, msp, group, threshold);\r
+if(PATH) printf("captures on %d generated, msp=%d, group=%d, threshold=%d\n", nextVictim, msp, group, threshold),fflush(stdout);\r
goto extractMove; // in auto-fail phase, only search if they might auto-fail-hi\r
}\r
if(PATH) printf("# autofail=%d\n", autoFail);\r
{\r
int i, j;\r
for(i=0; i<182; i++) {\r
- printf("%3d. %3d %3d %4d %02x %d %d %x %3d %4d ", i, p[i].value, p[i].promo, p[i].pos, p[i].promoFlag&255, p[i].mobWeight, p[i].qval, p[i].bulk, p[i].promoGain, p[i].pst);\r
- for(j=0; j<8; j++) printf(" %2d", p[i].range[j]);\r
+ printf("%3d. %4d %3d %4d %02x %d %2d %x %3d %4d ", i, p[i].value, p[i].promo, p[i].pos, p[i].promoFlag&255, p[i].mobWeight, p[i].qval, p[i].bulk, p[i].promoGain, p[i].pst);\r
+ for(j=0; j<8; j++) printf(" %3d", p[i].range[j]);\r
if(i<2 || i>11) printf("\n"); else printf(" %02x %d\n", fireFlags[i-2]&255, p[i].ranking);\r
}\r
printf("last: %d / %d\nroyal %d / %d\n", last[WHITE], last[BLACK], royal[WHITE], royal[BLACK]);\r
for(i=listStart; i<msp && currentVariant == V_WOLF; i++) { // mark Werewolf captures as promotions\r
int to = moveStack[i] & SQUARE, from = moveStack[i] >> SQLEN & SQUARE;\r
if(to >= SPECIAL) continue;\r
- if(p[board[to]].ranking == 5 && p[board[from]].ranking < 4) moveStack[i] |= PROMOTE;\r
+ if(p[board[to]].ranking >= 5 && p[board[from]].ranking < 4) moveStack[i] |= PROMOTE;\r
}\r
}\r
\r
PrintResult(stm, score);\r
} else {\r
MOVE f, pMove = move;\r
+ static char *pName[] = { "w", "z", "j" };\r
if((move & SQUARE) >= SPECIAL && p[board[f = move>>SQLEN & SQUARE]].value == pVal) { // e.p. capture\r
pMove = move & ~SQUARE | f + toList[(move & SQUARE) - SPECIAL]; // print as a single move\r
}\r
stm = MakeMove2(stm, move); // assumes MakeMove returns new side to move\r
gameMove[moveNr++] = move; // remember game\r
- printf("move %s%s\n", MoveToText(pMove, 1), p[undoInfo.victim].ranking == 5 && p[undoInfo.piece].ranking < 4 ? "w" : "");\r
+ i = p[undoInfo.victim].ranking;\r
+ printf("move %s%s\n", MoveToText(pMove, 1), i == 5 && p[undoInfo.piece].ranking < 4 ? pName[i-5] : "");\r
listEnd = 0;\r
continue; // go check if we should ponder\r
}\r
"piece D& sbWfF\npiece V& FfW\npiece W& WfF\npiece S& sRvW\npiece R& FfRbW\npiece F& BfW\npiece X& FvWAvD\n"\r
"piece +D& WfF\npiece +V& FfsW\npiece +W& K\npiece +S& R\npiece +R& FvWAvD\npiece +F& BvRsW\npiece E& vRfF3bFsW\n");\r
if(currentVariant == V_MACAD)\r
- printf("setup (P.*B*RQSEXOG....D^J'..*LP'.L!J'...*W!...*F'...^C.C.^L!.^P'^K.T*L'.*C!*H!^I'.^E...*R'^P^T*W'*G'^G^SI'^X^OK"\r
- "p.*b*rqsexog....d^j'..*lp'.l!j'...*w!...*f'...^c.c.^l!.^p'^k.t*l'.*c!*h!^i'.^e...*r'^p^t*w'*g'^g^si'^x^ok) 13x13+0_chu %s w 0 1\n"\r
+ printf("setup (P.*B*RQSEXOG....D^J'..*LP'.L!J'=J...*W!...*F'...^C.C.^L!.^P'^K.T*L'.*C!*H!^I'=Z.^E...*R'^P^T*W'*G'^G^SI'^X^OK"\r
+ "p.*b*rqsexog....d^j'..*lp'.l!j'=j...*w!...*f'...^c.c.^l!.^p'^k.t*l'.*c!*h!^i'=z.^e...*r'^p^t*w'*g'^g^si'^x^ok) 13x13+0_chu %s w 0 1\n"\r
"piece P& fW\npiece S& FfW\npiece E& FfsW\npiece X& WA\npiece O& FD\npiece G& WfF\npiece D& RF\npiece +J'& QNADcaKmabK\n"\r
"piece L& fR\npiece P'& vW\npiece L!& KNADcaKmabK\npiece J'& blfFrW\npiece H!& RmasR\npiece W!& KADcavKmcpafmcpavK\n"\r
"piece C!& BmasB\npiece F'& F2\npiece +C& vRfB\npiece C& vWfF\npiece +L!& K3NADcaKmabK\npiece +P'& vR\npiece T& FbsW\n"\r