Implement S-Chess
authorH.G. Muller <h.g.muller@hccnet.nl>
Tue, 29 Nov 2011 17:05:44 +0000 (18:05 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 29 Nov 2011 17:14:37 +0000 (18:14 +0100)
The value drops=2 in the gameState controls whether gating in pieces
from the holdings is possible, and implies holdings even if holdings=0.
New incarations of Cardinal and Marshall are added to the piece types,
under the names H and E. Gating has to be entered as promotion ('/' in
stead of '=' is allowed). King does no longer have to be the last piece
type; a macro PIECES has been added to indicate the number of piece types.

lasker-2.2.3/data/boards/seirawan/0 [new file with mode: 0644]
lasker-2.2.3/src/Makefile.in
lasker-2.2.3/src/algcheck.c
lasker-2.2.3/src/board.c
lasker-2.2.3/src/board.h
lasker-2.2.3/src/gameproc.c
lasker-2.2.3/src/matchproc.c
lasker-2.2.3/src/movecheck.c

diff --git a/lasker-2.2.3/data/boards/seirawan/0 b/lasker-2.2.3/data/boards/seirawan/0
new file mode 100644 (file)
index 0000000..e627474
--- /dev/null
@@ -0,0 +1,3 @@
+S 8x8 g
+W: P a2 b2 c2 d2 e2 f2 g2 h2 N b1 g1 B c1 f1 Q d1 K e1 R a1 h1 D @ U @
+B: P a7 b7 c7 d7 e7 f7 g7 h7 N b8 g8 B c8 f8 Q d8 K e8 R a8 h8 D @ U @
index 531038e..b0aff55 100644 (file)
@@ -141,6 +141,7 @@ install: $(ALL)
        install -d -m0755 ${CHESSDDIR}/data/boards/courier
        install -d -m0755 ${CHESSDDIR}/data/boards/fairy
        install -d -m0755 ${CHESSDDIR}/data/boards/great
+       install -d -m0755 ${CHESSDDIR}/data/boards/seirawan
        install -d -m0755 ${CHESSDDIR}/games/history
        install -d -m0755 ${CHESSDDIR}/games/journal
        install -d -m0755 ${CHESSDDIR}/games/adjourned
@@ -166,6 +167,7 @@ install: $(ALL)
        cp -u ${srcdir}/../data/boards/fairy/* ${CHESSDDIR}/data/boards/fairy
        cp -u ${srcdir}/../data/boards/great/* ${CHESSDDIR}/data/boards/great
        cp -u ${srcdir}/../data/boards/caparandom/* ${CHESSDDIR}/data/boards/caparandom
+       cp -u ${srcdir}/../data/boards/seirawan/* ${CHESSDDIR}/data/boards/seirawan
        perl -e 'mkdir("${CHESSDDIR}/players/$$_",0755) for ("a".."z")'
        perl -e 'mkdir("${CHESSDDIR}/games/history/$$_",0755) for ("0".."99")'
        perl -e 'mkdir("${CHESSDDIR}/games/journal/$$_",0755) for ("a".."z")'
index 3efc4ce..aa7d5af 100644 (file)
@@ -106,9 +106,9 @@ static int get_move_info(const char *str, int *piece, int *ff, int *fr, int *tf,
       case 'r':
        if ((tmp[j] < '0') || (tmp[j] > '9')) // [HGM] also match 0- and 9-rank
          goto nomatch;
-       if (ltr == ALG_UNKNOWN)\r
-         ltr = tmp[j] - '0'; // [HGM] allow 0-rank for Xiangqi, correct later\r
-       else\r
+       if (ltr == ALG_UNKNOWN)
+         ltr = tmp[j] - '0'; // [HGM] allow 0-rank for Xiangqi, correct later
+       else
          lfr = tmp[j] - '0';
        break;
       case 'p':
@@ -261,18 +261,18 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
        case 'q':
                piece = QUEEN;
                break;
-       case 'c':\r
-               if(!gs->capablancaPieces) return; // [HGM] should make variant-dependent piece mask\r
-               piece = MARSHALL;\r
-               break;\r
-       case 'a':\r
-               if(!gs->capablancaPieces) return;\r
-               piece = CARDINAL;\r
-               break;\r
-       case 'm':\r
-               if(!gs->royalKnight) return; // [HGM] only in knightmate\r
-               piece = MAN;\r
-               break;\r
+       case 'c':
+               if(!gs->capablancaPieces) return; // [HGM] should make variant-dependent piece mask
+               piece = MARSHALL;
+               break;
+       case 'a':
+               if(!gs->capablancaPieces) return;
+               piece = CARDINAL;
+               break;
+       case 'm':
+               if(!gs->royalKnight) return; // [HGM] only in knightmate
+               piece = MAN;
+               break;
        case 'r':
                piece = ROOK;
                break;
@@ -280,7 +280,7 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
                piece = BISHOP;
                break;
        case 'n':
-               if(gs->royalKnight) return; // [HGM] not in knightmate\r
+               if(gs->royalKnight) return; // [HGM] not in knightmate
                piece = KNIGHT;
                break;
        // Superchess promotons: filtered out later by promoType
@@ -296,18 +296,22 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
        case 'v':
                piece = CENTAUR;
                break;
-       case 'e':\r
-               piece = EMPRESS;
+       case 'e':
+               piece = gs->drops == 2 ? SELEPHANT : EMPRESS; // for Seirawan
                break;
        case 's':
                piece = PRINCESS;
                break;
+       case 'h':
+               if(gs->drops != 2) return;
+               piece = HAWK;
+               break;
        default:
                return;
        }
        i = colorval(gs->board[mt->fromFile][mt->fromRank]) == WHITE ? 0 : 1;
        if(gs->promoType == 2 && gs->holding[i][piece-1] == 0) return; // only if piece was captured
-       if(piece >= WOODY && (gs->promoType != 2 || gs->promoZone == 3)) return; // reserved for Superchess
+       if(piece >= WOODY && piece < KING && (gs->promoType != 2 || gs->promoZone == 3)) return; // reserved for Superchess
 
        mt->piecePromotionTo = piece | colorval(gs->board[mt->fromFile][mt->fromRank]);
 }
@@ -322,13 +326,13 @@ int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
     d_printf( "CHESSD: Shouldn't try to algebraicly parse non-algabraic move string.\n");
     return MOVE_ILLEGAL;
   }
-  // [HGM] check if move does not stray off board\r
-  if(gs->ranks < 10) { \r
-    if(tr == 0 || fr == 0) return MOVE_ILLEGAL; // used nonexistent 0-rank\r
-    if(tr != ALG_UNKNOWN) tr--; if(fr != ALG_UNKNOWN) fr--; // shift to lowest rank = 1\r
-  }\r
-  if(tr >= gs->ranks || fr >= gs->ranks || tf >= gs->files || ff >= gs->files)\r
-    return MOVE_ILLEGAL;\r
+  // [HGM] check if move does not stray off board
+  if(gs->ranks < 10) { 
+    if(tr == 0 || fr == 0) return MOVE_ILLEGAL; // used nonexistent 0-rank
+    if(tr != ALG_UNKNOWN) tr--; if(fr != ALG_UNKNOWN) fr--; // shift to lowest rank = 1
+  }
+  if(tr >= gs->ranks || fr >= gs->ranks || tf >= gs->files || ff >= gs->files)
+    return MOVE_ILLEGAL;
 
   // [HGM] resolve ambiguity in piece, type based on variant
   switch(piece) {
@@ -371,7 +375,7 @@ int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
       if(strstr(gs->variant, "great")) piece = MASTODON;
       break;
   }
-\r
+
   /* Resolve ambiguities in to-ness */
   if (tf == ALG_UNKNOWN) {
          d_printf("Ambiguous %s(%d)\n", __FUNCTION__, __LINE__);
@@ -521,14 +525,14 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     piece = piecetype(gs->board[mt->fromFile][mt->fromRank]);
   }
 
-  if ((mt->fromFile == ALG_CASTLE) && (mt->toFile > mt->toRank)) { // [HGM] castle: K ends right of R\r
-    strcpy(mStr, "O-O");\r
-    goto check;\r
-  }\r
-  if ((mt->fromFile == ALG_CASTLE) && (mt->toFile < mt->toRank)) { // [HGM] castle: K ends left of R\r
-    strcpy(mStr, "O-O-O");\r
-    goto check;\r
-  }\r
+  if ((mt->fromFile == ALG_CASTLE) && (mt->toFile > mt->toRank)) { // [HGM] castle: K ends right of R
+    strcpy(mStr, "O-O");
+    goto check;
+  }
+  if ((mt->fromFile == ALG_CASTLE) && (mt->toFile < mt->toRank)) { // [HGM] castle: K ends left of R
+    strcpy(mStr, "O-O-O");
+    goto check;
+  }
   strcpy(mStr, "");
   switch (piece) {
   case PAWN:
@@ -551,16 +555,16 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     break;
   case ALFIL2:
   case AMAZON:
-  case CARDINAL:\r
-    strcpy(mStr, "A");\r
-    break;\r
+  case CARDINAL:
+    strcpy(mStr, "A");
+    break;
   case CANNON:
-  case MARSHALL:\r
-    strcpy(mStr, "C");\r
-    break;\r
-  case MAN:\r
-    strcpy(mStr, "M");\r
-    break;\r
+  case MARSHALL:
+    strcpy(mStr, "C");
+    break;
+  case MAN:
+    strcpy(mStr, "M");
+    break;
   case FERZ:
   case QUEEN:
     strcpy(mStr, "Q");
@@ -625,8 +629,8 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
   /* Checks for ambiguity in short notation ( Ncb3, R8e8 or so) */
   if (piece != PAWN) {
     ambig = r_ambig = f_ambig = 0;
-    for (r = 0; r < gs->ranks; r++)\r
-      for (f = 0; f < gs->files; f++) {\r
+    for (r = 0; r < gs->ranks; r++)
+      for (f = 0; f < gs->files; f++) {
        if ((gs->board[f][r] != NOPIECE) && iscolor(gs->board[f][r], gs->onMove)
            && (piecetype(gs->board[f][r]) == piece) &&
            ((f != mt->fromFile) || (r != mt->fromRank))) {
@@ -660,87 +664,89 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
          }
        }
       }
-    if (ambig > 0) {\r
-      /* Ambiguity in short notation, need to add file,rank or _both_ in\r
-         notation */\r
-      if (f_ambig == 0) {\r
-       sprintf(tmp, "%c", mt->fromFile + 'a');\r
-       strcat(mStr, tmp);\r
-      } else if (r_ambig == 0) {\r
-       sprintf(tmp, "%d", mt->fromRank + 1 - (gs->ranks > 9));\r
-       strcat(mStr, tmp);\r
-      } else {\r
-       sprintf(tmp, "%c%d", mt->fromFile + 'a', mt->fromRank + 1 - (gs->ranks > 9));\r
-       strcat(mStr, tmp);\r
-      }\r
-    }\r
-  }\r
-  if ((gs->board[mt->toFile][mt->toRank] != NOPIECE) ||\r
-      ((piece == PAWN) && (mt->fromFile != mt->toFile))) {\r
-    strcat(mStr, "x");\r
-  }\r
-  }\r
-  sprintf(tmp, "%c%d", mt->toFile + 'a', mt->toRank + 1 - (gs->ranks > 9));\r
-  strcat(mStr, tmp);\r
-
-  if ((piece == PAWN || gs->promoType == 3) && (mt->piecePromotionTo != NOPIECE)) {\r
-    strcat(mStr, "=");         /* = before promoting piece */\r
-    switch (piecetype(mt->piecePromotionTo)) {\r
-    case KNIGHT:\r
-      strcat(mStr, "N");\r
-      break;\r
-    case BISHOP:\r
-      strcat(mStr, "B");\r
-      break;\r
-    case ROOK:\r
-      strcat(mStr, "R");\r
-      break;\r
-    case CARDINAL:\r
-      strcat(mStr, "A");\r
-      break;\r
-    case MARSHALL:\r
-      strcat(mStr, "C");\r
-      break;\r
-    case MAN:\r
-      strcat(mStr, "M");\r
-      break;\r
-    case QUEEN:\r
-      strcat(mStr, "Q");\r
-      break;\r
-    case FERZ2:\r
-      strcat(mStr, "F");\r
-      break;\r
-    case WOODY:\r
-      strcat(mStr, "W");\r
-      break;\r
-    case EMPRESS:\r
-      strcat(mStr, "E");\r
-      break;\r
-    case CENTAUR:\r
-      strcat(mStr, "V");\r
-      break;\r
-    case PRINCESS:\r
-      strcat(mStr, "S");\r
-      break;\r
-    case SQUIRREL:\r
-      strcat(mStr, "O");\r
-      break;\r
-    case MASTODON:\r
-      strcat(mStr, "G");\r
-      break;\r
-    case GOLD: // [HGM] Shogi promotions: avoid use of '+'\r
-      strcat(mStr, "G");\r
-      break;\r
-    case DRAGONHORSE:\r
-      strcat(mStr, "H");\r
-      break;\r
-    case DRAGONKING:\r
-      strcat(mStr, "D");\r
-      break;\r
-    default:\r
-      break;\r
-    }\r
-  }\r
+    if (ambig > 0) {
+      /* Ambiguity in short notation, need to add file,rank or _both_ in
+         notation */
+      if (f_ambig == 0) {
+       sprintf(tmp, "%c", mt->fromFile + 'a');
+       strcat(mStr, tmp);
+      } else if (r_ambig == 0) {
+       sprintf(tmp, "%d", mt->fromRank + 1 - (gs->ranks > 9));
+       strcat(mStr, tmp);
+      } else {
+       sprintf(tmp, "%c%d", mt->fromFile + 'a', mt->fromRank + 1 - (gs->ranks > 9));
+       strcat(mStr, tmp);
+      }
+    }
+  }
+  if ((gs->board[mt->toFile][mt->toRank] != NOPIECE) ||
+      ((piece == PAWN) && (mt->fromFile != mt->toFile))) {
+    strcat(mStr, "x");
+  }
+  }
+  sprintf(tmp, "%c%d", mt->toFile + 'a', mt->toRank + 1 - (gs->ranks > 9));
+  strcat(mStr, tmp);
+
+  if ((piece == PAWN || gs->promoType == 3) && (mt->piecePromotionTo != NOPIECE)) {
+    strcat(mStr, "=");         /* = before promoting piece */
+    switch (piecetype(mt->piecePromotionTo)) {
+    case KNIGHT:
+      strcat(mStr, "N");
+      break;
+    case BISHOP:
+      strcat(mStr, "B");
+      break;
+    case ROOK:
+      strcat(mStr, "R");
+      break;
+    case CARDINAL:
+      strcat(mStr, "A");
+      break;
+    case MARSHALL:
+      strcat(mStr, "C");
+      break;
+    case MAN:
+      strcat(mStr, "M");
+      break;
+    case QUEEN:
+      strcat(mStr, "Q");
+      break;
+    case FERZ2:
+      strcat(mStr, "F");
+      break;
+    case WOODY:
+      strcat(mStr, "W");
+      break;
+    case SELEPHANT:
+    case EMPRESS:
+      strcat(mStr, "E");
+      break;
+    case CENTAUR:
+      strcat(mStr, "V");
+      break;
+    case PRINCESS:
+      strcat(mStr, "S");
+      break;
+    case SQUIRREL:
+      strcat(mStr, "O");
+      break;
+    case MASTODON:
+      strcat(mStr, "G");
+      break;
+    case GOLD: // [HGM] Shogi promotions: avoid use of '+'
+      strcat(mStr, "G");
+      break;
+    case HAWK:
+    case DRAGONHORSE:
+      strcat(mStr, "H");
+      break;
+    case DRAGONKING:
+      strcat(mStr, "D");
+      break;
+    default:
+      break;
+    }
+  }
 check:;
   fakeMove = *gs;
   execute_move(&fakeMove, mt, 0);
