changes from H.G. Muller; version 4.3.8
[xboard.git] / backend.c
index 6c79b03..79bdc68 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -1367,9 +1367,8 @@ StringToVariant(e)
     if (!e) return v;\r
 \r
     /* [HGM] skip over optional board-size prefixes */\r
-    if( sscanf(e, "%dx%d+%d_", &i, &i, &i) == 3 ) {\r
-        while( *e++ != '_');\r
-    } else if( sscanf(e, "%dx%d_", &i, &i) == 2 ) {\r
+    if( sscanf(e, "%dx%d_", &i, &i) == 2 ||\r
+        sscanf(e, "%dx%d+%d_", &i, &i, &i) == 3 ) {\r
         while( *e++ != '_');\r
     }\r
 \r
@@ -1734,6 +1733,65 @@ CopyHoldings(Board board, char *holdings, ChessSquare lowestPiece)
 \r
 }\r
 \r
+void\r
+VariantSwitch(Board board, VariantClass newVariant)\r
+{\r
+   int newHoldingsWidth, newWidth = 8, newHeight = 8, i, j;\r
+   if(gameInfo.variant == newVariant) return;\r
+\r
+   /* [HGM] This routine is called each time an assignment is made to\r
+    * gameInfo.variant during a game, to make sure the board sizes\r
+    * are set to match the new variant. If that means adding or deleting\r
+    * holdings, we shift the playing board accordingly\r
+    */\r
+\r
+  if (appData.debugMode) {\r
+    fprintf(debugFP, "Switch board from %s to %s\n",\r
+               VariantName(gameInfo.variant), VariantName(newVariant));\r
+    setbuf(debugFP, NULL);\r
+  }\r
+    gameInfo.holdingsSize = 5; /* [HGM] prepare holdings */\r
+         switch(newVariant) {\r
+            case VariantShogi:\r
+            case VariantShowgi:\r
+              newWidth = 9;  newHeight = 9;\r
+              gameInfo.holdingsSize = 7;\r
+            case VariantBughouse:\r
+            case VariantCrazyhouse:\r
+              newHoldingsWidth = 2; break;\r
+            default:\r
+              newHoldingsWidth = gameInfo.holdingsSize = 0;\r
+    }\r
+\r
+    if(newWidth  != gameInfo.boardWidth  ||\r
+       newHeight != gameInfo.boardHeight ||\r
+       newHoldingsWidth != gameInfo.holdingsWidth ) {\r
+\r
+        /* shift position to new playing area, if needed */\r
+        if(newHoldingsWidth > gameInfo.holdingsWidth) {\r
+           for(i=0; i<BOARD_HEIGHT; i++) \r
+               for(j=BOARD_RGHT-1; j>=BOARD_LEFT; j--)\r
+                   board[i][j+newHoldingsWidth-gameInfo.holdingsWidth] =\r
+                                                     board[i][j];\r
+           for(i=0; i<newHeight; i++) {\r
+               board[i][0] = board[i][newWidth+2*newHoldingsWidth-1] = EmptySquare;\r
+               board[i][1] = board[i][newWidth+2*newHoldingsWidth-2] = (ChessSquare) 0;\r
+           }\r
+        } else if(newHoldingsWidth < gameInfo.holdingsWidth) {\r
+           for(i=0; i<BOARD_HEIGHT; i++)\r
+               for(j=BOARD_LEFT; j<BOARD_RGHT; j++)\r
+                   board[i][j+newHoldingsWidth-gameInfo.holdingsWidth] =\r
+                                                 board[i][j];\r
+        }\r
+\r
+        gameInfo.boardWidth  = newWidth;\r
+        gameInfo.boardHeight = newHeight;\r
+        gameInfo.holdingsWidth = newHoldingsWidth;\r
+        gameInfo.variant = newVariant;\r
+        InitDrawingSizes(-2, 0);\r
+    } else gameInfo.variant = newVariant;\r
+}\r
+\r
 static int loggedOn = FALSE;\r
 \r
 /*-- Game start info cache: --*/\r
@@ -2332,12 +2390,11 @@ read_from_ics(isr, closure, data, count, error)
              "* * match, initial time: * minute*, increment: * second")) {\r
                /* Header for a move list -- second line */\r
                /* Initial board will follow if this is a wild game */\r
-\r
                if (gameInfo.event != NULL) free(gameInfo.event);\r
                sprintf(str, "ICS %s %s match", star_match[0], star_match[1]);\r
                gameInfo.event = StrSave(str);\r
-               gameInfo.variant = StringToVariant(gameInfo.event);\r
-                Reset(TRUE,TRUE); /* [HGM] possibly change board or holdings size */\r
+                /* [HGM] we switched variant. Translate boards if needed. */\r
+                VariantSwitch(boards[currentMove], StringToVariant(gameInfo.event));\r
                continue;\r
            }\r
 \r
@@ -2802,7 +2859,8 @@ read_from_ics(isr, closure, data, count, error)
                    started = STARTED_NONE;\r
                    parse[parse_pos] = NULLCHAR;\r
                    if (appData.debugMode)\r
