Bump version number to 4.8S
[fairymax.git] / fairymax.c
index 91fe48d..ffa6ca8 100644 (file)
@@ -18,7 +18,7 @@
      /*****************************************************************/\r
 \r
 #define MULTIPATH\r
-#define VERSION "4.8R"\r
+#define VERSION "4.8S"\r
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -98,14 +98,13 @@ int MovesLeft;
 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
@@ -140,7 +139,7 @@ n[]=".*XKNBRQEWFMACHG?x+knbrqewfmachg";        /* piece symbols on printout*/
 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
@@ -151,7 +150,7 @@ int k,q,l,e,E,z,n;      /* (q,l)=window, e=current eval. score, E=e.p. sqr.*/
 {                       /* 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
- struct _*a=A+(J+(k+S)*E&U-1);                 /* lookup pos. in hash table*/\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
  d=a->D;m=a->V;X=a->F;Y=a->Y;                  /* resume at stored depth   */\r
@@ -188,7 +187,7 @@ int k,q,l,e,E,z,n;      /* (q,l)=window, e=current eval. score, E=e.p. sqr.*/
       }\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
@@ -324,7 +323,7 @@ if(z&4*S)K=X,L=Y&~S;
 \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
@@ -365,8 +364,12 @@ int PrintResult(int s)
         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
@@ -377,17 +380,15 @@ int PrintResult(int s)
 }\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
@@ -406,14 +407,14 @@ InitGame()
   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
@@ -424,7 +425,7 @@ void CopyBoard(int s)
                                          \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
@@ -461,7 +462,7 @@ void PrintOptions()
        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
@@ -469,13 +470,13 @@ int LoadGame(char *name)
 \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
@@ -510,6 +511,7 @@ int LoadGame(char *name)
             { 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
@@ -531,11 +533,10 @@ int LoadGame(char *name)
 \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
@@ -575,12 +576,6 @@ int main(int argc, char **argv)
                         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
@@ -614,7 +609,7 @@ int main(int argc, char **argv)
                         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
@@ -666,7 +661,7 @@ int main(int argc, char **argv)
                }\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
@@ -747,7 +742,7 @@ int main(int argc, char **argv)
                        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
@@ -884,6 +879,7 @@ int main(int argc, char **argv)
                 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