index 6aa7524..8c92473 100644 (file)
 
 
 const char *wpstring[] = {" ", "P", "N", "B", "R", "A", "C", "M", "Q", "E", "B", "Q", "W", "H", "N", "D", "H", "L", 
-                         "C", "S", "G", "H", "A", "F", "E", "H", "M", "S", "E", "W", "O", "G", "V", "S", "E", "A", "K"};
+                         "C", "S", "G", "H", "A", "F", "E", "H", "M", "S", "E", "W", "O", "G", "V", "S", "E", "A", "K", "H", "E"};
 const char *bpstring[] = {" ", "p", "n", "b", "r", "a", "c", "m", "q", "e", "b", "q", "w", "h", "n", "d", "h", "l", 
-                         "c", "s", "g", "h", "a", "f", "e", "h", "m", "s", "e", "w", "o", "g", "v", "s", "e", "a", "k"};
+                         "c", "s", "g", "h", "a", "f", "e", "h", "m", "s", "e", "w", "o", "g", "v", "s", "e", "a", "k", "h", "e"};
 
-int pieceValues[KING+1] = {0, 1, 3, 3, 5, 8, 9, 3, 9, 1, 1, 2, 2, 2, 1, 6, 5, 2, 3, 3, 3, 1, 5, 2, 1, 7, 7, 3, 3, 3, 7, 7, 7, 8, 9, 12, 0};
+int pieceValues[PIECES] = {0, 1, 3, 3, 5, 8, 9, 3, 9, 1, 1, 2, 2, 2, 1, 6, 5, 2, 3, 3, 3, 1, 5, 2, 1, 7, 7, 3, 3, 3, 7, 7, 7, 8, 9, 12, 0, 8, 9};
 
 static const int mach_type = (1<<7) | (1<<8) | (1<<9) | (1<<10) | (1<<11);
 #define IsMachineStyle(n) (((1<<(n)) & mach_type) != 0)
@@ -78,7 +78,7 @@ static void reset_board_vars(struct game_state_t *gs)
   for (f = 0; f < 2; f++) {
     for (r = 0; r < BW; r++)
       gs->ep_possible[f][r] = 0;
-    for (r = PAWN; r <= KING-1; r++)
+    for (r = PAWN; r <= PIECES-1; r++)
       gs->holding[f][r-PAWN] = 0;
   }
   gs->wkmoved = gs->wqrmoved = gs->wkrmoved = -1; // [HGM] castle: no rights