-                     fprintf(debugFP, "Parsing holdings: %s\n", parse);\r
+                      fprintf(debugFP, "Parsing holdings: %s, currentMove = %d\n",\r
+                                                        parse, currentMove);\r
                    if (sscanf(parse, " game %d", &gamenum) == 1 &&\r
                        gamenum == ics_gamenum) {\r
                        if (gameInfo.variant == VariantNormal) {\r
@@ -2811,22 +2869,7 @@ read_from_ics(isr, closure, data, count, error)
                            * to move the position two files to the right to\r
                            * create room for them!\r
                            */\r
-                          int i, j;\r
-                          if(gameInfo.holdingsWidth == 0) /* to be sure */\r
-                          for(i=0; i<BOARD_HEIGHT; i++)\r
-                            for(j=BOARD_RGHT-1; j>=0; j--)\r
-                              boards[currentMove][i][j+2] = boards[currentMove][i][j];\r
-\r
-  if (appData.debugMode) {\r
-    fprintf(debugFP, "Switch board to Crazy\n");\r
-    setbuf(debugFP, NULL);\r
-  }\r
-                         gameInfo.variant = VariantCrazyhouse; /*temp guess*/\r
-                          gameInfo.boardWidth  = 8;  /* [HGM] guess board size as well */\r
-                          gameInfo.boardHeight = 8;\r
-                          gameInfo.holdingsSize = 5;\r
-                          gameInfo.holdingsWidth = 2;\r
-                          InitDrawingSizes(-2, 0);\r
+                          VariantSwitch(boards[currentMove], VariantCrazyhouse); /* temp guess */\r
                          /* Get a move list just to see the header, which\r
                             will tell us whether this is really bug or zh */\r
                          if (ics_getting_history == H_FALSE) {\r
@@ -2862,7 +2905,7 @@ read_from_ics(isr, closure, data, count, error)
                                    gameInfo.black, black_holding);\r
                        }\r
 \r
-                       DrawPosition(FALSE, NULL);\r
+                        DrawPosition(FALSE, boards[currentMove]);\r
                        DisplayTitle(str);\r
                    }\r
                    /* Suppress following prompt */\r
@@ -3078,27 +3121,13 @@ ParseBoard12(string)
        timeIncrement = increment * 1000;\r
        movesPerSession = 0;\r
        gameInfo.timeControl = TimeControlTagValue();\r
-       gameInfo.variant = StringToVariant(gameInfo.event);\r
+        VariantSwitch(board, StringToVariant(gameInfo.event) );\r
   if (appData.debugMode) {\r
     fprintf(debugFP, "ParseBoard says variant = '%s'\n", gameInfo.event);\r
     fprintf(debugFP, "recognized as %s\n", VariantName(gameInfo.variant));\r
     setbuf(debugFP, NULL);\r
   }\r
 \r
-        gameInfo.holdingsSize = 5; /* [HGM] prepare holdings */\r
-        gameInfo.boardWidth = gameInfo.boardHeight = 8;\r
-        switch(gameInfo.variant) {\r
-            case VariantShogi:\r
-            case VariantShowgi:\r
-              gameInfo.boardWidth = 9;  gameInfo.boardHeight = 9;\r
-              gameInfo.holdingsSize = 7;\r
-            case VariantBughouse:\r
-            case VariantCrazyhouse:\r
-              gameInfo.holdingsWidth = 2; break;\r
-            default:\r
-              gameInfo.holdingsWidth = gameInfo.holdingsSize = 0;\r
-        }\r
-        InitDrawingSizes(-2, 0);\r
         gameInfo.outOfBook = NULL;\r
        \r
        /* Do we have the ratings? */\r
@@ -3237,7 +3266,7 @@ ParseBoard12(string)
     if (moveNum > 0) {\r
   if (appData.debugMode) {\r
     fprintf(debugFP, "accepted move %s from ICS, parse it.\n", move_str);\r
-    fprintf(debugFP, "board = %d-d x%d\n", BOARD_LEFT, BOARD_RGHT, BOARD_HEIGHT);\r
+    fprintf(debugFP, "board = %d-%d x %d\n", BOARD_LEFT, BOARD_RGHT, BOARD_HEIGHT);\r
     setbuf(debugFP, NULL);\r
   }\r
        if (moveNum <= backwardMostMove) {\r
@@ -3592,8 +3621,8 @@ AlphaRank(char *move, int n)
     if( !appData.alphaRank ) return;\r
 \r
     while(c = *p) {\r
-        if(c>='0' && c<='9') *p += 'a'-'0'; else\r
-        if(c>='a' && c<='z') *p -= 'a'-'0';\r
+        if(c>='0' && c<='9') *p += AAA-ONE; else\r
+        if(c>='a' && c<'x') *p -= AAA-ONE;\r
         p++;\r
         if(--n < 1) break;\r
     }\r
@@ -5075,7 +5104,7 @@ HandleMachineMove(message, cps)
     if (!strncmp(message, "setboard ", 9)) {\r
         Board initial_position; int i;\r
 \r
-        GameEnds(GameIsDrawn, "Engine aborts game", GE_XBOARD);\r
+        GameEnds(GameUnfinished, "Engine aborts game", GE_XBOARD);\r
 \r
         if (!ParseFEN(initial_position, &blackPlaysFirst, message + 9)) {\r
             DisplayError("Bad FEN received from engine", 0);\r
@@ -11818,8 +11847,8 @@ PositionToFEN(move, useFEN960)
        *p++ = '-';\r
     }\r
 \r
-    /* [HGM] print Crazyhouse holdings */\r
-    if( gameInfo.variant == VariantCrazyhouse ) {\r
+    /* [HGM] print Crazyhouse or Shogi holdings */\r
+    if( gameInfo.holdingsWidth ) {\r
         *p++ = ' '; q = p;\r
         for(i=0; i<gameInfo.holdingsSize; i++) { /* white holdings */\r
             piece = boards[move][i][BOARD_WIDTH-1];\r