Warnings: correctly use #ifdef for declarations.
[gnushogi.git] / gnushogi / commondsp.c
index 40bfd22..14fd387 100644 (file)
@@ -6,6 +6,7 @@
  * ----------------------------------------------------------------------
  * Copyright (c) 1993, 1994, 1995 Matthias Mutz
  * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
+ * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
  *
  * GNU SHOGI is based on GNU CHESS
  *
  *
  */
 
+/* request *snprintf prototypes */
+#define _POSIX_C_SOURCE 200112L
+#include <stdio.h>
+
 #if defined HAVE_GETTIMEOFDAY
 #include <sys/time.h>
 #endif
 #include "gnushogi.h"
 
 char mvstr[4][6];
-char *InPtr;
-int InBackground = false;
+int mycnt1, mycnt2;
+static char *InPtr;
 struct display *dsp = &raw_display;
 
+short xboard = false;
 
 #if defined(BOOKTEST)
 
@@ -89,20 +95,20 @@ movealgbr(short m, char *s)
         s++;
         *s = '*';
         s++;
-        *s = cxx[column(t)];
+        *s = COL_NAME(column(t));
         s++;
-        *s = rxx[row(t)];
+        *s = ROW_NAME(row(t));
         s++;
     }
     else
     {
-        *s = cxx[column(f)];
+        *s = COL_NAME(column(f));
         s++;
-        *s = rxx[row(f)];
+        *s = ROW_NAME(row(f));
         s++;
-        *s = cxx[column(t)];
+        *s = COL_NAME(column(t));
         s++;
-        *s = rxx[row(t)];
+        *s = ROW_NAME(row(t));
         s++;
 
         if (flag & promote)
@@ -133,7 +139,10 @@ movealgbr(short m, char *s)
  *   - NO_SQUARES <= f NO_SQUARES + 2*NO_PIECES                dropped piece modulo NO_PIECES
  * - t & 0x7f                          target square
  * - t & 0x80                          promotion flag
- * - flag                              FIXME: must be zero ?
+ * - flag
+ *   - if flag & dropmask, piece type encoded in flag & pmask
+ *
+ * FIXME: that makes 2 ways to specify drops and promotions, why ?
  *
  * OUTPUT:
  * - GLOBAL mvstr
@@ -162,7 +171,7 @@ algbr(short f, short t, short flag)
 
     if ((f == t) && ((f != 0) || (t != 0)))
     {
-        if (!barebones) {
+        if (!XSHOGI) {
             dsp->Printf("error in algbr: FROM=TO=%d, flag=0x%4x\n", t, flag);
         }
 
@@ -173,9 +182,9 @@ algbr(short f, short t, short flag)
         short piece = flag & pmask;
 
         mvstr[0][0] = pxx[piece];
-        mvstr[0][1] = '*';
-        mvstr[0][2] = cxx[column(t)];
-        mvstr[0][3] = rxx[row(t)];
+        mvstr[0][1] = xboard ? '@' : '*';
+        mvstr[0][2] = COL_NAME(column(t));
+        mvstr[0][3] = ROW_NAME(row(t));
         mvstr[0][4] = '\0';
         strcpy(mvstr[1], mvstr[0]);
         strcpy(mvstr[2], mvstr[0]);
@@ -183,20 +192,27 @@ algbr(short f, short t, short flag)
     }
     else if ((f != 0) || (t != 0))
     {
-        /* algebraic notation */
-        mvstr[0][0] = cxx[column(f)];
-        mvstr[0][1] = rxx[row(f)];
-        mvstr[0][2] = cxx[column(t)];
-        mvstr[0][3] = rxx[row(t)];
-        mvstr[0][4] = mvstr[3][0] = '\0';
+        /* pure coordinates notation */
+        mvstr[0][0] = COL_NAME(column(f));
+        mvstr[0][1] = ROW_NAME(row(f));
+        mvstr[0][2] = COL_NAME(column(t));
+        mvstr[0][3] = ROW_NAME(row(t));
+        mvstr[0][4] = '\0';
+
+        /* algebraic notation without disambiguation */
         mvstr[1][0] = pxx[board[f]];
+        mvstr[1][1] = mvstr[0][2];    /* to column */
+        mvstr[1][2] = mvstr[0][3];    /* to row */
+        mvstr[1][3] = '\0';
 
+        /* algebraic notation with row disambiguation */
         mvstr[2][0] = mvstr[1][0];
         mvstr[2][1] = mvstr[0][1];
+        mvstr[2][2] = mvstr[0][2];    /* to column */
+        mvstr[2][3] = mvstr[0][3];    /* to row */
+        mvstr[2][4] = '\0';
 
-        mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
-        mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
-        mvstr[2][4] = mvstr[1][3] = '\0';
+        /* algebraic notation with column disambiguation */
         strcpy(mvstr[3], mvstr[2]);
         mvstr[3][1] = mvstr[0][0];
 
@@ -295,7 +311,7 @@ VerifyMove(char *s, VerifyMove_mode iop, unsigned short *mv)
         if (SqAttacked(PieceList[opponent][0], computer, &blocked))
         {
             UnmakeMove(opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
-            dsp->AlwaysShowMessage("Illegal move (in check) %s", s);
+            dsp->AlwaysShowMessage("Illegal move (in check): %s", s);
             return false;
         }
         else
@@ -337,9 +353,9 @@ VerifyMove(char *s, VerifyMove_mode iop, unsigned short *mv)
         }
     }
 
-    dsp->AlwaysShowMessage("Illegal move (no match) %s", s);
+    dsp->AlwaysShowMessage("Illegal move (no match): %s", s);
 
-    if (!barebones && (cnt > 1))
+    if (!XSHOGI && (cnt > 1))
     {
         sprintf(buffer, "Ambiguous Move %s!", s);
         dsp->ShowMessage(buffer);
@@ -369,17 +385,17 @@ parser(char *f, short *fpiece)
 
     if (f[1] == '*' || f[1] == '\'')
     {
-        c2 = COL_NAME(f[2]);
-        r2 = ROW_NAME(f[3]);
+        c2 = COL_NUM(f[2]);
+        r2 = ROW_NUM(f[3]);
 
         return ((NO_SQUARES + *fpiece) << 8) | locn(r2, c2);
     }
     else
     {
-        c1 = COL_NAME(f[1]);
-        r1 = ROW_NAME(f[2]);
-        c2 = COL_NAME(f[3]);
-        r2 = ROW_NAME(f[4]);
+        c1 = COL_NUM(f[1]);
+        r1 = ROW_NUM(f[2]);
+        c2 = COL_NUM(f[3]);
+        r2 = ROW_NUM(f[4]);
         p = (f[5] == '+') ? 0x80 : 0;
 
         return (locn(r1, c1) << 8) | locn(r2, c2) | p;
@@ -424,7 +440,7 @@ void RequestInputString(char* buffer, unsigned bufsize)
 }
 
 
-void
+static void
 GetGame(void)
 {
     FILE *fd;
@@ -647,7 +663,7 @@ GetGame(void)
 }
 
 
-void
+static void
 SaveGame(void)
 {
     FILE *fd;
@@ -799,7 +815,7 @@ SaveGame(void)
  * xshogi wasn't defined -- wonder why?
  */
 
-void
+static void
 GetXGame(void)
 {
     FILE *fd;
@@ -928,7 +944,7 @@ GetXGame(void)
 }
 
 
-void
+static void
 SaveXGame(void)
 {
     FILE *fd;
@@ -1008,7 +1024,7 @@ SaveXGame(void)
 }
 
 
-void
+static void
 BookSave(void)
 {
     FILE *fd;
@@ -1227,7 +1243,7 @@ ListGame(void)
 }
 
 
-void
+static void
 FlagMove(char c)
 {
     switch(c)
@@ -1253,7 +1269,7 @@ FlagMove(char c)
  * Undo the most recent half-move.
  */
 
-void
+static void
 Undo(void)
 {
     short f, t;
@@ -1310,59 +1326,7 @@ Undo(void)
 }
 
 
-void
-FlagString(unsigned short flags, char *s)
-{
-    short l, piece;
-    *s = '\0';
-
-    if (flags & promote)
-        strcat(s, " promote");
-
-    if (flags & dropmask)
-        strcat(s, " drop:");
-
-    if ((piece = (flags & pmask)))
-    {
-        l = strlen(s);
-
-        if (is_promoted[piece])
-            s[l++] = '+';
-
-        s[l++] = pxx[piece];
-        s[l] = '\0';
-    }
-
-    if (flags & capture)
-        strcat(s, " capture");
-
-    if (flags & exact)
-        strcat(s, " exact");
-
-    if (flags & tesuji)
-        strcat(s, " tesuji");
-
-    if (flags & check)
-        strcat(s, " check");
-
-    if (flags & draw)
-        strcat(s, " draw");
-
-    if (flags & stupid)
-        strcat(s, " stupid");
-
-    if (flags & questionable)
-        strcat(s, " questionable");
-
-    if (flags & kingattack)
-        strcat(s, " kingattack");
-
-    if (flags & book)
-        strcat(s, " book");
-}
-
-
-void
+static void
 TestSpeed(void(*f)(short side, short ply,
                    short in_check, short blockable),
           unsigned j)
@@ -1416,7 +1380,7 @@ TestSpeed(void(*f)(short side, short ply,
 }
 
 
-void
+static void
 TestPSpeed(short(*f) (short side), unsigned j)
 {
     unsigned i;
@@ -1453,21 +1417,18 @@ TestPSpeed(short(*f) (short side), unsigned j)
 }
 
 
-void
-SetOppTime(char *s)
+static void
+SetOppTime(char *time)
 {
-    char *time;
-    int m, t, sec;
+    int m, t;
 
-    sec = 0;
-    time = &s[strlen("otime")];
     t = (int)strtol(time, &time, 10);
 
     if (*time == ':')
     {
         time++;
        /* FIXME: sec is parsed but ignored */
-        sec = (int)strtol(time, &time, 10);
+        (void)strtol(time, &time, 10);
     }
 
     m = (int)strtol(time, &time, 10);
@@ -1488,21 +1449,18 @@ SetOppTime(char *s)
 }
 
 
-void
-SetMachineTime(char *s)
+static void
+SetMachineTime(char *time)
 {
-    char *time;
-    int m, t, sec;
+    int m, t;
 
-    time = &s[strlen("time")];
-    sec = 0;
     t = (int)strtol(time, &time, 10);
 
     if (*time == ':')
     {
         time++;
        /* FIXME: sec is parsed but ignored */
-        sec = (int)strtol(time, &time, 10);
+        (void)strtol(time, &time, 10);
     }
 
     m = (int)strtol(time, &time, 10);
@@ -1529,16 +1487,16 @@ SetMachineTime(char *s)
  * Process the user's command. If easy mode is OFF (the computer is thinking
  * on opponents time) and the program is out of book, then make the 'hint'
  * move on the board and call SelectMove() to find a response. The user
- * terminates the search by entering ^C (quit siqnal) before entering a
- * command. If the opponent does not make the hint move, then set Sdepth to
- * zero.
+ * terminates the search by entering a command. If the opponent does not make
+ * the hint move, then set Sdepth to zero.
  */
 
 void
 InputCommand(char *command)
 {
-    int eof = 0;
+#ifdef QUIETBACKGROUND
     short have_shown_prompt = false;
+#endif
     short ok, done, is_move = false;
     unsigned short mv;
     char s[80], sx[80];
@@ -1564,10 +1522,8 @@ InputCommand(char *command)
         algbr((short) hint >> 8, (short) hint & 0xff, false);
         strcpy(s, mvstr[0]);
 
-#if !defined NOPOST
         if (flag.post)
             dsp->GiveHint();
-#endif
 
         /* do the hint move */
         if (VerifyMove(s, VERIFY_AND_TRY_MODE, &mv))
@@ -1631,21 +1587,16 @@ InputCommand(char *command)
 #endif /* QUIETBACKGROUND */
 
         if (command == NULL) {
-            if (NOT_CURSES)
-                s[0] = '\0';
-
-            eof = dsp->GetString(sx);
+            int eof = dsp->GetString(sx);
+            if (eof)
+                dsp->ExitShogi();
         } else {
             strcpy(sx, command);
             done = true;
         }
 
-        sscanf(sx, "%s", s);
-
-        if (eof)
-            dsp->ExitShogi();
-
-        if (s[0] == '\0')
+        /* extract first word */
+        if (sscanf(sx, "%s", s) < 1)
             continue;
 
         if (strcmp(s, "bd") == 0)   /* bd -- display board */
@@ -1664,29 +1615,45 @@ InputCommand(char *command)
         }
         else if (strcmp(s, "post") == 0)
         {
-            flag.post = !flag.post;
+            flag.post = (xboard ? 1 : !flag.post);
         }
-        else if (strcmp(s, "alg") == 0)
+        else if (strcmp(s, "nopost") == 0)
         {
-            /* noop */ ; /* alg */
+            flag.post = 0;
+        }
+        else if (strcmp(s, "alg") == 0 ||
+                 strcmp(s, "accepted") == 0 || strcmp(s, "rejected") == 0 ||
+                 strcmp(s, "variant") == 0 || strcmp(s, "computer") == 0)
+        {
+            /* noop */ ;
         }
         else if ((strcmp(s, "quit") == 0)
                  || (strcmp(s, "exit") == 0))
         {
             flag.quit = true;
         }
-#if !defined NOPOST
-        else if (strcmp(s, "post") == 0)
+        else if (strcmp(s, "xboard") == 0)
         {
-            flag.post = !flag.post;
+            xboard = true;
+            strcpy(ColorStr[0], "White");
+            strcpy(ColorStr[1], "Black");
         }
+        else if (strcmp(s, "protover") == 0)
+        {
+            printf("feature myname=\"GNU %sShogi %s\" variants=\"%sshogi\" debug=1 setboard=0 sigint=0 done=1\n",
+#ifdef MINISHOGI
+                                       "mini", PACKAGE_VERSION, "5x5+5_"
+#else
+                                         "",   PACKAGE_VERSION, ""
 #endif
+                  );
+        }
         else if ((strcmp(s, "set") == 0)
                  || (strcmp(s, "edit") == 0))
         {
             dsp->EditBoard();
         }
-        else if ((strcmp(s, "setup") == 0))
+        else if (strcmp(s, "setup") == 0)
         {
             dsp->SetupBoard();
         }
@@ -1744,10 +1711,13 @@ InputCommand(char *command)
         {
             ListGame();
         }
-        else if ((strcmp(s, "level") == 0)
-                 || (strcmp(s, "clock") == 0))
+        else if (strcmp(s, "level") == 0)
+        {
+            dsp->SelectLevel(sx + strlen("level"));
+        }
+        else if (strcmp(s, "clock") == 0)
         {
-            dsp->SelectLevel(sx);
+            dsp->SelectLevel(sx + strlen("clock"));
         }
         else if (strcmp(s, "hash") == 0)
         {
@@ -1763,11 +1733,12 @@ InputCommand(char *command)
         }
         else if (strcmp(s, "time") == 0)
         {
-            SetMachineTime(sx);
+            SetMachineTime(sx + strlen("time"));
         }
-        else if (strcmp(s, "otime") == 0)
+        else if ((strcmp(s, "otime") == 0) ||
+                 (xboard && (strcmp(s, "otim")) == 0))
         {
-            SetOppTime(sx);
+            SetOppTime(sx + strlen("otime"));
         }
         else if (strcmp(s, "Awindow") == 0)
         {
@@ -1808,8 +1779,9 @@ InputCommand(char *command)
             flag.force = false;
             Sdepth = 0;
             ok = true;
+            dsp->UpdateDisplay(0, 0, 1, 0);
         }
-        else if (strcmp(s, "black") == 0)
+        else if (xboard ? strcmp(s, "white") == 0 : strcmp(s, "black") == 0)
         {
             computer = white;
             opponent = black;
@@ -1821,7 +1793,7 @@ InputCommand(char *command)
              * ok = true; don't automatically start with black command
              */
         }
-        else if (strcmp(s, "white") == 0)
+        else if (xboard ? strcmp(s, "black") == 0 : strcmp(s, "white") == 0)
         {
             computer = black;
             opponent = white;
@@ -1876,7 +1848,11 @@ InputCommand(char *command)
         }
         else if (strcmp(s, "depth") == 0)
         {
-            dsp->ChangeSearchDepth();
+            dsp->ChangeSearchDepth(sx + strlen("depth"));
+        }
+        else if (strcmp(s, "sd") == 0)
+        {
+            dsp->ChangeSearchDepth(sx + strlen("sd"));
         }
         else if (strcmp(s, "hashdepth") == 0)
         {
@@ -2021,45 +1997,5 @@ InputCommand(char *command)
             printf("%d. %s %ld\n",
                    ++mycnt2, s, TimeControl.clock[player] * 10);
         }
-
-#ifdef notdef /* optional pass best line to frontend with move */
-#  if !defined NOPOST
-
-        if (flag.post && !flag.mate)
-        {
-            int i;
-
-            printf(" %6d ", MSCORE);
-
-            for (i = 1; MV[i] > 0; i++)
-            {
-                algbr((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
-                printf("%5s ", mvstr[0]);
-            }
-        }
-#  endif
-        printf("\n");
-#endif
-    }
-}
-
-
-void
-SetTimeControl(void)
-{
-    if (TCflag)
-    {
-        TimeControl.moves[black] = TimeControl.moves[white] = TCmoves;
-        TimeControl.clock[black] += 6000L * TCminutes + TCseconds * 100;
-        TimeControl.clock[white] += 6000L * TCminutes + TCseconds * 100;
     }
-    else
-    {
-        TimeControl.moves[black] = TimeControl.moves[white] = 0;
-        TimeControl.clock[black] = TimeControl.clock[white] = 0;
-    }
-
-    flag.onemove = (TCmoves == 1);
-    et = 0;
-    ElapsedTime(COMPUTE_AND_INIT_MODE);
 }