@@ -103,42 +103,42 @@ void board_standard(struct game_state_t *gs)
 {
  int f,r;
 
- for (f = 0; f < BW; f++)\r
-    for (r = 0; r < BH; r++)\r
-      gs->board[f][r] = NOPIECE;\r
- for (f = 0; f < gs->files; f++)\r
-   gs->board[f][gs->ranks-7] = W_PAWN;\r
- for (f = 0; f < gs->files; f++)\r
-   gs->board[f][6] = B_PAWN;\r
- gs->board[0][0] = W_ROOK;\r
- gs->board[1][0] = W_KNIGHT;\r
- gs->board[2][0] = W_BISHOP; \r
- gs->board[3][0] = W_QUEEN;\r
- gs->board[gs->files/2][0] = W_KING;\r
- gs->board[gs->files-3][0] = W_BISHOP;\r
- gs->board[gs->files-2][0] = W_KNIGHT;\r
- gs->board[gs->files-1][0] = W_ROOK;\r
- gs->board[0][gs->ranks-1] = B_ROOK;\r
- gs->board[1][gs->ranks-1] = B_KNIGHT;\r
- gs->board[2][gs->ranks-1] = B_BISHOP;\r
- gs->board[3][gs->ranks-1] = B_QUEEN;\r
- gs->board[gs->files/2][gs->ranks-1] = B_KING;\r
- gs->board[gs->files-3][gs->ranks-1] = B_BISHOP;\r
- gs->board[gs->files-2][gs->ranks-1] = B_KNIGHT;\r
- gs->board[gs->files-1][gs->ranks-1] = B_ROOK;\r
+ for (f = 0; f < BW; f++)
+    for (r = 0; r < BH; r++)
+      gs->board[f][r] = NOPIECE;
+ for (f = 0; f < gs->files; f++)
+   gs->board[f][gs->ranks-7] = W_PAWN;
+ for (f = 0; f < gs->files; f++)
+   gs->board[f][6] = B_PAWN;
+ gs->board[0][0] = W_ROOK;
+ gs->board[1][0] = W_KNIGHT;
+ gs->board[2][0] = W_BISHOP; 
+ gs->board[3][0] = W_QUEEN;
+ gs->board[gs->files/2][0] = W_KING;
+ gs->board[gs->files-3][0] = W_BISHOP;
+ gs->board[gs->files-2][0] = W_KNIGHT;
+ gs->board[gs->files-1][0] = W_ROOK;
+ gs->board[0][gs->ranks-1] = B_ROOK;
+ gs->board[1][gs->ranks-1] = B_KNIGHT;
+ gs->board[2][gs->ranks-1] = B_BISHOP;
+ gs->board[3][gs->ranks-1] = B_QUEEN;
+ gs->board[gs->files/2][gs->ranks-1] = B_KING;
+ gs->board[gs->files-3][gs->ranks-1] = B_BISHOP;
+ gs->board[gs->files-2][gs->ranks-1] = B_KNIGHT;
+ gs->board[gs->files-1][gs->ranks-1] = B_ROOK;
 #if 1
- if(gs->files == 10) {\r
-  gs->board[6][0] = W_CARDINAL;\r
-  gs->board[4][0] = W_MARSHALL;\r
-  gs->board[6][gs->ranks-1] = B_CARDINAL;\r
-  gs->board[4][gs->ranks-1] = B_MARSHALL;\r
- }\r
- if(gs->royalKnight) {\r
-   gs->board[1][0] = W_MAN;\r
-   gs->board[gs->files-2][0] = W_MAN;\r
-   gs->board[1][gs->ranks-1] = B_MAN;\r
-   gs->board[gs->files-2][gs->ranks-1] = B_MAN;\r
- }\r
+ if(gs->files == 10) {
+  gs->board[6][0] = W_CARDINAL;
+  gs->board[4][0] = W_MARSHALL;
+  gs->board[6][gs->ranks-1] = B_CARDINAL;
+  gs->board[4][gs->ranks-1] = B_MARSHALL;
+ }
+ if(gs->royalKnight) {
+   gs->board[1][0] = W_MAN;
+   gs->board[gs->files-2][0] = W_MAN;
+   gs->board[1][gs->ranks-1] = B_MAN;
+   gs->board[gs->files-2][gs->ranks-1] = B_MAN;
+ }
 #endif
 
  reset_board_vars(gs);
@@ -156,9 +156,9 @@ int board_init(int g,struct game_state_t *b, char *category, char *board)
   int retval = 0;
   int wval, i, j;
 
-  b->files = b->ranks = 8;\r
-  b->pawnDblStep = (!category || strcmp(category, "shatranj")); \r
-  b->royalKnight = (category && !strcmp(category, "knightmate"));\r
+  b->files = b->ranks = 8;
+  b->pawnDblStep = (!category || strcmp(category, "shatranj")); 
+  b->royalKnight = (category && !strcmp(category, "knightmate"));
   b->capablancaPieces = 0;
   b->holdings = 0;
   b->drops = 0;
@@ -169,24 +169,24 @@ int board_init(int g,struct game_state_t *b, char *category, char *board)
   b->stalemate = 1;
   b->promoType = 1;
   b->promoZone = 1;
-  b->variant[0] = 0; // [HGM] variant: default is normal, if variant name is missing\r
-  if (!category || !board || !category[0] || !board[0]) \r
-                               /* accounts for bughouse too */\r
-    board_standard(b);\r
+  b->variant[0] = 0; // [HGM] variant: default is normal, if variant name is missing
+  if (!category || !board || !category[0] || !board[0]) 
+                               /* accounts for bughouse too */
+    board_standard(b);
   else {
-    if(category && category[0]) strcpy(b->variant, category); // [HGM] variant: remember category name\r
+    if(category && category[0]) strcpy(b->variant, category); // [HGM] variant: remember category name
     if (!strcmp(category, "wild") && sscanf(board, "%d", &wval) == 1) {
-       if(wval >= 1 && wval <= 4)\r
+       if(wval >= 1 && wval <= 4)
             wild_update(b->board, wval);
-       sprintf(b->variant, "wild/%d", wval);\r
+       sprintf(b->variant, "wild/%d", wval);
     }
 
     if (board && !strcmp(board, "0"))
-       b->setup = 0; // [HGM] variant: any board in the default file "0" is supposed to be implied by the variant\r
+       b->setup = 0; // [HGM] variant: any board in the default file "0" is supposed to be implied by the variant
 
-    if (!strcmp(category, "knightmate")) {\r
-      board_standard(b);\r
-    } else if (!strcmp(category, "super")) {\r
+    if (!strcmp(category, "knightmate")) {
+      board_standard(b);
+    } else if (!strcmp(category, "super")) {
       board_standard(b);
       b->holdings = 1;
       b->promoType = 2;
@@ -203,17 +203,17 @@ int board_init(int g,struct game_state_t *b, char *category, char *board)
          placed = 1;
        } while(!placed);
       }
-      b->setup = 1;\r
-    } else if (!strcmp(category, "fischerandom")) {\r
+      b->setup = 1;
+    } else if (!strcmp(category, "fischerandom")) {
       wild_update(b->board, 22);
       b->castlingStyle = 2;
-      b->setup = 1; // [HGM] FRC: even the default is a setup position, for which an initial board has to be printed\r
+      b->setup = 1; // [HGM] FRC: even the default is a setup position, for which an initial board has to be printed
     } else if (!strcmp(category, "caparandom")) {
-      b->files = 10;\r
+      b->files = 10;
       wild_update(b->board, 46);
       b->castlingStyle = 2;
-      b->setup = 1; \r
-    } else retval = board_read_file(category, board, b); \r
+      b->setup = 1; 
+    } else retval = board_read_file(category, board, b); 
   }
   if(b->setup && game_globals.garray[g].FENstartPos[0])  // [HGM] use pre-existing start position, if one available
     FEN_to_board(game_globals.garray[g].FENstartPos, b); //       (could be wild board, or shuffle variant)
@@ -236,7 +236,7 @@ int board_init(int g,struct game_state_t *b, char *category, char *board)
       }
     }
   }
-\r
+
   MakeFENpos(g, game_globals.garray[g].FENstartPos);
 
   return retval;
@@ -257,7 +257,7 @@ void board_calc_strength(struct game_state_t *b, int *ws, int *bs)
       *p += pieceValues[piecetype(b->board[r][f])];
     }
   }
