\r
#define VERSION "0.19"\r
\r
-//define PATH level==0 || path[0] == 0x1103a && (level==1 || path[1] == 0x6f0f6 && (level == 2 /*|| path[2] == 0x8710f && (level == 3 /*|| path[3] == 0x3e865 && (level == 4 || path[4] == 0x4b865 && (level == 5)))*/))\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 0\r
\r
#define HASH\r
char c, *q, name[3], prince = 0;\r
PieceDesc *p1, *p2;\r
last[WHITE] = 1; last[BLACK] = 0;\r
+ royal[WHITE] = royal[BLACK] = 0;\r
for(i=0; ; i++) {\r
//printf("next rank: %s\n", array);\r
for(j = BW*i; ; j++) {\r
}\r
}\r
eos:\r
+ // add dummy Kings if not yet added (needed to set royal[] to valid value!)\r
+ if(!royal[WHITE]) p[AddPiece(WHITE, LookUp("K", V_CHU))].pos = ABSENT;\r
+ if(!royal[BLACK]) p[AddPiece(BLACK, LookUp("K", V_CHU))].pos = ABSENT;\r
// add dummy Crown Princes if not yet added\r
if(!(prince & WHITE+1)) p[AddPiece(WHITE, LookUp("CP", V_CHU))].pos = ABSENT;\r
if(!(prince & BLACK+1)) p[AddPiece(BLACK, LookUp("CP", V_CHU))].pos = ABSENT;\r
}\r
\r
int\r
-Surround (int stm, int king, int start)\r
+Surround (int stm, int king, int start, int max)\r
{\r
int i, s=0;\r
for(i=start; i<9; i++) {\r
v = p[piece].value;\r
s += -(v > 70) & v;\r
}\r
- return (s > 512 ? 512 : s);\r
+ return (s > max ? max : s);\r
}\r
\r
int\r
int\r
Evaluate (int difEval)\r
{\r
- int wLion = ABSENT, bLion = ABSENT, wKing, bKing, score=mobilityScore, f, i, j;\r
+ int wLion = ABSENT, bLion = ABSENT, wKing, bKing, score=mobilityScore, f, i, j, max=512;\r
+\r
+ if(tsume) return difEval;\r
\r
if(p[WHITE+2].value == LVAL) wLion = p[WHITE+2].pos;\r
if(p[BLACK+2].value == LVAL) bLion = p[BLACK+2].pos;\r
score += (PST[PST_CENTER+wKing] - PST[PST_CENTER+bKing])*(32 - filling) >> 7;\r
if(lead > 100) score -= PST[PST_CENTER+bKing]*(32 - filling) >> 3; // white leads, drive black K to corner\r
if(lead < -100) score += PST[PST_CENTER+wKing]*(32 - filling) >> 3; // black leads, drive white K to corner\r
+ max = 16*filling;\r
}\r
\r
# ifdef FORTRESS\r
# endif\r
\r
# ifdef KSHIELD\r
- score += Surround(WHITE, wKing, 1) - Surround(BLACK, bKing, 1) >> 3;\r
+ score += Surround(WHITE, wKing, 1, max) - Surround(BLACK, bKing, 1, max) >> 3;\r
# endif\r
\r
#endif\r
int sq;\r
if((wLion = kylin[WHITE]) && (sq = p[wLion].pos) != ABSENT) {\r
int anchor = sq - PST[5*BW*BH - 1 - sq]; // FIXME: PST_ZONDIST indexed backwards\r
- score += (512 - Surround(BLACK, anchor, 0))*(128 - filling)*PST[p[wLion].pst + sq] >> 15;\r
+ score += (512 - Surround(BLACK, anchor, 0, 512))*(128 - filling)*PST[p[wLion].pst + sq] >> 15;\r
}\r
if((bLion = kylin[BLACK]) && (sq = p[bLion].pos) != ABSENT) {\r
int anchor = sq + PST[PST_ZONDIST + sq];\r
- score -= (512 - Surround(WHITE, anchor, 0))*(128 - filling)*PST[p[bLion].pst + sq] >> 15;\r
+ score -= (512 - Surround(WHITE, anchor, 0, 512))*(128 - filling)*PST[p[bLion].pst + sq] >> 15;\r
}\r
}\r
#endif\r
// in-check test and TSUME filter\r
{\r
k = p[king=royal[stm]].pos;\r
- if( k == ABSENT) k = p[king + 2].pos;\r
- else if(p[king + 2].pos != ABSENT) k = ABSENT; // two kings is no king...\r
+ if( k == ABSENT) {\r
+ if((k = p[king + 2].pos) == ABSENT && (!tsume || tsume & stm+1))\r
+ return -INF; // lose when no King (in tsume only for side to be mated)\r
+ } else if(p[king + 2].pos != ABSENT) {\r
+ if(tsume && tsume & stm+1) {\r
+ retDep = 60; return INF; // we win when not in check\r
+ }\r
+ k = ABSENT; // two kings is no king...\r
+ }\r
if( k != ABSENT) { // check is possible\r
if(!attacks[2*k + xstm]) {\r
if(tsume && tsume & stm+1) {\r
}\r
} else { // he has no king! Test for attacks on Crown Prince\r
k = p[king + 2].pos;\r
- if(k == ABSENT || attacks[2*k + stm]) return INF; // we have attack on Crown Prince\r
+ if(k == ABSENT ? !tsume : attacks[2*k + stm]) return INF; // we have attack on Crown Prince\r
}\r
//printf("King safe\n");fflush(stdout);\r
// EVALUATION & WINDOW SHIFT\r
if(to == ABSENT) continue; // ignore if absent\r
if(!attacks[2*to + stm]) continue; // skip if not attacked\r
group = p[nextVictim].value; // remember value of this found victim\r
- if(iterDep <= QSdepth + 1 && 2*group + curEval + 30 < alpha) { resDep = QSdepth + 1; goto cutoff; }\r
+ if(iterDep <= QSdepth + 1 && 2*group + curEval + 30 < alpha) {\r
+ resDep = QSdepth + 1; nextVictim -= 2;\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
GenCapts(to, 0);\r
if(PATH) printf("%d:%2d:%2d first=%d msp=%d\n",level,depth,iterDep,firstMove,msp);\r
case 6: // non-captures\r
nonCapts = msp;\r
nullMove = GenNonCapts(oldPromo);\r
+ if(msp == nonCapts) goto cutoff;\r
#ifdef KILLERS\r
{ // swap killers to front\r
Move h = killer[level][0]; int j = curMove;\r
\r
if(flag & depth >= 0) printf("%2d:%d made %d/%d %s\n", depth, iterDep, curMove, msp, MoveToText(moveStack[curMove], 0));\r
for(i=2; i<=cnt50; i+=2) if(repStack[level-i+200] == hashKeyH) {\r
+ retDep = iterDep;\r
if(repDraws) { score = 0; goto repetition; }\r
if(!allowRep) {\r
moveStack[curMove] = 0; // erase forbidden move\r
#ifdef HASH\r
// hash store\r
hashTable[index].lock[hit] = hashKeyH;\r
- hashTable[index].depth[hit] = iterDep;\r
+ hashTable[index].depth[hit] = resDep;\r
hashTable[index].score[hit] = bestScore;\r
hashTable[index].flag[hit] = (bestScore < beta) * H_UPPER;\r
if(bestScore > alpha) {\r
*p++ = table[2* (*fen - 'A' - n)+1] + n;\r
}\r
} else *p++ = *fen;\r
+ if(!*fen) break;\r
fen++;\r
}\r
printf("# converted FEN '%s'\n", fenArray);\r
SetUp(array, currentVariant);\r
strcpy(startPos, array);\r
sup0 = sup1 = sup2 = ABSENT;\r
- hashKeyH = hashKeyL = 87620895*currentVariant;\r
+ hashKeyH = hashKeyL = 87620895*currentVariant + !!fen;\r
return stm;\r
}\r
\r