/*****************************************************************/\r
\r
#define MULTIPATH\r
-#define VERSION "4.8R"\r
+#define VERSION "4.8S"\r
\r
#include <stdio.h>\r
#include <stdlib.h>\r
int MaxDepth;\r
int Post;\r
int Fifty;\r
-int UnderProm;\r
int GameNr;\r
int Resign;\r
int Cambodian;\r
int Threshold = 800;\r
int Score;\r
int makruk;\r
-int prom, pm, gating;\r
+int prom, pm, gating, succession;\r
char piecename[32], piecetype[32], blacktype[32];\r
char selectedFairy[80];\r
char *inifile = INI_FILE;\r
int pv[10000],*sp=pv; // triangular array\r
int margin;\r
\r
-pboard()\r
+void pboard()\r
{int i;\r
i=-1;W(++i<128)printf(" %c",(i&15)==BW&&(i+=15-BW)?10:n[b[i]&31]);\r
}\r
int k,q,l,e,E,z,n; /* (q,l)=window, e=current eval. score, E=e.p. sqr.*/\r
{ /* e=score, z=prev.dest; J,Z=hashkeys; return score*/\r
int j,r,m,v,d,h,i,F,G,P,V,f=J,g=Z,C,s,flag,FF,*ps=sp,kk=S;\r
- signed char t,p,u,x,y,X,Y,H,B,gt;\r
+ signed char t,p,u,x,y,X,Y,H,B,gt,rg;\r
struct _*a=A+(J+(k+S)*E&U); /* lookup pos. in hash table*/\r
*sp++=0;\r
q-=q<e;l-=l<=e; /* adj. window: delay bonus */\r
W(r=o[++j]) /* loop over directions o[] */\r
{A: /* resume normal after best */\r
flag=h?3:of[j]; /* move modes (for fairies) */\r
- y=x;F=FF=G=S; /* (x,y)=move, (F,G)=castl.R*/\r
+ y=x;F=FF=G=S;rg=flag>>10&3; /* (x,y)=move, (F,G)=castl.R*/\r
do{ /* y traverses ray, or: */\r
H=y=h?Y^h:y+r; /* sneak in prev. best move */\r
if(flag&1<<8)H=y=(y&15)>13?y+BW:(y&15)>=BW?y-BW:y; /* cylinder board */\r
}\r
#endif\r
m=E<16|(E^112)<16&&flag&1&y-E<2&E-y<2?I:m; /* bad castling */\r
- if(p<3&y==E)H=z&127; /* shift capt.sqr. H if e.p.*/\r
+ if(p<3&y==E&flag)H=z&127; /* shift capt.sqr. H if e.p.*/\r
t=b[H];\r
if(flag&1+!t) /* mode (capt/nonc) allowed?*/\r
{if(t&&(t&16)==k)break; /* capture own */\r
v+=e+i;V=m>q?m:q; /*** new eval & alpha ****/\r
if(z&S)V=m-margin>q?m-margin:q; /* multiPV */\r
C=d-1-(d>5&p>2&!t&!h); /* nw depth, reduce non-cpt.*/\r
- C=R<EG|P-I|d<3||t&&p-3?C:d; /* extend 1 ply if in-check */\r
+ C=R<EG|P-I|d<3||t&&w[p]>0?C:d; /* extend 1 ply if in-check */\r
do\r
s=C>2|v>V?-D(16-k,-l,-V,-v,/*** futility, recursive eval. of reply */\r
F,y&255,C):v;\r
if(z&S&&K-I) /* move pending: check legal*/\r
{if(v+I&&x==K&y==L>==GT) /* if move found */\r
{Q=-e-i;O=F;LL=L;prom=gt;\r
- if(b[y]-u&15)prom=b[y]-=PromPiece, /* under-promotion, correct */\r
- Z+=PromPiece; /* piece & invalidate hash */\r
+ if(b[y]-u&15)prom=b[y]-=PromPiece, /* (under-)promotion: */\r
+ Q-=abs(w[prom&=15])-w[p]-(6*S>>sh), /* correct piece & score & */\r
+ Z+=PromPiece; /* invalidate hash */\r
a->D=99;a->V=0; /* lock game in hash as draw*/\r
R-=i/FAC; /*** total captd material ***/\r
Fifty = t|p<3?0:Fifty+1;\r
)t+=flag&4; /* fake capt. for nonsliding*/\r
else if(flag&64)t=flag&128?0:t,flag&=63;else F=y; /* enable e.p. */\r
if(s&&flag&8)t=0,flag^=flag>>4&15; /* hoppers go to next phase */\r
- if(!(flag&S)) /* zig-zag piece? */\r
+ if(--rg<0&!(flag&S)) /* zig-zag piece? (w. delay)*/\r
r=v,flag^=flag>>4&15; /* alternate vector & mode */\r
}W(!t); /* if not capt. continue ray*/\r
}}\r
\r
int PrintResult(int s)\r
{\r
- int i, j, k, cnt=0;\r
+ int j, k, cnt=0;\r
\r
/* search last 50 states with this stm for third repeat */\r
for(j=2; j<=100 && j <= HistPtr; j+=2)\r
if(cnt==-I+1) {\r
if (s == WHITE)\r
printf("0-1 {Black mates}\n");\r
- else\r
+ else {\r
+ if(succession) { // suppress loss claim if black might be able to replace its King by promotion\r
+ for(j=0;j<BW;j++)if((b[j+96]&31)==18)return 0;\r
+ }\r
printf("1-0 {White mates}\n");\r
+ }\r
return 3;\r
}\r
if(Fifty >=100) {\r
}\r
\r
\r
-InitEngine()\r
+void InitEngine()\r
{\r
- int i, j;\r
-\r
N=32*S+7;W(N-->S+3)T[N]=rand()>>9;\r
srand(GetTickCount());\r
}\r
\r
-InitGame()\r
+void InitGame()\r
{\r
- int i,j,k=0;\r
+ int i,k=0;\r
\r
Side = WHITE; Q=0; O=S;\r
Fifty = 0; R = 0;\r
if(w[oo[i]] < 0) k = w[oo[i]];\r
}\r
R -= 2*(-k/FAC);\r
- UnderProm = -1; pl[WHITE] = pl[BLACK] = 2*BW; \r
+ pl[WHITE] = pl[BLACK] = 2*BW; \r
pm = !pl[BLACK+7] && pl[BLACK+9] && pl[WHITE+7] ? 2 : 0; // Unlike white, black has no 'Q', so promote to 9, which he does have.\r
if(gating) pl[14] = pl[15] = pl[30] = pl[31] = 1, R += 2*(w[9]/FAC + w[10]/FAC);\r
}\r
\r
void CopyBoard(int s)\r
{\r
- int i, j, k, cnt=0;\r
+ int i, j;\r
\r
/* copy game representation of engine to HistoryBoard */\r
/* don't forget castling rights and e.p. state! */\r
\r
void PrintVariants(int combo)\r
{\r
- int i, j, count=0, total=0; char c=EOF+1, buf[80];\r
+ int count=0, total=0; char c=EOF+1, buf[80];\r
FILE *f;\r
\r
f = fopen(INI_FILE, "r");\r
printf("feature done=1\n");\r
}\r
\r
-int LoadGame(char *name)\r
+void LoadGame(char *name)\r
{\r
int i, j, ptc, count=0; char c, buf[80], pieceToChar[80];\r
static int currentVariant;\r
\r
f = fopen(inifile, "r");\r
if(f==NULL)\r
- { printf("telluser piece-desription file '%s' not found\n", inifile);\r
+ { printf("telluser piece-description file '%s' not found\n", inifile);\r
exit(0);\r
}\r
if(fscanf(f, "version 4.8(%c)", &c)!=1 || c != 'w')\r
{ printf("telluser incompatible fmax.ini file\n"); exit(0); }\r
\r
- gating = 0;\r
+ gating = succession = 0;\r
if(name != NULL)\r
{ /* search for game name in definition file */\r
if(!strcmp(name, "makruk") && Cambodian) name = "cambodian"; else\r
{ od[++i]=j; centr[i] = c>='a';\r
blacktype[c&31]=i; piecename[i]=c&31;\r
if(piecetype[c&31]==0) piecetype[c&31]=i; // only first\r
+ succession |= w[i] < -4; // expendable royalty; assume we can promote to it\r
}\r
j++; o[j]=0;\r
/* printf("# c='%c' i=%d od[i]=%d j=%d (%3d,%8x)\n",c?c:' ',i,od[i],j,o[j-1],of[j-1]); /**/\r
\r
int main(int argc, char **argv)\r
{\r
- int Computer, MaxTime, MaxMoves, TimeInc, sec, i, j;\r
- char line[256], command[256], c, cc;\r
- int m, nr, hh;\r
+ int Computer, MaxTime, MaxMoves, TimeInc, sec, i;\r
+ char line[256], command[256], c;\r
+ int m, nr;\r
double cpuT;\r
- FILE *f;\r
\r
if(argc>1 && sscanf(argv[1], "%d", &m)==1)\r
{ U = (1<<m)-1; argc--; argv++; }\r
N=0;K=I;\r
if (D(Side,-I,I,Q,O,LL|S,3)==I) {\r
Side ^= BLACK^WHITE;\r
- if(UnderProm>=0 && UnderProm != L)\r
- { printf("tellics I hate under-promotions!\n");\r
- printf("resign { underpromotion } \n");\r
- Computer = EMPTY;\r
- continue;\r
- } else UnderProm = -1;\r
m = GetTickCount() - Ticks;\r
printf("# times @ %u: real=%d cpu=%1.0f\n", m + Ticks, m,\r
(CPUtime() - cpuT)/CLOCKS_PER_SEC);\r
printf("move ");\r
printf("%c%c%c%c",'a'+(K&15),'0'+BH-(K>>4),\r
'a'+(L&15),'0'+BH-(L>>4));\r
- if(prom)printf("%c",piecename[prom&15]+'a'-1);\r
+ if(prom)printf("%c",piecename[prom]+'a'-1);\r
printf("\n");\r
\r
/* time-control accounting */\r
continue;\r
}\r
if (!fgets(line, 256, stdin))\r
- return;\r
+ return 1;\r
if (line[0] == '\n')\r
continue;\r
sscanf(line, "%s", command);\r
}\r
if (!strcmp(command, "quit"))\r
/* exit engine */\r
- return;\r
+ return 0;\r
if (!strcmp(command, "force")) {\r
/* computer plays neither */\r
Computer = EMPTY;\r
if(sscanf(line+7, "Ini File=%s", filename) == 1) {\r
inifile = filename; continue;\r
}\r
- if(sscanf(line+7, "Clear Hash") == 1) for(i=0; i<=U; i++) A->K = 0;\r
+ if(sscanf(line+7, "Clear Hash%c", &c) == 1) for(i=0; i<=U; i++) A->K = 0;\r
if(sscanf(line+7, "MultiVariation Margin=%d", &margin) == 1) continue;\r
if(sscanf(line+7, "Variant fairy selects=%s", selectedFairy+6) == 1) continue;\r
if(sscanf(line+7, "Cambodian Makruk rules=%d", &Cambodian) == 1) continue;\r
continue;\r
}\r
if (!strcmp(command, "edit")) {\r
- int color = WHITE, p;\r
+ int color = WHITE, p, r;\r
\r
while(fgets(line, 256, stdin)) {\r
m = line[0];\r
} else\r
if(line[1] >= 'a' && line[1] <= 'a'+BW-1\r
&& line[2] >= '1' && line[2] <= '0'+BH) {\r
- m = line[1]-16*line[2]+799;\r
+ m = line[1]-16*line[2]+799; r = m & 0x70;\r
switch(p)\r
{\r
case 1:\r
case 2:\r
if(color==WHITE)\r
- b[m]=(m&0x70)==0x60?1:33,\r
- Q+=w[1];\r
- else b[m]=(m&0x70)==0x10?18:50,\r
- Q+=w[2];\r
+ b[m]=r==0x10?161:r==0x20?97:r==0x60?1:33,\r
+ Q+=w[1]+(r==0x10?S:r==0x20?64:0);\r
+ else b[m]=r==0x60?178:r==0x50?114:r==0x10?18:50,\r
+ Q+=w[2]+(r==0x60?S:r==0x50?64:0);\r
break;\r
default:\r
b[m]=p+color+32; // assume non-virgin\r
GT = (Side == WHITE ? piecetype : blacktype)[line[4]&31];\r
if(GT) PromPiece = (Side == WHITE ? 7 : 7+pm) - GT, GT |= 32 + Side;\r
{char *c=line; K=c[0]-16*c[1]+799;L=c[2]-16*c[3]+799; }\r
+ if(w[GT&15] == -1) L = S; // spoil move for promotion to King\r
if (m & line[1] != '@')\r
/* doesn't have move syntax */\r
printf("Error (unknown command): %s\n", command);\r