-  for (r = PAWN; r < KING; r++) {
+  for (r = PAWN; r < PIECES; r++) {
     *ws += b->holding[0][r-1] * pieceValues[r];
     *bs += b->holding[1][r-1] * pieceValues[r];
   }
@@ -269,7 +269,7 @@ static char *holding_str(int *holding)
        int p,i,j;
 
        i = 0;
-       for (p = PAWN; p < KING; p++) {
+       for (p = PAWN; p < PIECES; p++) {
                for (j = 0; j < holding[p-1]; j++) {
                        tmp[i++] = wpstring[p][0];
                }
@@ -350,7 +350,7 @@ char *board_to_string(char *wn, char *bn,
                      int p)
 {
   int bh = (b->gameNum >= 0 && game_globals.garray[b->gameNum].link >= 0
-             || b->holdings ); // [HGM] zh: make sure holdings are printed
+             || b->holdings || b->drops == 2); // [HGM] zh: make sure holdings are printed (also in Seirawan)
   orient = orientation;
   myTurn = relation;
 
@@ -433,96 +433,96 @@ static int genstyle(struct game_state_t *b, struct move_t *ml, const char *wp[],
                    const char *top, const char *mid, const char *start, const char *end, 
                    const char *label,const char *blabel)
 {
-  int f, r, count, i;\r
-  char tmp[80], mylabel[80], *p, *q, myTop[80], myMid[80];\r
-  int firstR, lastR, firstF, lastF, inc;\r
-  int ws, bs, sqrSize = strlen(wp[0]);\r
-\r
-  board_calc_strength(b, &ws, &bs);\r
-  if (orient == WHITE) {\r
-    firstR = b->ranks-1;\r
-    firstF = b->files-1;\r
-    lastR = lastF = 0;\r
-    inc = -1;\r
-  } else {\r
-    firstR = firstF = 0;\r
-    lastR = b->ranks-1;\r
-    lastF = b->files-1;\r
-    inc = 1;\r
+  int f, r, count, i;
+  char tmp[80], mylabel[80], *p, *q, myTop[80], myMid[80];
+  int firstR, lastR, firstF, lastF, inc;
+  int ws, bs, sqrSize = strlen(wp[0]);
+
+  board_calc_strength(b, &ws, &bs);
+  if (orient == WHITE) {
+    firstR = b->ranks-1;
+    firstF = b->files-1;
+    lastR = lastF = 0;
+    inc = -1;
+  } else {
+    firstR = firstF = 0;
+    lastR = b->ranks-1;
+    lastF = b->files-1;
+    inc = 1;
   }
   strcpy(myTop, top);
   strcpy(myMid, mid);
-  Enlarge(myTop, sqrSize, b->files);\r
-  Enlarge(myMid, sqrSize, b->files);\r
-  strcat(bstring, myTop);\r
-  for (f = firstR, count = b->ranks-1; f != lastR + inc; f += inc, count--) {\r
-    sprintf(tmp, "     %d  %s", f + (b->ranks < 10), start);\r
-    strcat(bstring, tmp);\r
-    for (r = lastF; r != firstF - inc; r = r - inc) {\r
-      if (square_color(r, f) == WHITE)\r
-       strcat(bstring, wsqr);\r
-      else\r
-       strcat(bstring, bsqr);\r
-      if (piecetype(b->board[r][f]) == NOPIECE) {\r
-       if (square_color(r, f) == WHITE)\r
-         strcat(bstring, bp[0]);\r
-       else\r
-         strcat(bstring, wp[0]);\r
+  Enlarge(myTop, sqrSize, b->files);
+  Enlarge(myMid, sqrSize, b->files);
+  strcat(bstring, myTop);
+  for (f = firstR, count = b->ranks-1; f != lastR + inc; f += inc, count--) {
+    sprintf(tmp, "     %d  %s", f + (b->ranks < 10), start);
+    strcat(bstring, tmp);
+    for (r = lastF; r != firstF - inc; r = r - inc) {
+      if (square_color(r, f) == WHITE)
+       strcat(bstring, wsqr);
+      else
+       strcat(bstring, bsqr);
+      if (piecetype(b->board[r][f]) == NOPIECE) {
+       if (square_color(r, f) == WHITE)
+         strcat(bstring, bp[0]);
+       else
+         strcat(bstring, wp[0]);
       } else {
        int piece = piecetype(b->board[r][f]);
-//     if(piece > QUEEN) piece = ELEPHANT + (piece == KING); // All fairies become elephants in ascii styles\r
-       if (colorval(b->board[r][f]) == WHITE)\r
-         strcat(bstring, wp[piece]);\r
-       else\r
-         strcat(bstring, bp[piece]);\r
-      }\r
-    }\r
-    sprintf(tmp, "%s", end);\r
-    strcat(bstring, tmp);\r
-    switch (count) {\r
-    case 7:\r
-      sprintf(tmp, "     Move # : %d (%s)", b->moveNum, CString(b->onMove));\r
-      strcat(bstring, tmp);\r
-      break;\r
-    case 6:\r
-/*    if ((b->moveNum > 1) || (b->onMove == BLACK)) {  */\r
-/* The change from the above line to the one below is a kludge by hersco. */\r
-      if (game_globals.garray[b->gameNum].numHalfMoves > 0) {\r
-/* loon: think this fixes the crashing ascii board on takeback bug */\r
-       sprintf(tmp, "     %s Moves : '%s'", CString(CToggle(b->onMove)),\r
-               move_and_time(&ml[game_globals.garray[b->gameNum].numHalfMoves - 1]));\r
-       strcat(bstring, tmp);\r
-      }\r
-      break;\r
-    case 5:\r
-      break;\r
-    case 4:\r
-      sprintf(tmp, "     Black Clock : %s", tenth_str(((bTime > 0) ? bTime : 0), 1));\r
-      strcat(bstring, tmp);\r
-      break;\r
-    case 3:\r
-      sprintf(tmp, "     White Clock : %s", tenth_str(((wTime > 0) ? wTime : 0), 1));\r
-      strcat(bstring, tmp);\r
-      break;\r
-    case 2:\r
-      sprintf(tmp, "     Black Strength : %d", bs);\r
-      strcat(bstring, tmp);\r
-      break;\r
-    case 1:\r
-      sprintf(tmp, "     White Strength : %d", ws);\r
-      strcat(bstring, tmp);\r
-      break;\r
-    case 0:\r
-      break;\r
-    }\r
-    strcat(bstring, "\n");\r
-    if (count != 0)\r
-      strcat(bstring, myMid);\r
-    else\r
-      strcat(bstring, myTop);\r
-  }\r
+//     if(piece > QUEEN) piece = ELEPHANT + (piece == KING); // All fairies become elephants in ascii styles
+       if (colorval(b->board[r][f]) == WHITE)
+         strcat(bstring, wp[piece]);
+       else
+         strcat(bstring, bp[piece]);
+      }
+    }
+    sprintf(tmp, "%s", end);
+    strcat(bstring, tmp);
+    switch (count) {
+    case 7:
+      sprintf(tmp, "     Move # : %d (%s)", b->moveNum, CString(b->onMove));
+      strcat(bstring, tmp);
+      break;
+    case 6:
+/*    if ((b->moveNum > 1) || (b->onMove == BLACK)) {  */
+/* The change from the above line to the one below is a kludge by hersco. */
+      if (game_globals.garray[b->gameNum].numHalfMoves > 0) {
+/* loon: think this fixes the crashing ascii board on takeback bug */
+       sprintf(tmp, "     %s Moves : '%s'", CString(CToggle(b->onMove)),
+               move_and_time(&ml[game_globals.garray[b->gameNum].numHalfMoves - 1]));
+       strcat(bstring, tmp);
+      }
+      break;
+    case 5:
+      break;
+    case 4:
+      sprintf(tmp, "     Black Clock : %s", tenth_str(((bTime > 0) ? bTime : 0), 1));
+      strcat(bstring, tmp);
+      break;
+    case 3:
+      sprintf(tmp, "     White Clock : %s", tenth_str(((wTime > 0) ? wTime : 0), 1));
+      strcat(bstring, tmp);
+      break;
+    case 2:
+      sprintf(tmp, "     Black Strength : %d", bs);
+      strcat(bstring, tmp);
+      break;
+    case 1:
+      sprintf(tmp, "     White Strength : %d", ws);
+      strcat(bstring, tmp);
+      break;
+    case 0:
+      break;
+    }
+    strcat(bstring, "\n");
+    if (count != 0)
+      strcat(bstring, myMid);
+    else
+      strcat(bstring, myTop);
+  }
   q = mylabel; i = 0;
-  if (orient == WHITE) {\r
+  if (orient == WHITE) {
     p = label;
     while(*p) {
        switch(*p) {
@@ -547,439 +547,440 @@ static int genstyle(struct game_state_t *b, struct move_t *ml, const char *wp[],
                *q++ = *p++ + b->files - 12;
                if(++i >= b->files) { *q++ = '\n'; *q++ = 0; }
        }
-    }\r
-  }\r
+    }
+  }
   *q++ = 0;
-  strcat(bstring, mylabel);\r
-  return 0;\r
+  strcat(bstring, mylabel);
+  return 0;
 }
 
-/* Experimental ANSI board for colour representation */\r
-static int style13(struct game_state_t *b, struct move_t *ml)\r
-{\r
-  static const char *wp[] = {"   ", "\033[37m\033[1m P ", "\033[37m\033[1m N ", "\033[37m\033[1m B ", "\033[37m\033[1m R ", "\033[37m\033[1m A ", "\033[37m\033[1m C ", "\033[37m\033[1m M ", "\033[37m\033[1m Q ", "\033[37m\033[1m E ", "\033[37m\033[1m K "};\r
-  static const char *bp[] = {"   ", "\033[21m\033[37m P ", "\033[21m\033[37m N ", "\033[21m\033[37m B ", "\033[21m\033[37m R ", "\033[21m\033[37m A ", "\033[21m\033[37m C ", "\033[21m\033[37m M ", "\033[21m\033[37m Q ", "\033[21m\033[37m E ", "\033[21m\033[37m K "};\r
-  static const char *wsqr = "\033[40m";\r
-  static const char *bsqr = "\033[45m";\r
-  static const char *top = "\t+------------------------+\n";\r
-  static const char *mid = "";\r
-  static const char *start = "|";\r
-  static const char *end = "\033[0m|";\r
-  static const char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";\r
-  static const char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";\r
-return 0;\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-\r
-/* Standard ICS */\r
-static int style1(struct game_state_t *b, struct move_t *ml)\r
-{\r
+/* Experimental ANSI board for colour representation */
+static int style13(struct game_state_t *b, struct move_t *ml)
+{
+  static const char *wp[] = {"   ", "\033[37m\033[1m P ", "\033[37m\033[1m N ", "\033[37m\033[1m B ", "\033[37m\033[1m R ", "\033[37m\033[1m A ", "\033[37m\033[1m C ", "\033[37m\033[1m M ", "\033[37m\033[1m Q ", "\033[37m\033[1m E ", "\033[37m\033[1m K "};
+  static const char *bp[] = {"   ", "\033[21m\033[37m P ", "\033[21m\033[37m N ", "\033[21m\033[37m B ", "\033[21m\033[37m R ", "\033[21m\033[37m A ", "\033[21m\033[37m C ", "\033[21m\033[37m M ", "\033[21m\033[37m Q ", "\033[21m\033[37m E ", "\033[21m\033[37m K "};
+  static const char *wsqr = "\033[40m";
+  static const char *bsqr = "\033[45m";
+  static const char *top = "\t+------------------------+\n";
+  static const char *mid = "";
+  static const char *start = "|";
+  static const char *end = "\033[0m|";
+  static const char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";
+  static const char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";
+return 0;
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Standard ICS */
+static int style1(struct game_state_t *b, struct move_t *ml)
+{
   static const char *wp[] = {"   |", " P |", " N |", " B |", " R |", " A |", " C |", " M |", " Q |", " E |", " B |", " Q |", 
                             " W |", " H |", " N |", " D |", " H |", " L |", " C |", " S |", " G |", " H |", " A |", " F |",
-                            " E |", " H |", " M |", " S |", " E |", " W |", " O |", " G |", " V |", " S |", " E |", " A |", " K |"};
+                            " E |", " H |", " M |", " S |", " E |", " W |", " O |", " G |", " V |", " S |", " E |", " A |", " K |", " H |", " E |"};
   static const char *bp[] = {"   |", " *P|", " *N|", " *B|", " *R|", " *A|", " *C|", " *M|", " *Q|", " *E|", " *B|", " *Q|", 
                             " *W|", " *H|", " *N|", " *D|", " *H|", " *L|", " *C|", " *S|", " *G|", " *H|", " *A|", " *F|",
-                            " *E|", " *H|", " *M|", " *S|", " *E|", " *W|", " *O|", " *G|", " *V|", " *S|", " *E|", " *A|", " *K|"};
-  static char *wsqr = "";\r
-  static char *bsqr = "";\r
-  static char *top = "\t---------------------------------\n";\r
-  static char *mid = "\t|---+---+---+---+---+---+---+---|\n";\r
-  static char *start = "|";\r
-  static char *end = "";\r
-  static char *label = "\t  a   b   c   d   e   f   g   h   i   j   k   l\n";\r
-  static char *blabel = "\t  l   k   j   i   h   g   f   e   d   c   b   a\n";\r
-\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-\r
-/* USA-Today Sports Center-style board */\r
-static int style2(struct game_state_t *b, struct move_t *ml)\r
-{\r
+                            " *E|", " *H|", " *M|", " *S|", " *E|", " *W|", " *O|", " *G|", " *V|", " *S|", " *E|", " *A|", " *K|", " *H|", " *E|"};
+  static char *wsqr = "";
+  static char *bsqr = "";
+  static char *top = "\t---------------------------------\n";
+  static char *mid = "\t|---+---+---+---+---+---+---+---|\n";
+  static char *start = "|";
+  static char *end = "";
+  static char *label = "\t  a   b   c   d   e   f   g   h   i   j   k   l\n";
+  static char *blabel = "\t  l   k   j   i   h   g   f   e   d   c   b   a\n";
+
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* USA-Today Sports Center-style board */
+static int style2(struct game_state_t *b, struct move_t *ml)
+{
   static const char *wp[] = {"-  ", "P  ", "N  ", "B  ", "R  ", "A  ", "C  ", "M  ", "Q  ", "E  ", "B  ", "Q  ",
                             "W  ", "H  ", "N  ", "D  ", "H  ", "L  ", "C  ", "S  ", "G  ", "H  ", "A  ", "F  ",
-                            "E  ", "H  ", "M  ", "S  ", "E  ", "W  ", "O  ", "G  ", "V  ", "S  ", "E  ", "A  ", "K  "};
+                            "E  ", "H  ", "M  ", "S  ", "E  ", "W  ", "O  ", "G  ", "V  ", "S  ", "E  ", "A  ", "K  ", "H  ", "E  "};
   static const char *bp[] = {"+  ", "p' ", "n' ", "b' ", "r' ", "a' ", "c' ", "m' ", "q' ", "e' ", "b' ", "q' ",
                             "w' ", "h' ", "n' ", "d' ", "h' ", "l' ", "c' ", "s' ", "g' ", "h' ", "a' ", "f' ",
-                            "e' ", "h' ", "m' ", "s' ", "e' ", "w' ", "o' ", "g' ", "v' ", "s' ", "e' ", "a' ", "k' "};
-  static char *wsqr = "";\r
-  static char *bsqr = "";\r
-  static char *top = "";\r
-  static char *mid = "";\r
-  static char *start = "";\r
-  static char *end = "";\r
-  static char *label = "\ta  b  c  d  e  f  g  h  i  j  k  l\n";\r
-  static char *blabel = "\tl  k  j  i  h  g  f  e  d  c  b  a\n";\r
-\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-\r
-/* Experimental vt-100 ANSI board for dark backgrounds */\r
-static int style3(struct game_state_t *b, struct move_t *ml)\r
-{\r
+                            "e' ", "h' ", "m' ", "s' ", "e' ", "w' ", "o' ", "g' ", "v' ", "s' ", "e' ", "a' ", "k' ", "h' ", "e' "};
+  static char *wsqr = "";
+  static char *bsqr = "";
+  static char *top = "";
+  static char *mid = "";
+  static char *start = "";
+  static char *end = "";
+  static char *label = "\ta  b  c  d  e  f  g  h  i  j  k  l\n";
+  static char *blabel = "\tl  k  j  i  h  g  f  e  d  c  b  a\n";
+
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Experimental vt-100 ANSI board for dark backgrounds */
+static int style3(struct game_state_t *b, struct move_t *ml)
+{
   static const char *wp[] = {"   ", " P ", " N ", " B ", " R ", " A ", " C ", " M ", " Q ", " E ", " B ", " Q ", 
                             " W ", " H ", " N ", " D ", " H ", " L ", " C ", " S ", " G ", " H ", " A ", " F ",
-                            " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K "};
+                            " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K ", " H ", " E "};
   static const char *bp[] = {"   ", " *P", " *N", " *B", " *R", " *A", " *C", " *M", " *Q", " *E", " *B", " *Q", 
                             " *W", " *H", " *N", " *D", " *H", " *L", " *C", " *S", " *G", " *H", " *A", " *F",
-                            " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K"};
-  static char *wsqr = "\033[0m";\r
-  static char *bsqr = "\033[7m";\r
-  static char *top = "\t+------------------------+\n";\r
-  static char *mid = "";\r
-  static char *start = "|";\r
-  static char *end = "\033[0m|";\r
-  static char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";\r
-  static char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";\r
-\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-\r
-/* Experimental vt-100 ANSI board for light backgrounds */\r
-static int style4(struct game_state_t *b, struct move_t *ml)\r
-{\r
+                            " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K", " *H", " *E"};
+  static char *wsqr = "\033[0m";
+  static char *bsqr = "\033[7m";
+  static char *top = "\t+------------------------+\n";
+  static char *mid = "";
+  static char *start = "|";
+  static char *end = "\033[0m|";
+  static char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";
+  static char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";
+
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Experimental vt-100 ANSI board for light backgrounds */
+static int style4(struct game_state_t *b, struct move_t *ml)
+{
   static const char *wp[] = {"   ", " P ", " N ", " B ", " R ", " A ", " C ", " M ", " Q ", " E ", " B ", " Q ", 
                             " W ", " H ", " N ", " D ", " H ", " L ", " C ", " S ", " G ", " H ", " A ", " F ",
-                            " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K "};
+                            " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K ", " H ", " E "};
   static const char *bp[] = {"   ", " *P", " *N", " *B", " *R", " *A", " *C", " *M", " *Q", " *E", " *B", " *Q", 
                             " *W", " *H", " *N", " *D", " *H", " *L", " *C", " *S", " *G", " *H", " *A", " *F",
-                            " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K"};
-  static char *wsqr = "\033[7m";\r
-  static char *bsqr = "\033[0m";\r
-  static char *top = "\t+------------------------+\n";\r
-  static char *mid = "";\r
-  static char *start = "|";\r
-  static char *end = "\033[0m|";\r
-  static char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";\r
-  static char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";\r
-\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-\r
-/* Style suggested by ajpierce@med.unc.edu */\r
-static int style5(struct game_state_t *b, struct move_t *ml)\r
-{\r
+                            " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K", " *H", " *E"};
+  static char *wsqr = "\033[7m";
+  static char *bsqr = "\033[0m";
+  static char *top = "\t+------------------------+\n";
+  static char *mid = "";
+  static char *start = "|";
+  static char *end = "\033[0m|";
+  static char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";
+  static char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";
+
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Style suggested by ajpierce@med.unc.edu */
+static int style5(struct game_state_t *b, struct move_t *ml)
+{
   static const char *wp[] = {"    ", "  o ", " :N:", " <B>", " |R|", " (A)", " [C]", " :M:", " {Q}", " !E!",
                             " <B>", " {Q}", " .W.", " :H:", " :N:", " <H>", " |D|", " |L|", 
                             " |C|", " !S!", " :G:", " :H:", " {A}", " {F}", " !E!", " (H)", " [M]", " :S:",
-                            " !E!", " |W|", " *O*", " {G}", " :V:", " (S)", " [E]", " &A&", " =K="};
+                            " !E!", " |W|", " *O*", " {G}", " :V:", " (S)", " [E]", " &A&", " =K=", " (H)", " [E]"};
   static const char *bp[] = {"    ", "  p ", " :n:", " <b>", " |r|", " (a)", " [c]", " :m:", " {q}", " !e!",
                             " <b>", " {q}", " .w.", " :h:", " :n:", " <h>", " |d|", " |l|", 
                             " |c|", " !s!", " :g:", " :h:", " {a}", " {f}", " !e!", " (h)", " [m]", " :s:",
-                            " !e!", " |w|", " *o*", " {g}", " :v:", " (s)", " [e]", " &a&", " =k="};
-  static char *wsqr = "";\r
-  static char *bsqr = "";\r
-  static char *top = "        .   .   .   .   .   .   .   .   .\n";\r
-  static char *mid = "        .   .   .   .   .   .   .   .   .\n";\r
-  static char *start = "";\r
-  static char *end = "";\r
-  static char *label = "\t  a   b   c   d   e   f   g   h   i   j   k   l\n";\r
-  static char *blabel = "\t  l   k   j   i   h   g   f   e   d   c   b   a\n";\r
-\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-\r
-/* Email Board suggested by Thomas Fought (tlf@rsch.oclc.org) */\r
-static int style6(struct game_state_t *b, struct move_t *ml)\r
-{\r
+                            " !e!", " |w|", " *o*", " {g}", " :v:", " (s)", " [e]", " &a&", " =k=", " (f)", " [e]"};
+  static char *wsqr = "";
+  static char *bsqr = "";
+  static char *top = "        .   .   .   .   .   .   .   .   .\n";
+  static char *mid = "        .   .   .   .   .   .   .   .   .\n";
+  static char *start = "";
+  static char *end = "";
+  static char *label = "\t  a   b   c   d   e   f   g   h   i   j   k   l\n";
+  static char *blabel = "\t  l   k   j   i   h   g   f   e   d   c   b   a\n";
+
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Email Board suggested by Thomas Fought (tlf@rsch.oclc.org) */
+static int style6(struct game_state_t *b, struct move_t *ml)
+{
   static const char *wp[] = {"    |", " wp |", " WN |", " WB |", " WR |", " WA |", " WC |", " WM |", " WQ |", 
                             " WE |", " WB |", " WQ |", " WW |", " WH |", " WN |", " WD |", " WH |", " WL |", 
                             " WC |", " WS |", " WG |", " WH |", " WA |", " WF |", " WE |", " WH |", " WM |", 
-                            " WS |", " WE |", " WW |", " WO |", " WG |", " WV |", " WS |", " WE |", " WA |", " WK |"};
+                            " WS |", " WE |", " WW |", " WO |", " WG |", " WV |", " WS |", " WE |", " WA |", " WK |", " WH |", " WE |"};
   static const char *bp[] = {"    |", " bp |", " BN |", " BB |", " BR |", " BA |", " BC |", " BM |", " BQ |", 
                             " BE |", " BB |", " BQ |", " BW |", " BH |", " BN |", " BD |", " BH |", " BL |", 
                             " BC |", " BS |", " BG |", " BH |", " BA |", " BF |", " BE |", " BH |", " BM |", 
-                            " BS |", " BE |", " BW |", " BO |", " BG |", " BV |", " BS |", " BE |", " BA |", " BK |"};
-  static char *wsqr = "";\r
-  static char *bsqr = "";\r
-  static char *top = "\t-----------------------------------------\n";\r
-  static char *mid = "\t-----------------------------------------\n";\r
-  static char *start = "|";\r
-  static char *end = "";\r
-  static char *label = "\t  A    B    C    D    E    F    G    H    I    J    K    L\n";\r
-  static char *blabel = "\t  L    K    J    I    H    G    F    E    D    C    B    A\n";\r
-\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-\r
-/* Miniature board */\r
-static int style7(struct game_state_t *b, struct move_t *ml)\r
-{\r
+                            " BS |", " BE |", " BW |", " BO |", " BG |", " BV |", " BS |", " BE |", " BA |", " BK |", " BH |", " BE |"};
+  static char *wsqr = "";
+  static char *bsqr = "";
+  static char *top = "\t-----------------------------------------\n";
+
+  static char *mid = "\t-----------------------------------------\n";
+  static char *start = "|";
+  static char *end = "";
+  static char *label = "\t  A    B    C    D    E    F    G    H    I    J    K    L\n";
+  static char *blabel = "\t  L    K    J    I    H    G    F    E    D    C    B    A\n";
+
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Miniature board */
+static int style7(struct game_state_t *b, struct move_t *ml)
+{
   static const char *wp[] = {"  ", " P", " N", " B", " R", " A", " C", " M", " Q", " E", " B", " Q", " W", " H", " N", " D", " H", " L", 
-                            " C", " S", " G", " H", " A", " F", " E", " H", " M", " S", " E", " W", " O", " G", " V", " S", " E", " A", " K"};
+                            " C", " S", " G", " H", " A", " F", " E", " H", " M", " S", " E", " W", " O", " G", " V", " S", " E", " A", " K", " H", " E"};
   static const char *bp[] = {" -", " p", " n", " b", " r", " a", " c", " m", " q", " e", " b", " q", " w", " h", " n", " d", " h", " l", 
-                            " c", " s", " g", " h", " a", " f", " e", " h", " m", " s", " e", " w", " o", " g", " v", " s", " e", " a", " k"};
-  static char *wsqr = "";\r
-  static char *bsqr = "";\r
-  static char *top = "\t:::::::::::::::::::::\n";\r
-  static char *mid = "";\r
-  static char *start = "..";\r
-  static char *end = " ..";\r
-  static char *label = "\t   a b c d e f g h i j k l\n";\r
-  static char *blabel = "\t   l k j i h g f e d c b a\n";\r
-\r
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
-}\r
-
-/* ICS interface maker board-- raw data dump */\r
-static int style8(struct game_state_t *b, struct move_t *ml)\r
-{\r
-  char tmp[160];\r
-  int f, r;\r
-  int ws, bs;\r
-\r
-  board_calc_strength(b, &ws, &bs);\r
-  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum + 1,\r
-         game_globals.garray[b->gameNum].white_name,\r
-         (orient == WHITE) ? "*" : ":",\r
-         game_globals.garray[b->gameNum].black_name,\r
-         (orient == WHITE) ? ":" : "*");\r
-  strcat(bstring, tmp);\r
-  for (r = 0; r < b->ranks; r++) {\r
-    for (f = 0; f < b->files; f++) {\r
-      if (b->board[f][r] == NOPIECE) {\r
-       strcat(bstring, " ");\r
-      } else {\r
-       if (colorval(b->board[f][r]) == WHITE)\r
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
-       else\r
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
-      }\r
-    }\r
-  }\r
-  sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",\r
-         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,\r
-         (b->onMove == WHITE) ? "W" : "B",\r
-         ws,\r
-         bs,\r
-         (wTime + 5) / 10,\r
-         (bTime + 5) / 10,\r
-         game_globals.garray[b->gameNum].numHalfMoves ?\r
-         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :\r
-         "none",\r
-         game_globals.garray[b->gameNum].numHalfMoves ?\r
-         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :\r
-         "0:00");\r
-  strcat(bstring, tmp);\r
-  return 0;\r
-}\r
-\r
-/* last 2 moves only (previous non-verbose mode) */\r
-static int style9(struct game_state_t *b, struct move_t *ml)\r
-{\r
-  int i, count;\r
-  char tmp[160];\r
-  int startmove;\r
-\r
-  sprintf(tmp, "\nMove     %-23s%s\n",\r
-         game_globals.garray[b->gameNum].white_name,\r
-         game_globals.garray[b->gameNum].black_name);\r
-  strcat(bstring, tmp);\r
-  sprintf(tmp, "----     --------------         --------------\n");\r
-  strcat(bstring, tmp);\r
-  startmove = ((game_globals.garray[b->gameNum].numHalfMoves - 3) / 2) * 2;\r
-  if (startmove < 0)\r
-    startmove = 0;\r
-  for (i = startmove, count = 0;\r
-       i < game_globals.garray[b->gameNum].numHalfMoves && count < 4;\r
-       i++, count++) {\r
-    if (!(i & 0x01)) {\r
-      sprintf(tmp, "  %2d     ", i / 2 + 1);\r
-      strcat(bstring, tmp);\r
-    }\r
-    sprintf(tmp, "%-23s", move_and_time(&ml[i]));\r
-    strcat(bstring, tmp);\r
-    if (i & 0x01)\r
-      strcat(bstring, "\n");\r
-  }\r
-  if (i & 0x01)\r
-    strcat(bstring, "\n");\r
-  return 0;\r
-}\r
-\r
-/* Sleator's 'new and improved' raw dump format... */\r
-static int style10(struct game_state_t *b, struct move_t *ml)\r
-{\r
-  int f, r;\r
-  char tmp[160];\r
-  int ws, bs;\r
-\r
-  board_calc_strength(b, &ws, &bs);\r
-  sprintf(tmp, "<10>\n");\r
-  strcat(bstring, tmp);\r
-  for (r = b->ranks-1; r >= 0; r--) {\r
-    strcat(bstring, "|");\r
-    for (f = 0; f < b->files; f++) {\r
-      if (b->board[f][r] == NOPIECE) {\r
-       strcat(bstring, " ");\r
-      } else {\r
-       if (colorval(b->board[f][r]) == WHITE)\r
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
-       else\r
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
-      }\r
-    }\r
-    strcat(bstring, "|\n");\r
-  }\r
-  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");\r
-  if (game_globals.garray[b->gameNum].numHalfMoves) {\r
-    sprintf(tmp, "%d ",\r
-           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);\r
-  } else {\r
-    sprintf(tmp, "-1 ");\r
-  }\r
-  strcat(bstring, tmp);\r
-  sprintf(tmp, "%d %d %d %d %d\n",\r
-         (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights\r
-         (b->wkmoved >= 0 && b->wqrmoved >= 0),\r
-         (b->bkmoved >= 0 && b->bkrmoved >= 0),\r
-         (b->bkmoved >= 0 && b->bqrmoved >= 0),\r
-       (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 :\r
-                                          b->lastIrreversable)));\r
-  strcat(bstring, tmp);\r
-  sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d\n",\r
-         b->gameNum,\r
-         game_globals.garray[b->gameNum].white_name,\r
-         game_globals.garray[b->gameNum].black_name,\r
-         myTurn,\r
-         game_globals.garray[b->gameNum].wInitTime / 600,\r
-         game_globals.garray[b->gameNum].wIncrement / 10,\r
-         ws,\r
-         bs,\r
-         (wTime + 5) / 10,\r
-         (bTime + 5) / 10,\r
-         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,\r
-         game_globals.garray[b->gameNum].numHalfMoves ?\r
-         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :\r
-         "none",\r
-         game_globals.garray[b->gameNum].numHalfMoves ?\r
-         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :\r
-         "0:00",\r
-         game_globals.garray[b->gameNum].numHalfMoves ?\r
-         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :\r
-         "none",\r
-         (orient == WHITE) ? 0 : 1);\r
-  strcat(bstring, tmp);\r
-  sprintf(tmp, ">10<\n");\r
-  strcat(bstring, tmp);\r
-  return 0;\r
-}\r
-\r
-/* Same as 8, but with verbose moves ("P/e3-e4", instead of "e4") */\r
-static int style11(struct game_state_t *b, struct move_t *ml)\r
-{\r
-  char tmp[160];\r
-  int f, r;\r
-  int ws, bs;\r
-\r
-  board_calc_strength(b, &ws, &bs);\r
-  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum,\r
-         game_globals.garray[b->gameNum].white_name,\r
-         (orient == WHITE) ? "*" : ":",\r
-         game_globals.garray[b->gameNum].black_name,\r
-         (orient == WHITE) ? ":" : "*");\r
-  strcat(bstring, tmp);\r
-  for (r = 0; r < b->ranks; r++) {\r
-    for (f = 0; f < b->files; f++) {\r
-      if (b->board[f][r] == NOPIECE) {\r
-       strcat(bstring, " ");\r
-      } else {\r
-       if (colorval(b->board[f][r]) == WHITE)\r
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
-       else\r
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
-      }\r
-    }\r
-  }\r
-    sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",\r
-           game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,\r
-           (b->onMove == WHITE) ? "W" : "B",\r
-           ws,\r
-           bs,\r
-           (wTime + 5) / 10,\r
-           (bTime + 5) / 10,\r
-           game_globals.garray[b->gameNum].numHalfMoves ?\r
-           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :\r
-           "none",\r
-           game_globals.garray[b->gameNum].numHalfMoves ?\r
-           tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :\r
-           "0:00");\r
-  strcat(bstring, tmp);\r
-  return 0;\r
-}\r
-
-
-int kludgeFlag = 0; \r
-/* Similar to style 10.  See the "style12" help file for information */\r
-static int style12(struct game_state_t *b, struct move_t *ml)\r
-{\r
-  int f, r;\r
-  char tmp[160]; // [HGM] 80 caused problems with long login names\r
+                            " c", " s", " g", " h", " a", " f", " e", " h", " m", " s", " e", " w", " o", " g", " v", " s", " e", " a", " k", " h", " e"};
+  static char *wsqr = "";
+  static char *bsqr = "";
+  static char *top = "\t:::::::::::::::::::::\n";
+  static char *mid = "";
+  static char *start = "..";
+  static char *end = " ..";
+  static char *label = "\t   a b c d e f g h i j k l\n";
+  static char *blabel = "\t   l k j i h g f e d c b a\n";
+
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* ICS interface maker board-- raw data dump */
+static int style8(struct game_state_t *b, struct move_t *ml)
+{
+  char tmp[160];
+  int f, r;
+  int ws, bs;
+
+  board_calc_strength(b, &ws, &bs);
+  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum + 1,
+         game_globals.garray[b->gameNum].white_name,
+         (orient == WHITE) ? "*" : ":",
+         game_globals.garray[b->gameNum].black_name,
+         (orient == WHITE) ? ":" : "*");
+  strcat(bstring, tmp);
+  for (r = 0; r < b->ranks; r++) {
+    for (f = 0; f < b->files; f++) {
+      if (b->board[f][r] == NOPIECE) {
+       strcat(bstring, " ");
+      } else {
+       if (colorval(b->board[f][r]) == WHITE)
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+       else
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+      }
+    }
+  }
+  sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
+         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
+         (b->onMove == WHITE) ? "W" : "B",
+         ws,
+         bs,
+         (wTime + 5) / 10,
+         (bTime + 5) / 10,
+         game_globals.garray[b->gameNum].numHalfMoves ?
+         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
+         "none",
+         game_globals.garray[b->gameNum].numHalfMoves ?
+         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+         "0:00");
+  strcat(bstring, tmp);
+  return 0;
+}
+
+/* last 2 moves only (previous non-verbose mode) */
+static int style9(struct game_state_t *b, struct move_t *ml)
+{
+  int i, count;
+  char tmp[160];
+  int startmove;
+
+  sprintf(tmp, "\nMove     %-23s%s\n",
+         game_globals.garray[b->gameNum].white_name,
+         game_globals.garray[b->gameNum].black_name);
+  strcat(bstring, tmp);
+  sprintf(tmp, "----     --------------         --------------\n");
+  strcat(bstring, tmp);
+  startmove = ((game_globals.garray[b->gameNum].numHalfMoves - 3) / 2) * 2;
+  if (startmove < 0)
+    startmove = 0;
+  for (i = startmove, count = 0;
+       i < game_globals.garray[b->gameNum].numHalfMoves && count < 4;
+       i++, count++) {
+    if (!(i & 0x01)) {
+      sprintf(tmp, "  %2d     ", i / 2 + 1);
+      strcat(bstring, tmp);
+    }
+    sprintf(tmp, "%-23s", move_and_time(&ml[i]));
+    strcat(bstring, tmp);
+    if (i & 0x01)
+      strcat(bstring, "\n");
+  }
+  if (i & 0x01)
+    strcat(bstring, "\n");
+  return 0;
+}
+
+/* Sleator's 'new and improved' raw dump format... */
+static int style10(struct game_state_t *b, struct move_t *ml)
+{
+  int f, r;
+  char tmp[160];
+  int ws, bs;
+
+  board_calc_strength(b, &ws, &bs);
+  sprintf(tmp, "<10>\n");
+  strcat(bstring, tmp);
+  for (r = b->ranks-1; r >= 0; r--) {
+    strcat(bstring, "|");
+    for (f = 0; f < b->files; f++) {
+      if (b->board[f][r] == NOPIECE) {
+       strcat(bstring, " ");
+      } else {
+       if (colorval(b->board[f][r]) == WHITE)
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+       else
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+      }
+    }
+    strcat(bstring, "|\n");
+  }
+  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
+  if (game_globals.garray[b->gameNum].numHalfMoves) {
+    sprintf(tmp, "%d ",
+           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);
+  } else {
+    sprintf(tmp, "-1 ");
+  }
+  strcat(bstring, tmp);
+  sprintf(tmp, "%d %d %d %d %d\n",
+         (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights
+         (b->wkmoved >= 0 && b->wqrmoved >= 0),
+         (b->bkmoved >= 0 && b->bkrmoved >= 0),
+         (b->bkmoved >= 0 && b->bqrmoved >= 0),
+       (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 :
+                                          b->lastIrreversable)));
+  strcat(bstring, tmp);
+  sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d\n",
+         b->gameNum,
+         game_globals.garray[b->gameNum].white_name,
+         game_globals.garray[b->gameNum].black_name,
+         myTurn,
+         game_globals.garray[b->gameNum].wInitTime / 600,
+         game_globals.garray[b->gameNum].wIncrement / 10,
+         ws,
+         bs,
+         (wTime + 5) / 10,
+         (bTime + 5) / 10,
+         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
+         game_globals.garray[b->gameNum].numHalfMoves ?
+         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
+         "none",
+         game_globals.garray[b->gameNum].numHalfMoves ?
+         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+         "0:00",
+         game_globals.garray[b->gameNum].numHalfMoves ?
+         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
+         "none",
+         (orient == WHITE) ? 0 : 1);
+  strcat(bstring, tmp);
+  sprintf(tmp, ">10<\n");
+  strcat(bstring, tmp);
+  return 0;
+}
+
+/* Same as 8, but with verbose moves ("P/e3-e4", instead of "e4") */
+static int style11(struct game_state_t *b, struct move_t *ml)
+{
+  char tmp[160];
+  int f, r;
+  int ws, bs;
+
+  board_calc_strength(b, &ws, &bs);
+  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum,
+         game_globals.garray[b->gameNum].white_name,
+         (orient == WHITE) ? "*" : ":",
+         game_globals.garray[b->gameNum].black_name,
+         (orient == WHITE) ? ":" : "*");
+  strcat(bstring, tmp);
+  for (r = 0; r < b->ranks; r++) {
+    for (f = 0; f < b->files; f++) {
+      if (b->board[f][r] == NOPIECE) {
+       strcat(bstring, " ");
+      } else {
+       if (colorval(b->board[f][r]) == WHITE)
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+       else
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+      }
+    }
+  }
+    sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
+           game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
+           (b->onMove == WHITE) ? "W" : "B",
+           ws,
+           bs,
+           (wTime + 5) / 10,
+           (bTime + 5) / 10,
+           game_globals.garray[b->gameNum].numHalfMoves ?
+           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
+           "none",
+           game_globals.garray[b->gameNum].numHalfMoves ?
+           tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+           "0:00");
+  strcat(bstring, tmp);
+  return 0;
+}
+
+
+int kludgeFlag = 0; 
+/* Similar to style 10.  See the "style12" help file for information */
+static int style12(struct game_state_t *b, struct move_t *ml)
+{
+  int f, r;
+  char tmp[160]; // [HGM] 80 caused problems with long login names
   int ws, bs; 
   int nhm = kludgeFlag ? 0 : game_globals.garray[b->gameNum].numHalfMoves; 
   // [HGM] setup: the number of half moves appeared in this routine an enormous number of times,
   // and had to be dug out of the game_globals, so that this routine could only be used to print
   // a board from a game, and not just any board given by an isolated game_state_t. This was very
   // inconvenient for printing initial boards in move lists of shuffle variants, so I added the
-  // global kludgeFlag to signal that we want to print an initial position, and force nhm = 0.\r
-\r
-  board_calc_strength(b, &ws, &bs);\r
-\r
-  sprintf(bstring, "<12> ");\r
-  for (r = b->ranks-1; r >= 0; r--) {\r
+  // global kludgeFlag to signal that we want to print an initial position, and force nhm = 0.
+
+  board_calc_strength(b, &ws, &bs);
+
+  sprintf(bstring, "<12> ");
+  for (r = b->ranks-1; r >= 0; r--) {
     for (f = 0; f < b->files; f++) {
-      if (b->board[f][r] == NOPIECE) {\r
-       strcat(bstring, "-");\r
-      } else {\r
-       if (colorval(b->board[f][r]) == WHITE)\r
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
-       else\r
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
-      }\r
-    }\r
-    strcat(bstring, " ");\r
+      if (b->board[f][r] == NOPIECE) {
+       strcat(bstring, "-");
+      } else {
+       if (colorval(b->board[f][r]) == WHITE)
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+       else
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+      }
+    }
+    strcat(bstring, " ");
+  }
+
+  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
+  if (nhm) {
+    sprintf(tmp, "%d ",
+           ml[nhm - 1].doublePawn);
+  } else {
+    sprintf(tmp, "-1 ");
   }
-\r
-  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");\r
-  if (nhm) {\r
-    sprintf(tmp, "%d ",\r
-           ml[nhm - 1].doublePawn);\r
-  } else {\r
-    sprintf(tmp, "-1 ");\r
-  }\r
-  strcat(bstring, tmp);\r
-  sprintf(tmp, "%d %d %d %d %d ",\r
-         (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights\r
-         (b->wkmoved >= 0 && b->wqrmoved >= 0),\r
-         (b->bkmoved >= 0 && b->bkrmoved >= 0),\r
-         (b->bkmoved >= 0 && b->bqrmoved >= 0),\r
-         (nhm - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable)));\r
   strcat(bstring, tmp);
-  sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d %d\n",\r
-         b->gameNum + 1,\r
-         game_globals.garray[b->gameNum].white_name,\r
-         game_globals.garray[b->gameNum].black_name,\r
-         myTurn,\r
-         game_globals.garray[b->gameNum].wInitTime / 600,\r
-         game_globals.garray[b->gameNum].wIncrement / 10,\r
-         ws,\r
-         bs,\r
-         (wTime / 10),\r
-         (bTime / 10),\r
-         nhm / 2 + 1,\r
-         nhm ?\r
-         ml[nhm - 1].moveString :\r
-         "none",\r
-         nhm ?\r
-         tenth_str(ml[nhm - 1].tookTime, 0) :\r
-         "0:00",\r
-         nhm ?\r
-         ml[nhm - 1].algString :\r
-         "none", (orient == WHITE) ? 0 : 1,\r
-         b->moveNum > 1 ? 1 : 0); /* ticking */\r
-
-  strcat(bstring, tmp);\r
-  return 0;\r
-}\r
+  sprintf(tmp, "%d %d %d %d %d ",
+         (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights
+         (b->wkmoved >= 0 && b->wqrmoved >= 0),
+         (b->bkmoved >= 0 && b->bkrmoved >= 0),
+         (b->bkmoved >= 0 && b->bqrmoved >= 0),
+         (nhm - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable)));
+  strcat(bstring, tmp);
+  sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d %d\n",
+         b->gameNum + 1,
+         game_globals.garray[b->gameNum].white_name,
+         game_globals.garray[b->gameNum].black_name,
+         myTurn,
+         game_globals.garray[b->gameNum].wInitTime / 600,
+         game_globals.garray[b->gameNum].wIncrement / 10,
+         ws,
+         bs,
+         (wTime / 10),
+         (bTime / 10),
+         nhm / 2 + 1,
+         nhm ?
+         ml[nhm - 1].moveString :
+         "none",
+         nhm ?
+         tenth_str(ml[nhm - 1].tookTime, 0) :
+         "0:00",
+         nhm ?
+         ml[nhm - 1].algString :
+         "none", (orient == WHITE) ? 0 : 1,
+         b->moveNum > 1 ? 1 : 0); /* ticking */
+
+  strcat(bstring, tmp);
+  return 0;
+}
 
 static int board_read_file(char *category, char *gname, struct game_state_t *gs)
 {
@@ -1023,6 +1024,9 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs)
            case 'd':
                gs->drops = 1;
                break;
+           case 'g':
+               gs->drops = 2;
+               break;
            case 'h':
                gs->holdings = -1;     // color-flip holdings
                break;
@@ -1088,15 +1092,15 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs)
       case 'B':
        onPiece = BISHOP;
        break;
-      case 'A':\r
-       onPiece = CARDINAL;\r
-       break;\r
-      case 'C':\r
-       onPiece = MARSHALL;\r
-       break;\r
-      case 'M':\r
-       onPiece = MAN;\r
-       break;\r
+      case 'A':
+       onPiece = CARDINAL;
+       break;
+      case 'C':
+       onPiece = MARSHALL;
+       break;
+      case 'M':
+       onPiece = MAN;
+       break;
       case 'Q':
        onPiece = QUEEN;
        break;
@@ -1175,41 +1179,48 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs)
       case 'K':
        onPiece = KING;
        break;
-      case 'a':\r
-      case 'b':\r
-      case 'c':\r
-      case 'd':\r
-      case 'e':\r
-      case 'f':\r
-      case 'g':\r
-      case 'h':\r
-      case 'i':\r
-      case 'j':\r
-      case 'k':\r
-      case 'l':\r
-       onFile = c - 'a';\r
-        if(onFile >= gs->files) { onFile = -1; break; }\r
-       onRank = -1;\r
-       break;\r
+      case 'D':
+       onPiece = SELEPHANT;
+       break;
+      case 'U':
+       onPiece = HAWK;
+       break;
+      case 'a':
+      case 'b':
+      case 'c':
+      case 'd':
+      case 'e':
+      case 'f':
+      case 'g':
+      case 'h':
+      case 'i':
+      case 'j':
+      case 'k':
+      case 'l':
+       onFile = c - 'a';
+        if(onFile >= gs->files) { onFile = -1; break; }
+       onRank = -1;
+       break;
       case '@':
-       if (onColor >= 0 && onPiece >= 0) // allow placement in holdings\r
+       if (onColor >= 0 && onPiece >= 0) // allow placement in holdings
          gs->holding[onColor == BLACK][onPiece-1]++;
-       break;\r
-      case '1':\r
-      case '2':\r
-      case '3':\r
-      case '4':\r
-      case '5':\r
-      case '6':\r
-      case '7':\r
-      case '8':\r
-      case '9':\r
-      case '0':\r
-       onRank = c - '1' + (gs->ranks > 9);\r
-        if(onRank < 0 || onRank >= gs->ranks) { onRank = -1; break; }\r
-       if (onFile >= 0 && onColor >= 0 && onPiece >= 0)\r
-         gs->board[onFile][onRank] = onPiece | onColor;\r
-       break;\r      case '#':
+       break;
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '0':
+       onRank = c - '1' + (gs->ranks > 9);
+        if(onRank < 0 || onRank >= gs->ranks) { onRank = -1; break; }
+       if (onFile >= 0 && onColor >= 0 && onPiece >= 0)
+         gs->board[onFile][onRank] = onPiece | onColor;
+       break;
+      case '#':
        while (!feof(fp) && c != '\n')
          c = fgetc(fp);        /* Comment line */
       case '\n':
index c1aa22f..611ff80 100644 (file)
@@ -65,6 +65,9 @@
 #define EMPRESS 34
 #define AMAZON 35
 #define KING 36
+#define HAWK 37
+#define SELEPHANT 38
+#define PIECES 39
 
 #define MAX_BOARD_STRING_LENGTH 1280   /* Abitrarily 80 * 16 */
 #define MAX_STYLES 13
 #define W_MASTODON (MASTODON | WHITE)
 #define W_MAN2 (MAN2 | WHITE)
 #define W_NIGHTRIDER (NIGHTRIDER | WHITE)
+#define W_HAWK (HAWK | WHITE)
+#define W_SELEPHANT (SELEPHANT | WHITE)
 
 #define B_PAWN (PAWN | BLACK)
 #define B_KNIGHT (KNIGHT | BLACK)
 #define B_MASTODON (MASTODON | BLACK)
 #define B_MAN2 (MAN2 | BLACK)
 #define B_NIGHTRIDER (NIGHTRIDER | BLACK)
+#define B_HAWK (HAWK | BLACK)
+#define B_SELEPHANT (SELEPHANT | BLACK)
 
 #define isblack(p) ((p) & BLACK)
 #define iswhite(p) (!isblack(p))
 #define colorval(p) ((p) & 0x80)
 #define square_color(r,f) ((((r)+(f)) & 0x01) ? BLACK : WHITE)
 
-extern int pieceValues[KING+1];
+extern int pieceValues[PIECES];
 
 #define BW 12
 #define BH 10
@@ -156,7 +163,7 @@ typedef int board_t[BW][BH];
 GENSTRUCT struct game_state_t {
        int board[BW][BH];
        /* for bughouse */
-       int holding[2][KING];
+       int holding[2][PIECES];
        /* For castling */
        char wkmoved, wqrmoved, wkrmoved;
        char bkmoved, bqrmoved, bkrmoved;
index b7aab88..52f42e2 100644 (file)
@@ -434,6 +434,18 @@ static int was_promoted(struct game *g, int f, int r)
   return 0;
 }
 
+static int is_virgin(struct game *g, int f, int r)
+{
+  int i;
+
+  for (i = g->numHalfMoves-2; i > 0; i -= 2) {
+    if (g->moveList[i].toFile == f && g->moveList[i].toRank == r) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
 int pIsPlaying (int p)
 {
        struct player *pp = &player_globals.parray[p];
@@ -561,7 +573,7 @@ void process_move(int p, char *command)
   }
   pp->promote = NOPIECE; // [HGM] this seemed to be uninitialized, which caused spurious promotion in Shogi
   if ((len = strlen(command)) > 1) {
-    if (command[len - 2] == '=') {
+    if (command[len - 2] == '=' || gg->gameState.drops == 2 && command[len - 2] == '/') { // [HGM] encode gating as promotion
 printf("promo '%s'\n", command);
       switch (tolower(command[strlen(command) - 1])) {
       case 'n':
index 1e79943..88c0366 100644 (file)
@@ -531,6 +531,9 @@ static int parse_match_string(int p, int* wt,int* bt,int* winc,int* binc,
        if(!strcmp("su", category)) {
          strcpy(category, "super");
        } else
+       if(!strcmp("sc", category)) {
+         strcpy(category, "seirawan");
+       } else
        if(!strcmp("sg", category)) {
          strcpy(category, "shogi");
        } else
index 8f0dd9c..6996d09 100644 (file)
@@ -1296,7 +1296,7 @@ int legal_move(struct game_state_t * gs,
 
   if (fFile == ALG_DROP) {
     move_piece = fRank;
-    if(!gs->drops) return 0; // [HGM] variants: no drops in this variant
+    if(gs->drops != 1) return 0; // [HGM] variants: no drops in this variant
     if (move_piece == KING)
       return 0;
     if (gs->holding[gs->onMove==WHITE ? 0 : 1][move_piece-1] == 0)
@@ -1387,10 +1387,12 @@ int legal_move(struct game_state_t * gs,
   case ROOK:
     legal = legal_rook_move(gs, fFile, fRank, tFile, tRank);
     break;
+  case HAWK:
   case CARDINAL:
   case PRINCESS:
     legal = legal_cardinal_move(gs, fFile, fRank, tFile, tRank);
     break;
+  case SELEPHANT:
   case MARSHALL:
   case EMPRESS:
     legal = legal_marshall_move(gs, fFile, fRank, tFile, tRank);
@@ -1484,6 +1486,7 @@ int legal_move(struct game_state_t * gs,
 static int move_calculate(struct game_state_t * gs, struct move_t * mt, int promote)
 {
   struct game_state_t fakeMove;
+  int gating = 0;
 
   mt->pieceCaptured = gs->board[mt->toFile][mt->toRank];
   mt->enPassant = 0;           /* Don't know yet, let execute move take care
@@ -1536,15 +1539,23 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
     int stm = colorval(gs->board[mt->fromFile][mt->fromRank]);
     if(!promote && (mt->toRank == 0 || mt->toRank == gs->ranks-1)) { // promotion obligatory, but not specified
        if(gs->promoType != 2) promote = QUEEN; else { // choose a default
-           for(promote=KING-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break;
+           for(promote=PIECES-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break;
            if(promote == PAWN) return MOVE_ILLEGAL; // nothing available
        }
-    } // if not obligatory, we defer unless promoton was explicitly specified!
+    } // if not obligatory, we defer unless promotion was explicitly specified!
     if(!gs->pawnDblStep && promote == PRINCESS) promote = MAN2;
     if(!gs->pawnDblStep && promote != FERZ2 && promote != MAN2) promote = FERZ; // [HGM] kludge to recognize shatranj
     // non-promotion can still be an option for deeper promotion zones
     mt->piecePromotionTo = promote ? (promote | stm) : NOPIECE;
     if(promote && gs->promoType == 2 && !gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified
+  } else if(gs->drops == 2 && promote && mt->fromRank == (stm == WHITE ? 0 : gs->ranks-1)) { // [HGM] Seirawan-style gating
+    int i; struct game *g = &game_globals.garray[gs->gameNum];
+    if(!gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified
+    // now we must test virginity of the moved piece. Yegh!
+    for (i = g->numHalfMoves-2; i > 0; i -= 2) {
+      if (g->moveList[i].toFile == mt->fromFile && g->moveList[i].toRank == mt->fromRank) return MOVE_ILLEGAL;
+    }
+    gating = 1; // gating OK; remember we did it for check test
   } else {
     mt->piecePromotionTo = NOPIECE;
   }
@@ -1579,6 +1590,7 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   fakeMove = *gs;
   /* Calculates enPassant also */
   execute_move(&fakeMove, mt, 0);
+  if(gating) fakeMove.board[mt-fromFile][mt->fromRank] = NOPIECE; // [HGM] gating is only legal if non-gating move was (weird, but true)
 
   /* Does making this move leave ME in check? */
   if (in_check(&fakeMove))
@@ -1667,10 +1679,12 @@ int has_legal_move(struct game_state_t * gs)
     case ROOK:
       possible_rook_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
+    case HAWK:
     case CARDINAL:
     case PRINCESS:
       possible_cardinal_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
+    case SELEPHANT:
     case MARSHALL:
     case EMPRESS:
       possible_marshall_moves(gs, f, r, possiblef, possibler, &numpossible);
@@ -1922,13 +1936,19 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
   } else {
   movedPiece = gs->board[mt->fromFile][mt->fromRank];
   tookPiece = gs->board[mt->toFile][mt->toRank];
-  if (mt->piecePromotionTo == NOPIECE) {
+  if(gs->drops == 2 && mt->piecePromotionTo != NOPIECE && pieceType(movedPiece) != PAWN) { // [HGM] Seirawan-style gating
     gs->board[mt->toFile][mt->toRank] = gs->board[mt->fromFile][mt->fromRank];
+    gs->board[mt->fromFile][mt->fromRank] = mt->piecePromotionTo | gs->onMove;;
+    gs->holding[gs->onMove==WHITE ? 0 : 1][mt->piecePromotionTo-1]--; // remove gated piece from holdings
   } else {
-    gs->board[mt->toFile][mt->toRank] = mt->piecePromotionTo | gs->onMove;
-    if(gs->promoType == 2) gs->holding[gs->onMove][mt->piecePromotionTo-1]--;
+    if (mt->piecePromotionTo == NOPIECE) {
+      gs->board[mt->toFile][mt->toRank] = gs->board[mt->fromFile][mt->fromRank];
+    } else {
+      gs->board[mt->toFile][mt->toRank] = mt->piecePromotionTo | gs->onMove;
+      if(gs->promoType == 2) gs->holding[gs->onMove][mt->piecePromotionTo-1]--;
+    }
+    gs->board[mt->fromFile][mt->fromRank] = NOPIECE;
   }
-  gs->board[mt->fromFile][mt->fromRank] = NOPIECE;
   /* Check if irreversable */
   if ((piecetype(movedPiece) == PAWN) && (mt->fromRank != mt->toRank) // [HGM] XQ: sideway Pawn move reversible!
                        || (tookPiece != NOPIECE)) {
@@ -2243,6 +2263,9 @@ int backup_move(int g, int mode)
     goto cleanupMove;
   }
   gs->board[m->toFile][m->toRank] = m->pieceCaptured;
+  if(gs->board[m->fromFile][m->fromRank] != NOPIECE) { // [HGM] from-square occupied, must have been Seirawan-style gating
+    gs->holding[gs->onMove==WHITE ? 1 : 0][piecetype(gs->board[m->fromFile][m->fromRank])-1]++; // put back in holdings (onMove not flipped yet!)
+  }
 cleanupMove:
   if (game_globals.garray[g].status != GAME_EXAMINE) {
     game_update_time(g);