Check validity of promotion piece in long algebraic
[capablanca.git] / lasker-2.2.3 / src / movecheck.c
index 468a8a3..6d05050 100644 (file)
 int is_move(const char *mstr)
 {
   int len = strlen(mstr);
-  if ((len > 3) && (mstr[len - 2] == '='))
-    len -= 2;
-
   /* remove the 'mates' marker */
   if (mstr[len - 1] == '#')
     len--;
 
+  if ((len > 3) && (mstr[len - 2] == '=' || mstr[len - 2] == '/'))
+    len -= 2;
+
   if (len == 4) {              /* Test for e2e4 */
     if (isfile(mstr[0]) && isrank(mstr[1]) &&
        isfile(mstr[2]) && isrank(mstr[3])) {
@@ -140,21 +140,21 @@ int InitPieceLoop(board_t b, int *f, int *r, int color)
 /* See legal_move() */
 static int legal_pawn_move( struct game_state_t *gs, int ff, int fr, int tf, int tr )
 {
-  if (ff == tf) {\r
-    if (gs->board[tf][tr] != NOPIECE && !gs->palace && gs->promoType != 3) return 0; // [HGM] XQ and Shogi pawns can capture straight ahead\r
-    if (gs->onMove == WHITE) {\r
-      if (tr - fr == 1) return 1;\r
+  if (ff == tf) {
+    if (gs->board[tf][tr] != NOPIECE && !gs->palace && gs->promoType != 3) return 0; // [HGM] XQ and Shogi pawns can capture straight ahead
+    if (gs->onMove == WHITE) {
+      if (tr - fr == 1) return 1;
       if ((fr <= gs->pawnDblStep) && (tr - fr == 2) && gs->board[ff][fr+1]==NOPIECE) return 1;
-    } else {\r
-      if (fr - tr == 1) return 1;\r
-      if ((fr >= gs->ranks - 1 - gs->pawnDblStep) && (fr - tr == 2) && gs->board[ff][fr-1]==NOPIECE) return 1;\r
-    }\r
-    return 0;\r
-  }\r
+    } else {
+      if (fr - tr == 1) return 1;
+      if ((fr >= gs->ranks - 1 - gs->pawnDblStep) && (fr - tr == 2) && gs->board[ff][fr-1]==NOPIECE) return 1;
+    }
+    return 0;
+  }
   if (ff != tf && gs->promoType != 3) { /* Capture ? ([HGM] but not in Shogi) */
     if ((ff - tf != 1) && (tf - ff != 1)) return 0;
     if (gs->onMove == WHITE) {
-      if(gs->palace) return (fr >= gs->ranks/2 && fr == tr); // [HGM] XQ promoted pawns\r
+      if(gs->palace) return (fr >= gs->ranks/2 && fr == tr); // [HGM] XQ promoted pawns
       if (tr != fr+1) return 0;
       if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],BLACK))
         return 1;
@@ -164,7 +164,7 @@ static int legal_pawn_move( struct game_state_t *gs, int ff, int fr, int tf, int
         if ((tf==ff-1) && (gs->board[ff-1][fr] == B_PAWN)) return 1;
       }
     } else {
-      if(gs->palace) return (fr < gs->ranks/2 && fr == tr); // [HGM] XQ promoted pawns\r
+      if(gs->palace) return (fr < gs->ranks/2 && fr == tr); // [HGM] XQ promoted pawns
       if (tr != fr-1) return 0;
       if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],WHITE))
         return 1;
@@ -178,6 +178,36 @@ static int legal_pawn_move( struct game_state_t *gs, int ff, int fr, int tf, int
   return 0;
 }
 
+static int legal_hoplite_move( struct game_state_t *gs, int ff, int fr, int tf, int tr )
+{
+  if (ff == tf) { /* Capture ? */
+    if (gs->board[tf][tr] == NOPIECE) return 0;
+    if (gs->onMove == WHITE) {
+      if(iscolor(gs->board[tf][tr],WHITE)) return 0;
+      if (tr - fr == 1) return 1;
+    } else {
+      if(iscolor(gs->board[tf][tr],BLACK)) return 0;
+      if (fr - tr == 1) return 1;
+    }
+    return 0;
+  }
+  if (ff != tf) {
+    if (gs->board[tf][tr] != NOPIECE) return 0;
+    if (gs->onMove == WHITE) {
+      if (tr == fr+1 && abs(tf-ff) == 1) return 1;
+      if (tr != fr+2 || abs(tf-ff) != 2) return 0;
+      if (fr > gs->pawnDblStep) return 0;
+        return 1;
+    } else {
+      if (tr == fr-1 && abs(tf-ff) == 1) return 1;
+      if (tr != fr-2 || abs(tf-ff) != 2) return 0;
+      if (fr < gs->ranks - 1 - gs->pawnDblStep) return 0;
+        return 1;
+    }
+  }
+  return 0;
+}
+
 static int legal_knight_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
 {
   int dx, dy;
@@ -366,16 +396,16 @@ static int legal_queen_move(struct game_state_t * gs, int ff, int fr, int tf, in
   return legal_rook_move(gs, ff, fr, tf, tr) || legal_bishop_move(gs, ff, fr, tf, tr);
 }
 
-static int legal_cardinal_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_knight_move(gs, ff, fr, tf, tr) || legal_bishop_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_marshall_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_rook_move(gs, ff, fr, tf, tr) || legal_knight_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
+static int legal_cardinal_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_knight_move(gs, ff, fr, tf, tr) || legal_bishop_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_marshall_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_rook_move(gs, ff, fr, tf, tr) || legal_knight_move(gs, ff, fr, tf, tr);
+}
+
 /* Ckeck, if square (kf,kr) is attacked by enemy piece.
  * Used in castling from/through check testing.
  */
@@ -387,7 +417,7 @@ static int is_square_attacked (struct game_state_t *gs, int kf, int kr)
   int oldk = gs->onMove == WHITE ? gs->wkmoved : gs->bkmoved;
 
   fakeMove = *gs;
-  fakeMove.board[oldk][kr] = NOPIECE; // [HGM] castle: this routine is called only when King has not moved\r
+  fakeMove.board[oldk][kr] = NOPIECE; // [HGM] castle: this routine is called only when King has not moved
   fakeMove.board[kf][kr] = KING | fakeMove.onMove;
   fakeMove.onMove = CToggle (fakeMove.onMove);
   if (in_check(&fakeMove)) return 1;
@@ -412,148 +442,154 @@ static int is_square_attacked(struct game_state_t * gs, int kf, int kr)
 }
 */
 
-static int legal_man_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  if (abs(ff - tf) > 1)\r
-    return 0;\r
-  if (abs(fr - tr) > 1)\r
-    return 0;\r
-  return 1;\r
-}\r
-\r
-static int legal_wazir_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
+static int legal_man_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  if (abs(ff - tf) > 1)
+    return 0;
+  if (abs(fr - tr) > 1)
+    return 0;
+  return 1;
+}
+
+static int legal_wazir_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
   if(gs->palace && (tr > gs->palace && tr < gs->ranks - gs->palace ||
      tf < (gs->files - gs->palace)/2 || tf >= (gs->files + gs->palace)/2))
-    return 0;\r
-  if (abs(ff - tf) == 1 && fr == tr)\r
-    return 1;\r
-  if (abs(fr - tr) == 1 && ff == tf)\r
-    return 1;\r
-  return 0;\r
-}\r
-\r
-static int legal_dababba_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  if (abs(ff - tf) == 2 && fr == tr)\r
-    return 1;\r
-  if (abs(fr - tr) == 2 && ff == tf)\r
-    return 1;\r
-  return 0;\r
-}\r
-\r
-static int legal_ferz_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  if (abs(ff - tf) != 1)\r
-    return 0;\r
-  if (abs(fr - tr) != 1)\r
-    return 0;\r
-  return 1;\r
-}\r
-
-static int legal_mandarin_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
+    return 0;
+  if (abs(ff - tf) == 1 && fr == tr)
+    return 1;
+  if (abs(fr - tr) == 1 && ff == tf)
+    return 1;
+  return 0;
+}
+
+static int legal_dababba_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  if (abs(ff - tf) == 2 && fr == tr)
+    return 1;
+  if (abs(fr - tr) == 2 && ff == tf)
+    return 1;
+  return 0;
+}
+
+static int legal_ferz_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  if (abs(ff - tf) != 1)
+    return 0;
+  if (abs(fr - tr) != 1)
+    return 0;
+  return 1;
+}
+
+static int legal_mandarin_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
   if(gs->palace && (tr > gs->palace && tr < gs->ranks - gs->palace ||
      tf < (gs->files - gs->palace)/2 || tf >= (gs->files + gs->palace)/2))
-    return 0;\r
-  if (abs(ff - tf) != 1)\r
-    return 0;\r
-  if (abs(fr - tr) != 1)\r
-    return 0;\r
-  return 1;\r
-}\r
-\r
-static int legal_alfil_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{
-  if (abs(ff - tf) != 2)\r
-    return 0;\r
-  if (abs(fr - tr) != 2)\r
-    return 0;\r
-  return 1;\r
-}\r
-\r
-static int legal_elephant_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  if (abs(ff - tf) != 2)\r
-    return 0;\r
-  if (abs(fr - tr) != 2)\r
+    return 0;
+  if (abs(ff - tf) != 1)
+    return 0;
+  if (abs(fr - tr) != 1)
+    return 0;
+  return 1;
+}
+
+static int legal_alfil_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  if (abs(ff - tf) != 2)
+    return 0;
+  if (abs(fr - tr) != 2)
+    return 0;
+  return 1;
+}
+
+static int legal_elephant_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  if (abs(ff - tf) != 2)
+    return 0;
+  if (abs(fr - tr) != 2)
     return 0;
   if(gs->board[(ff+tf)/2][(fr+tr)/2] != NOPIECE) return 0; // blocked
-  if((tr >= gs->ranks/2) != (fr >= gs->ranks/2)) return 0; // do not cross river\r
-  return 1;\r
-}\r
-\r
-static int legal_gold_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_wazir_move(gs, ff, fr, tf, tr) || (abs(ff-tf) == 1 && tr == fr + (gs->onMove==WHITE ? 1 : -1));\r
-}\r
-\r
-static int legal_silver_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_ferz_move(gs, ff, fr, tf, tr) || (tf == ff && tr == fr + (gs->onMove==WHITE ? 1 : -1) );\r
-}\r
-\r
-static int legal_woody_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_wazir_move(gs, ff, fr, tf, tr) || legal_dababba_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_squirrel_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
+  if((tr >= gs->ranks/2) != (fr >= gs->ranks/2)) return 0; // do not cross river
+  return 1;
+}
+
+static int legal_gold_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_wazir_move(gs, ff, fr, tf, tr) || (abs(ff-tf) == 1 && tr == fr + (gs->onMove==WHITE ? 1 : -1));
+}
+
+static int legal_silver_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_ferz_move(gs, ff, fr, tf, tr) || (tf == ff && tr == fr + (gs->onMove==WHITE ? 1 : -1) );
+}
+
+static int legal_woody_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_wazir_move(gs, ff, fr, tf, tr) || legal_dababba_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_squirrel_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
   return legal_alfil_move(gs, ff, fr, tf, tr) || legal_dababba_move(gs, ff, fr, tf, tr) 
-                                                       || legal_knight_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_mastodon_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
+                                                       || legal_knight_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_mastodon_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
   return legal_man_move(gs, ff, fr, tf, tr) || legal_alfil_move(gs, ff, fr, tf, tr)
-                                                       || legal_dababba_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_centaur_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_man_move(gs, ff, fr, tf, tr) || legal_knight_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_amazon_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_queen_move(gs, ff, fr, tf, tr) || legal_knight_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_dragonking_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_rook_move(gs, ff, fr, tf, tr) || legal_ferz_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_dragonhorse_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_bishop_move(gs, ff, fr, tf, tr) || legal_wazir_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_modernelephant_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
-  return legal_ferz_move(gs, ff, fr, tf, tr) || legal_alfil_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_priestess_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
+                                                       || legal_dababba_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_centaur_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_man_move(gs, ff, fr, tf, tr) || legal_knight_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_amazon_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_queen_move(gs, ff, fr, tf, tr) || legal_knight_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_dragonking_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_rook_move(gs, ff, fr, tf, tr) || legal_ferz_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_dragonhorse_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_bishop_move(gs, ff, fr, tf, tr) || legal_wazir_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_modernelephant_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_ferz_move(gs, ff, fr, tf, tr) || legal_alfil_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_lieutenant_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+  return legal_modernelephant_move(gs, ff, fr, tf, tr) ||
+        fr == tr && abs(ff - tf) == 1 && gs->board[tf][tr] == NOPIECE;
+}
+
+static int legal_priestess_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
   return legal_knight_move(gs, ff, fr, tf, tr) || legal_ferz_move(gs, ff, fr, tf, tr)
-                                               || legal_alfil_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
-static int legal_minister_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)\r
-{\r
+                                               || legal_alfil_move(gs, ff, fr, tf, tr);
+}
+
+static int legal_minister_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
   return legal_knight_move(gs, ff, fr, tf, tr) || legal_wazir_move(gs, ff, fr, tf, tr)
-                                               || legal_dababba_move(gs, ff, fr, tf, tr);\r
-}\r
-\r
+                                               || legal_dababba_move(gs, ff, fr, tf, tr);
+}
+
 static int legal_king_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
 {
   int result;
 
   // [HGM] castle: test first if valid as regular King move; result = 1 or 0
-  if(gs->royalKnight)\r
-    result = legal_knight_move(gs, ff, fr, tf, tr);\r
+  if(gs->royalKnight)
+    result = legal_knight_move(gs, ff, fr, tf, tr);
   else if(gs->palace) {
     result = legal_wazir_move(gs, ff, fr, tf, tr);
     if(!result && ff == tf && piecetype(gs->board[tf][tr]) == KING) { // XQ regicide
@@ -562,50 +598,54 @@ static int legal_king_move(struct game_state_t * gs, int ff, int fr, int tf, int
        if(gs->board[ff][i] != NOPIECE) return 0; // line of sight blocked
       return 1;
     }
-  } else\r
+  } else
     result = legal_man_move(gs, ff, fr, tf, tr);
 
-  if(result) return 1;\r
+  if(result) return 1;
   // [HGM] castle: orthodox legal castlings given as King move return 2
 
-  if (gs->onMove == WHITE) {\r
-    /* King side castling */\r
-    if ((fr == 0) && (tr == 0) && (ff == gs->files/2) && (tf == gs->files-2) && (gs->wkmoved >= 0)\r
-       && (gs->wkrmoved >= 0) && (gs->board[gs->files-3][0] == NOPIECE) &&\r
-       (gs->board[gs->files-2][0] == NOPIECE) && (gs->board[gs->files-1][0] == W_ROOK) &&\r
-       (gs->board[gs->files/2+1][0] == NOPIECE) && (!is_square_attacked(gs, gs->files/2+1, 0)) &&\r
-       (!is_square_attacked(gs, gs->files/2, 0)) && (!is_square_attacked(gs, gs->files-3, 0))) {\r
-      return 2;\r
-    }\r
-    /* Queen side castling */\r
-    if ((fr == 0) && (tr == 0) && (ff == gs->files/2) && (tf == 2) && (gs->wkmoved >= 0)\r
-       && (gs->wqrmoved >= 0) && (gs->board[3][0] == NOPIECE) &&\r
-       (gs->board[2][0] == NOPIECE) && (gs->board[1][0] == NOPIECE) &&\r
-       (gs->board[0][0] == W_ROOK) &&\r
-       (gs->board[gs->files/2-1][0] == NOPIECE) && (!is_square_attacked(gs, gs->files/2-1, 0)) &&\r
-       (!is_square_attacked(gs, gs->files/2, 0)) && (!is_square_attacked(gs, 3, 0))) {\r
-      return 2;\r
-    }\r
-  } else {                     /* Black */\r
-    /* King side castling */\r
-    if ((fr == gs->ranks-1) && (tr == gs->ranks-1) && (ff == gs->files/2) && (tf == gs->files-2) && (gs->bkmoved >= 0)\r
-       && (gs->bkrmoved >= 0) && (gs->board[gs->files-3][7] == NOPIECE) &&\r
-       (gs->board[gs->files-2][gs->ranks-1] == NOPIECE) && (gs->board[gs->files-1][gs->ranks-1] == B_ROOK) &&\r
-       (gs->board[gs->files/2+1][gs->ranks-1] == NOPIECE) && (!is_square_attacked(gs, gs->files/2+1, gs->ranks-1)) &&\r
-       (!is_square_attacked(gs, gs->files/2, gs->ranks-1)) && (!is_square_attacked(gs, gs->files-3, gs->ranks-1))) {\r
-      return 2;\r
-    }\r
-    /* Queen side castling */\r
-    if ((fr == gs->ranks-1) && (tr == gs->ranks-1) && (ff == gs->files/2) && (tf == 2) && (gs->bkmoved >= 0)\r
-       && (gs->bqrmoved >= 0) && (gs->board[3][gs->ranks-1] == NOPIECE) &&\r
-       (gs->board[2][gs->ranks-1] == NOPIECE) && (gs->board[1][gs->ranks-1] == NOPIECE) &&\r
-       (gs->board[0][gs->ranks-1] == B_ROOK) &&\r
-       (gs->board[gs->files/2-1][gs->ranks-1] == NOPIECE) && (!is_square_attacked(gs, gs->files/2-1, gs->ranks-1)) &&\r
-       (!is_square_attacked(gs, gs->files/2, gs->ranks-1)) && (!is_square_attacked(gs, 3, gs->ranks-1))) {\r
-      return 2;\r
-    }\r
-  }
-\r
+  if (gs->onMove == WHITE) {
+    /* King side castling */
+    if ((fr == 0) && (tr == 0) && ((ff == gs->files/2) && (tf == gs->files-2) ||
+                gs->drops == 2 && (tf == gs->files/2) && (ff == gs->files-1)) // [HGM] reverse Seirawan gating
+       && (gs->wkmoved >= 0) && (gs->wkrmoved >= 0) && (gs->board[gs->files-3][0] == NOPIECE) &&
+       (gs->board[gs->files-2][0] == NOPIECE) && (gs->board[gs->files-1][0] == W_ROOK) &&
+       (gs->board[gs->files/2+1][0] == NOPIECE) && (!is_square_attacked(gs, gs->files/2+1, 0)) &&
+       (!is_square_attacked(gs, gs->files/2, 0)) && (!is_square_attacked(gs, gs->files-3, 0))) {
+      return 2;
+    }
+    /* Queen side castling */
+    if ((fr == 0) && (tr == 0) && ((ff == gs->files/2) && (tf == 2) ||
+                gs->drops == 2 && (tf == gs->files/2) && (ff == 0)) // [HGM] reverse Seirawan gating
+       && (gs->wkmoved >= 0) && (gs->wqrmoved >= 0) && (gs->board[3][0] == NOPIECE) &&
+       (gs->board[2][0] == NOPIECE) && (gs->board[1][0] == NOPIECE) &&
+       (gs->board[0][0] == W_ROOK) &&
+       (gs->board[gs->files/2-1][0] == NOPIECE) && (!is_square_attacked(gs, gs->files/2-1, 0)) &&
+       (!is_square_attacked(gs, gs->files/2, 0)) && (!is_square_attacked(gs, 3, 0))) {
+      return 2;
+    }
+  } else {                     /* Black */
+    /* King side castling */
+    if ((fr == gs->ranks-1) && (tr == gs->ranks-1) && ((ff == gs->files/2) && (tf == gs->files-2) ||
+                                    gs->drops == 2 && (tf == gs->files/2) && (ff == gs->files-1)) // [HGM] reverse Seirawan gating
+       && (gs->bkmoved >= 0) && (gs->bkrmoved >= 0) && (gs->board[gs->files-3][7] == NOPIECE) &&
+       (gs->board[gs->files-2][gs->ranks-1] == NOPIECE) && (gs->board[gs->files-1][gs->ranks-1] == B_ROOK) &&
+       (gs->board[gs->files/2+1][gs->ranks-1] == NOPIECE) && (!is_square_attacked(gs, gs->files/2+1, gs->ranks-1)) &&
+       (!is_square_attacked(gs, gs->files/2, gs->ranks-1)) && (!is_square_attacked(gs, gs->files-3, gs->ranks-1))) {
+      return 2;
+    }
+    /* Queen side castling */
+    if ((fr == gs->ranks-1) && (tr == gs->ranks-1) && ((ff == gs->files/2) && (tf == 2) ||
+                                    gs->drops == 2 && (tf == gs->files/2) && (ff == 0)) // [HGM] reverse Seirawan gating
+       && (gs->bkmoved >= 0) && (gs->bqrmoved >= 0) && (gs->board[3][gs->ranks-1] == NOPIECE) &&
+       (gs->board[2][gs->ranks-1] == NOPIECE) && (gs->board[1][gs->ranks-1] == NOPIECE) &&
+       (gs->board[0][gs->ranks-1] == B_ROOK) &&
+       (gs->board[gs->files/2-1][gs->ranks-1] == NOPIECE) && (!is_square_attacked(gs, gs->files/2-1, gs->ranks-1)) &&
+       (!is_square_attacked(gs, gs->files/2, gs->ranks-1)) && (!is_square_attacked(gs, 3, gs->ranks-1))) {
+      return 2;
+    }
+  }
+
   return 0; // neither regular King move nor castling
 }
 
@@ -620,375 +660,420 @@ static void possible_pawn_moves(struct game_state_t * gs,
                                  int onf, int onr,
                                  int *posf, int *posr, int *numpos)
 {
-  if (gs->onMove == WHITE) {\r
-    if (gs->board[onf][onr + 1] == NOPIECE || gs->palace || gs->promoType == 3) {\r
-      add_pos(onf, onr + 1, posf, posr, numpos);\r
-      if ((onr <= gs->pawnDblStep) && (gs->board[onf][onr + 2] == NOPIECE))\r
-       add_pos(onf, onr + 2, posf, posr, numpos);\r
-    }\r
+  if (gs->onMove == WHITE) {
+    if (gs->board[onf][onr + 1] == NOPIECE || gs->palace || gs->promoType == 3) {
+      add_pos(onf, onr + 1, posf, posr, numpos);
+      if ((onr <= gs->pawnDblStep) && (gs->board[onf][onr + 2] == NOPIECE))
+       add_pos(onf, onr + 2, posf, posr, numpos);
+    }
     if (onf > 0) {
-      if (gs->board[onf - 1][onr + 1] != NOPIECE &&\r
+      if (gs->board[onf - 1][onr + 1] != NOPIECE &&
          iscolor(gs->board[onf - 1][onr + 1], BLACK) &&
-          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
+          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi
         add_pos(onf - 1, onr + 1, posf, posr, numpos);
       if(gs->palace && onr >= gs->ranks/2 && (gs->board[onf-1][onr] || iscolor(gs->board[onf-1][onr], BLACK)))
         add_pos(onf - 1, onr, posf, posr, numpos); // XQ promoted pawn
-    }\r
+    }
     if (onf < gs->files-1) {
-      if (gs->board[onf + 1][onr + 1] != NOPIECE &&\r
+      if (gs->board[onf + 1][onr + 1] != NOPIECE &&
          iscolor(gs->board[onf + 1][onr + 1], BLACK) &&
-          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
+          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi
        add_pos(onf + 1, onr + 1, posf, posr, numpos);
       if(gs->palace && onr >= gs->ranks/2 && (gs->board[onf+1][onr] || iscolor(gs->board[onf+1][onr], BLACK)))
         add_pos(onf + 1, onr, posf, posr, numpos); // XQ promoted pawn
-    }\r
-    if (gs->ep_possible[0][onf] == -1)\r
-      add_pos(onf - 1, onr + 1, posf, posr, numpos);\r
-    if (gs->ep_possible[0][onf] == 1)\r
+    }
+    if (gs->ep_possible[0][onf] == -1)
+      add_pos(onf - 1, onr + 1, posf, posr, numpos);
+    if (gs->ep_possible[0][onf] == 1)
       add_pos(onf + 1, onr + 1, posf, posr, numpos);
-  } else {\r
-    if (gs->board[onf][onr - 1] == NOPIECE || gs->palace || gs->promoType == 3) {\r
-      add_pos(onf, onr - 1, posf, posr, numpos);\r
-      if ((onr >= gs->ranks - gs->pawnDblStep - 1) && (gs->board[onf][onr - 2] == NOPIECE))\r
-       add_pos(onf, onr - 2, posf, posr, numpos);\r
-    }\r
+  } else {
+    if (gs->board[onf][onr - 1] == NOPIECE || gs->palace || gs->promoType == 3) {
+      add_pos(onf, onr - 1, posf, posr, numpos);
+      if ((onr >= gs->ranks - gs->pawnDblStep - 1) && (gs->board[onf][onr - 2] == NOPIECE))
+       add_pos(onf, onr - 2, posf, posr, numpos);
+    }
     if (onf > 0) {
-      if (gs->board[onf - 1][onr - 1] != NOPIECE &&\r
-         iscolor(gs->board[onf - 1][onr - 1], WHITE) &&\r
-          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
+      if (gs->board[onf - 1][onr - 1] != NOPIECE &&
+         iscolor(gs->board[onf - 1][onr - 1], WHITE) &&
+          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi
        add_pos(onf - 1, onr - 1, posf, posr, numpos);
       if(gs->palace && onr < gs->ranks/2 && !iscolor(gs->board[onf-1][onr], BLACK))
         add_pos(onf - 1, onr, posf, posr, numpos); // XQ promoted pawn
-    }\r
+    }
     if (onf < gs->files-1) {
-      if (gs->board[onf + 1][onr - 1] != NOPIECE &&\r
-         iscolor(gs->board[onf + 1][onr - 1], WHITE) &&\r
-          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
+      if (gs->board[onf + 1][onr - 1] != NOPIECE &&
+         iscolor(gs->board[onf + 1][onr - 1], WHITE) &&
+          !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi
        add_pos(onf + 1, onr - 1, posf, posr, numpos);
       if(gs->palace && onr < gs->ranks/2 && !iscolor(gs->board[onf+1][onr], BLACK))
         add_pos(onf + 1, onr, posf, posr, numpos); // XQ promoted pawn
-    }\r
-    if (gs->ep_possible[1][onf] == -1)\r
-      add_pos(onf - 1, onr - 1, posf, posr, numpos);\r
-    if (gs->ep_possible[1][onf] == 1)\r
-      add_pos(onf + 1, onr - 1, posf, posr, numpos);\r
-  }\r
+    }
+    if (gs->ep_possible[1][onf] == -1)
+      add_pos(onf - 1, onr - 1, posf, posr, numpos);
+    if (gs->ep_possible[1][onf] == 1)
+      add_pos(onf + 1, onr - 1, posf, posr, numpos);
+  }
+}
+
+static void possible_hoplite_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  if (gs->onMove == WHITE) { // in Spartan Chess there are no white hoplites...
+    if (gs->board[onf][onr + 1] != NOPIECE &&
+         iscolor(gs->board[onf][onr + 1], BLACK)) {
+      add_pos(onf, onr + 1, posf, posr, numpos);
+    }
+    if (onf > 0) {
+      if (gs->board[onf - 1][onr + 1] == NOPIECE) {
+        add_pos(onf - 1, onr + 1, posf, posr, numpos);
+        if (onf > 1 && (onr <= gs->pawnDblStep) /*&& (gs->board[onf-2][onr + 2] == NOPIECE)*/)
+         add_pos(onf - 2, onr + 2, posf, posr, numpos);
+      }
+    }
+    if (onf < gs->files-1) {
+      if (gs->board[onf + 1][onr + 1] == NOPIECE) {
+       add_pos(onf + 1, onr + 1, posf, posr, numpos);
+        if (onf < gs->files-2 && (onr <= gs->pawnDblStep) /*&& (gs->board[onf+2][onr + 2] == NOPIECE)*/)
+         add_pos(onf + 2, onr + 2, posf, posr, numpos);
+      }
+    }
+  } else {
+    if (gs->board[onf][onr - 1] != NOPIECE &&
+         iscolor(gs->board[onf][onr - 1], WHITE)) {
+      add_pos(onf, onr - 1, posf, posr, numpos);
+    }
+    if (onf > 0) {
+      if (gs->board[onf - 1][onr - 1] == NOPIECE) {
+       add_pos(onf - 1, onr - 1, posf, posr, numpos);
+        if (onf > 1 && (onr >= gs->ranks - gs->pawnDblStep - 1) /*&& (gs->board[onf - 2][onr - 2] == NOPIECE)*/)
+         add_pos(onf - 2, onr - 2, posf, posr, numpos);
+      }
+    }
+    if (onf < gs->files-1) {
+      if (gs->board[onf + 1][onr - 1] == NOPIECE) {
+       add_pos(onf + 1, onr - 1, posf, posr, numpos);
+        if (onf < gs->files-2 && (onr >= gs->ranks - gs->pawnDblStep - 1) /*&& (gs->board[onf + 2][onr - 2] == NOPIECE)*/)
+         add_pos(onf + 2, onr - 2, posf, posr, numpos);
+      }
+    }
+  }
 }
 
 static void possible_knight_moves(struct game_state_t * gs,
                                    int onf, int onr,
                                    int *posf, int *posr, int *numpos)
 {
-  static int knightJumps[8][2] = {{-1, 2}, {1, 2}, {2, -1}, {2, 1},\r
-  {-1, -2}, {1, -2}, {-2, 1}, {-2, -1}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 8; j++) {\r
-    f = knightJumps[j][0] + onf;\r
-    r = knightJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      continue;\r
-    if ((gs->board[f][r] == NOPIECE) ||\r
-       (iscolor(gs->board[f][r], CToggle(gs->onMove))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
+  static int knightJumps[8][2] = {{-1, 2}, {1, 2}, {2, -1}, {2, 1},
+  {-1, -2}, {1, -2}, {-2, 1}, {-2, -1}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 8; j++) {
+    f = knightJumps[j][0] + onf;
+    r = knightJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
+      continue;
+    if ((r < 0) || (r >= gs->ranks))
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+       (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
 }
 
 static void possible_horse_moves(struct game_state_t * gs,
                                    int onf, int onr,
                                    int *posf, int *posr, int *numpos)
 {
-  static int knightJumps[8][4] = {{-1, 2, 0, 1}, {1, 2, 0, 1}, {2, -1, 1, 0}, {2, 1, 1, 0},\r
-  {-1, -2, 0, -1}, {1, -2, 0, -1}, {-2, 1, -1, 0}, {-2, -1, -1, 0}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 8; j++) {\r
-    f = knightJumps[j][0] + onf;\r
-    r = knightJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      continue;\r
+  static int knightJumps[8][4] = {{-1, 2, 0, 1}, {1, 2, 0, 1}, {2, -1, 1, 0}, {2, 1, 1, 0},
+  {-1, -2, 0, -1}, {1, -2, 0, -1}, {-2, 1, -1, 0}, {-2, -1, -1, 0}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 8; j++) {
+    f = knightJumps[j][0] + onf;
+    r = knightJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
+      continue;
+    if ((r < 0) || (r >= gs->ranks))
+      continue;
     if ((gs->board[knightJumps[j][2] + onf][knightJumps[j][3] + onr] == NOPIECE) && 
-       ((gs->board[f][r] == NOPIECE) || (iscolor(gs->board[f][r], CToggle(gs->onMove)))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
+       ((gs->board[f][r] == NOPIECE) || (iscolor(gs->board[f][r], CToggle(gs->onMove)))))
+      add_pos(f, r, posf, posr, numpos);
+  }
 }
 
 static void possible_bishop_moves(struct game_state_t * gs,
                                    int onf, int onr,
                                    int *posf, int *posr, int *numpos)
 {
-  int f, r;\r
-\r
-  /* Up Left */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    f--;\r
-    r++;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Up Right */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    f++;\r
-    r++;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Down Left */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    f--;\r
-    r--;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Down Right */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    f++;\r
-    r--;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
+  int f, r;
+
+  /* Up Left */
+  f = onf;
+  r = onr;
+  for (;;) {
+    f--;
+    r++;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Up Right */
+  f = onf;
+  r = onr;
+  for (;;) {
+    f++;
+    r++;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down Left */
+  f = onf;
+  r = onr;
+  for (;;) {
+    f--;
+    r--;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down Right */
+  f = onf;
+  r = onr;
+  for (;;) {
+    f++;
+    r--;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
 }
 
 static void possible_rook_moves(struct game_state_t * gs,
                                  int onf, int onr,
                                  int *posf, int *posr, int *numpos)
 {
-  int f, r;\r
-\r
-  /* Left */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    f--;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Right */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    f++;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Up */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    r++;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Down */\r
-  f = onf;\r
-  r = onr;\r
-  for (;;) {\r
-    r--;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
+  int f, r;
+
+  /* Left */
+  f = onf;
+  r = onr;
+  for (;;) {
+    f--;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Right */
+  f = onf;
+  r = onr;
+  for (;;) {
+    f++;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Up */
+  f = onf;
+  r = onr;
+  for (;;) {
+    r++;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down */
+  f = onf;
+  r = onr;
+  for (;;) {
+    r--;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
 }
 
 static void possible_cannon_moves(struct game_state_t * gs,
                                  int onf, int onr,
                                  int *posf, int *posr, int *numpos)
 {
-  int f, r, i;\r
-\r
-  /* Left */\r
-  f = onf;\r
-  r = onr;\r
-  for (i=0;;) {\r
-    f--;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
+  int f, r, i;
+
+  /* Left */
+  f = onf;
+  r = onr;
+  for (i=0;;) {
+    f--;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
     if ((gs->board[f][r] != NOPIECE) && i++ == 0) continue;
     if(i == 0)
        add_pos(f, r, posf, posr, numpos); // no hop: non-capt
     else if(i == 2 && !iscolor(gs->board[f][r], gs->onMove)) 
-       add_pos(f, r, posf, posr, numpos); // hop: capt\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Right */\r
-  f = onf;\r
-  r = onr;\r
-  for (i=0;;) {\r
-    f++;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
+       add_pos(f, r, posf, posr, numpos); // hop: capt
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Right */
+  f = onf;
+  r = onr;
+  for (i=0;;) {
+    f++;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
     if ((gs->board[f][r] != NOPIECE) && i++ == 0) continue;
     if(i == 0)
        add_pos(f, r, posf, posr, numpos); // no hop: non-capt
     else if(i == 2 && !iscolor(gs->board[f][r], gs->onMove)) 
-       add_pos(f, r, posf, posr, numpos); // hop: capt\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Up */\r
-  f = onf;\r
-  r = onr;\r
-  for (i=0;;) {\r
-    r++;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
+       add_pos(f, r, posf, posr, numpos); // hop: capt
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Up */
+  f = onf;
+  r = onr;
+  for (i=0;;) {
+    r++;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
     if ((gs->board[f][r] != NOPIECE) && i++ == 0) continue;
     if(i == 0)
        add_pos(f, r, posf, posr, numpos); // no hop: non-capt
     else if(i == 2 && !iscolor(gs->board[f][r], gs->onMove)) 
-       add_pos(f, r, posf, posr, numpos); // hop: capt\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Down */\r
-  f = onf;\r
-  r = onr;\r
-  for (i=0;;) {\r
-    r--;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
+       add_pos(f, r, posf, posr, numpos); // hop: capt
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down */
+  f = onf;
+  r = onr;
+  for (i=0;;) {
+    r--;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
     if ((gs->board[f][r] != NOPIECE) && i++ == 0) continue;
     if(i == 0)
        add_pos(f, r, posf, posr, numpos); // no hop: non-capt
     else if(i == 2 && !iscolor(gs->board[f][r], gs->onMove)) 
-       add_pos(f, r, posf, posr, numpos); // hop: capt\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
+       add_pos(f, r, posf, posr, numpos); // hop: capt
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
 }
 
 static void possible_lance_moves(struct game_state_t * gs,
                                  int onf, int onr,
                                  int *posf, int *posr, int *numpos)
 {
-  int f, r;\r
-\r
-  /* Up */\r
-  f = onf;\r
-  r = onr;\r
-  for (;gs->onMove == WHITE;) {\r
-    r++;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-  /* Down */\r
-  f = onf;\r
-  r = onr;\r
-  for (;gs->onMove == BLACK;) {\r
-    r--;\r
-    if ((f < 0) || (f >= gs->files))\r
-      break;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      break;\r
-    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))\r
-      break;\r
-    add_pos(f, r, posf, posr, numpos);\r
-    if (gs->board[f][r] != NOPIECE)\r
-      break;\r
-  }\r
-}
-
-static void possible_cardinal_moves(struct game_state_t * gs,\r
-                                  int onf, int onr,\r
-                                  int *posf, int *posr, int *numpos)\r
-{\r
-  possible_knight_moves(gs, onf, onr, posf, posr, numpos);\r
-  possible_bishop_moves(gs, onf, onr, posf, posr, numpos);\r
-}\r
-\r
-static void possible_marshall_moves(struct game_state_t * gs,\r
-                                  int onf, int onr,\r
-                                  int *posf, int *posr, int *numpos)\r
-{\r
-  possible_rook_moves(gs, onf, onr, posf, posr, numpos);\r
-  possible_knight_moves(gs, onf, onr, posf, posr, numpos);\r
-}\r
-\r
+  int f, r;
+
+  /* Up */
+  f = onf;
+  r = onr;
+  for (;gs->onMove == WHITE;) {
+    r++;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+  /* Down */
+  f = onf;
+  r = onr;
+  for (;gs->onMove == BLACK;) {
+    r--;
+    if ((f < 0) || (f >= gs->files))
+      break;
+    if ((r < 0) || (r >= gs->ranks))
+      break;
+    if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+      break;
+    add_pos(f, r, posf, posr, numpos);
+    if (gs->board[f][r] != NOPIECE)
+      break;
+  }
+}
+
+static void possible_cardinal_moves(struct game_state_t * gs,
+                                  int onf, int onr,
+                                  int *posf, int *posr, int *numpos)
+{
+  possible_knight_moves(gs, onf, onr, posf, posr, numpos);
+  possible_bishop_moves(gs, onf, onr, posf, posr, numpos);
+}
+
+static void possible_marshall_moves(struct game_state_t * gs,
+                                  int onf, int onr,
+                                  int *posf, int *posr, int *numpos)
+{
+  possible_rook_moves(gs, onf, onr, posf, posr, numpos);
+  possible_knight_moves(gs, onf, onr, posf, posr, numpos);
+}
+
 static void possible_queen_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
@@ -997,118 +1082,118 @@ static void possible_queen_moves(struct game_state_t * gs,
   possible_bishop_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_alfil_moves(struct game_state_t * gs,\r
-                                 int onf, int onr,\r
-                                 int *posf, int *posr, int *numpos)\r
-{\r
-  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 4; j++) {\r
-    f = 2*kingJumps[j][0] + onf;\r
-    r = 2*kingJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      continue;\r
-    if ((gs->board[f][r] == NOPIECE) ||\r
-       (iscolor(gs->board[f][r], CToggle(gs->onMove))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
-}\r
-\r
-static void possible_ferz_moves(struct game_state_t * gs,\r
-                                 int onf, int onr,\r
-                                 int *posf, int *posr, int *numpos)\r
-{\r
-  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 4; j++) {\r
-    f = kingJumps[j][0] + onf;\r
-    r = kingJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
+static void possible_alfil_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 4; j++) {
+    f = 2*kingJumps[j][0] + onf;
+    r = 2*kingJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
+      continue;
+    if ((r < 0) || (r >= gs->ranks))
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+       (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
+}
+
+static void possible_ferz_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 4; j++) {
+    f = kingJumps[j][0] + onf;
+    r = kingJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
+      continue;
+    if ((r < 0) || (r >= gs->ranks))
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+       (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
+}
+
+static void possible_mandarin_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 4; j++) {
+    f = kingJumps[j][0] + onf;
+    r = kingJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
       continue;
-    if ((gs->board[f][r] == NOPIECE) ||\r
-       (iscolor(gs->board[f][r], CToggle(gs->onMove))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
-}\r
-\r
-static void possible_mandarin_moves(struct game_state_t * gs,\r
-                                 int onf, int onr,\r
-                                 int *posf, int *posr, int *numpos)\r
-{\r
-  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 4; j++) {\r
-    f = kingJumps[j][0] + onf;\r
-    r = kingJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
+    if ((r < 0) || (r >= gs->ranks))
       continue;
     if(gs->palace && (r >= gs->palace && r < gs->ranks - gs->palace ||
        f < (gs->files - gs->palace)/2 || f >= (gs->files + gs->palace)/2))
-      continue;\r
-    if ((gs->board[f][r] == NOPIECE) ||\r
-       (iscolor(gs->board[f][r], CToggle(gs->onMove))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
-}\r
-\r
-static void possible_wazir_moves(struct game_state_t * gs,\r
-                                 int onf, int onr,\r
-                                 int *posf, int *posr, int *numpos)\r
-{\r
-  static int kingJumps[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 4; j++) {\r
-    f = kingJumps[j][0] + onf;\r
-    r = kingJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      continue;\r
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+       (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
+}
+
+static void possible_wazir_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  static int kingJumps[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 4; j++) {
+    f = kingJumps[j][0] + onf;
+    r = kingJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
+      continue;
+    if ((r < 0) || (r >= gs->ranks))
+      continue;
     if(gs->palace && (r >= gs->palace && r < gs->ranks - gs->palace ||
        f < (gs->files - gs->palace)/2 || f >= (gs->files + gs->palace)/2))
-      continue;\r
-    if ((gs->board[f][r] == NOPIECE) ||\r
-       (iscolor(gs->board[f][r], CToggle(gs->onMove))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
-}\r
-\r
-static void possible_dababba_moves(struct game_state_t * gs,\r
-                                 int onf, int onr,\r
-                                 int *posf, int *posr, int *numpos)\r
-{\r
-  static int kingJumps[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 4; j++) {\r
-    f = 2*kingJumps[j][0] + onf;\r
-    r = 2*kingJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      continue;\r
-    if ((gs->board[f][r] == NOPIECE) ||\r
-       (iscolor(gs->board[f][r], CToggle(gs->onMove))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
-}\r
-\r
-static void possible_man_moves(struct game_state_t * gs,\r
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+       (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
+}
+
+static void possible_dababba_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  static int kingJumps[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 4; j++) {
+    f = 2*kingJumps[j][0] + onf;
+    r = 2*kingJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
+      continue;
+    if ((r < 0) || (r >= gs->ranks))
+      continue;
+    if ((gs->board[f][r] == NOPIECE) ||
+       (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+      add_pos(f, r, posf, posr, numpos);
+  }
+}
+
+static void possible_man_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1116,7 +1201,7 @@ static void possible_man_moves(struct game_state_t * gs,
   possible_ferz_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_dragonking_moves(struct game_state_t * gs,\r
+static void possible_dragonking_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1124,7 +1209,7 @@ static void possible_dragonking_moves(struct game_state_t * gs,
   possible_ferz_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_dragonhorse_moves(struct game_state_t * gs,\r
+static void possible_dragonhorse_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1132,7 +1217,7 @@ static void possible_dragonhorse_moves(struct game_state_t * gs,
   possible_bishop_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_centaur_moves(struct game_state_t * gs,\r
+static void possible_centaur_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1140,7 +1225,7 @@ static void possible_centaur_moves(struct game_state_t * gs,
   possible_knight_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_woody_moves(struct game_state_t * gs,\r
+static void possible_woody_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1148,7 +1233,7 @@ static void possible_woody_moves(struct game_state_t * gs,
   possible_dababba_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_squirrel_moves(struct game_state_t * gs,\r
+static void possible_squirrel_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1157,7 +1242,7 @@ static void possible_squirrel_moves(struct game_state_t * gs,
   possible_knight_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_mastodon_moves(struct game_state_t * gs,\r
+static void possible_mastodon_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1166,7 +1251,7 @@ static void possible_mastodon_moves(struct game_state_t * gs,
   possible_dababba_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_amazon_moves(struct game_state_t * gs,\r
+static void possible_amazon_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1174,7 +1259,7 @@ static void possible_amazon_moves(struct game_state_t * gs,
   possible_knight_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_modernelephant_moves(struct game_state_t * gs,\r
+static void possible_modernelephant_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1182,7 +1267,18 @@ static void possible_modernelephant_moves(struct game_state_t * gs,
   possible_alfil_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_priestess_moves(struct game_state_t * gs,\r
+static void possible_lieutenant_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  possible_modernelephant_moves(gs, onf, onr, posf, posr, numpos);
+      if (onf < gs->files-1 && (gs->board[onf+1][onr] == NOPIECE))
+        add_pos(onf + 1, onr, posf, posr, numpos);
+    if (onf > 0 && (gs->board[onf-1][onr] == NOPIECE))
+        add_pos(onf - 1, onr, posf, posr, numpos);
+}
+
+static void possible_priestess_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1191,7 +1287,7 @@ static void possible_priestess_moves(struct game_state_t * gs,
   possible_knight_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_minister_moves(struct game_state_t * gs,\r
+static void possible_minister_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1200,7 +1296,7 @@ static void possible_minister_moves(struct game_state_t * gs,
   possible_knight_moves(gs, onf, onr, posf, posr, numpos);
 }
 
-static void possible_gold_moves(struct game_state_t * gs,\r
+static void possible_gold_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
@@ -1208,95 +1304,95 @@ static void possible_gold_moves(struct game_state_t * gs,
   if(gs->onMove == WHITE) {
     if(onr < gs->ranks-1)
       if(onf > 0 && !iscolor(gs->board[onf-1][onr+1], WHITE))
-       add_pos(onf-1, onr+1, posf, posr, numpos);\r
+       add_pos(onf-1, onr+1, posf, posr, numpos);
       if(onf < gs->files-1 && !iscolor(gs->board[onf+1][onr+1], WHITE))
-       add_pos(onf+1, onr+1, posf, posr, numpos);\r
+       add_pos(onf+1, onr+1, posf, posr, numpos);
   } else {
     if(onr > 0)
       if(onf > 0 && !iscolor(gs->board[onf-1][onr-1], BLACK))
-       add_pos(onf-1, onr-1, posf, posr, numpos);\r
+       add_pos(onf-1, onr-1, posf, posr, numpos);
       if(onf < gs->files-1 && !iscolor(gs->board[onf+1][onr-1], BLACK))
-       add_pos(onf+1, onr-1, posf, posr, numpos);\r
+       add_pos(onf+1, onr-1, posf, posr, numpos);
   }
 }
 
-static void possible_silver_moves(struct game_state_t * gs,\r
+static void possible_silver_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
 {
   possible_ferz_moves(gs, onf, onr, posf, posr, numpos);
   if(gs->onMove == WHITE) {
     if(onr < gs->ranks-1 && !iscolor(gs->board[onf][onr+1], WHITE))
-      add_pos(onf, onr+1, posf, posr, numpos);\r
+      add_pos(onf, onr+1, posf, posr, numpos);
   } else {
     if(onr > 0 && !iscolor(gs->board[onf][onr-1], BLACK))
-      add_pos(onf, onr-1, posf, posr, numpos);\r
+      add_pos(onf, onr-1, posf, posr, numpos);
   }
 }
 
-static void possible_honorablehorse_moves(struct game_state_t * gs,\r
-                                 int onf, int onr,\r
-                                 int *posf, int *posr, int *numpos)\r
-{\r
-  int f, r = onr + (gs->onMove == WHITE ? 2 : -2);\r
+static void possible_honorablehorse_moves(struct game_state_t * gs,
+                                 int onf, int onr,
+                                 int *posf, int *posr, int *numpos)
+{
+  int f, r = onr + (gs->onMove == WHITE ? 2 : -2);
 
-  if(r < 0 || r >= gs->ranks) return;\r
+  if(r < 0 || r >= gs->ranks) return;
   if(onf > 0) {
-    if ((gs->board[onf-1][r] == NOPIECE) ||\r
-       (iscolor(gs->board[onf-1][r], CToggle(gs->onMove))))\r
-      add_pos(onf - 1, r, posf, posr, numpos);\r
-  }\r
+    if ((gs->board[onf-1][r] == NOPIECE) ||
+       (iscolor(gs->board[onf-1][r], CToggle(gs->onMove))))
+      add_pos(onf - 1, r, posf, posr, numpos);
+  }
   if(onf < gs->files - 1) {
-    if ((gs->board[onf+1][r] == NOPIECE) ||\r
-       (iscolor(gs->board[onf+1][r], CToggle(gs->onMove))))\r
-      add_pos(onf + 1, r, posf, posr, numpos);\r
-  }\r
-}\r
-\r
+    if ((gs->board[onf+1][r] == NOPIECE) ||
+       (iscolor(gs->board[onf+1][r], CToggle(gs->onMove))))
+      add_pos(onf + 1, r, posf, posr, numpos);
+  }
+}
+
 static void possible_king_moves(struct game_state_t * gs,
                                  int onf, int onr,
                                  int *posf, int *posr, int *numpos)
 {
-  if(gs->royalKnight)\r
-    possible_knight_moves(gs, onf, onr, posf, posr, numpos);\r
+  if(gs->royalKnight)
+    possible_knight_moves(gs, onf, onr, posf, posr, numpos);
   else if(gs->palace)
     possible_wazir_moves(gs, onf, onr, posf, posr, numpos);
-  else\r
-    possible_man_moves(gs, onf, onr, posf, posr, numpos);\r
+  else
+    possible_man_moves(gs, onf, onr, posf, posr, numpos);
 }
 
 static void possible_elephant_moves(struct game_state_t * gs,
                                   int onf, int onr,
                                   int *posf, int *posr, int *numpos)
-{\r
-  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};\r
-  int f, r;\r
-  int j;\r
-\r
-  for (j = 0; j < 4; j++) {\r
-    f = 2*kingJumps[j][0] + onf;\r
-    r = 2*kingJumps[j][1] + onr;\r
-    if ((f < 0) || (f >= gs->files))\r
-      continue;\r
-    if ((r < 0) || (r >= gs->ranks))\r
-      continue;\r
-    if ((gs->board[(f+onf)/2][(r+onr)/2] == NOPIECE) && ((gs->board[f][r] == NOPIECE) ||\r
-       (iscolor(gs->board[f][r], CToggle(gs->onMove)))))\r
-      add_pos(f, r, posf, posr, numpos);\r
-  }\r
-}\r
+{
+  static int kingJumps[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};
+  int f, r;
+  int j;
+
+  for (j = 0; j < 4; j++) {
+    f = 2*kingJumps[j][0] + onf;
+    r = 2*kingJumps[j][1] + onr;
+    if ((f < 0) || (f >= gs->files))
+      continue;
+    if ((r < 0) || (r >= gs->ranks))
+      continue;
+    if ((gs->board[(f+onf)/2][(r+onr)/2] == NOPIECE) && ((gs->board[f][r] == NOPIECE) ||
+       (iscolor(gs->board[f][r], CToggle(gs->onMove)))))
+      add_pos(f, r, posf, posr, numpos);
+  }
+}
 
 /* Doesn't check for check */
 int legal_move(struct game_state_t * gs,
               int fFile, int fRank,
               int tFile, int tRank)
 {
-  int move_piece;
+  int move_piece, victim;
   int legal;
 
   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)
@@ -1369,15 +1465,24 @@ int legal_move(struct game_state_t * gs,
     return 0;
   if (!iscolor(gs->board[fFile][fRank], gs->onMove))   /* Wrong color */
     return 0;
-  if ((gs->board[tFile][tRank] != NOPIECE) &&
-      iscolor(gs->board[tFile][tRank], gs->onMove))    /* Can't capture own */
-    return 0;
+  if (((victim = gs->board[tFile][tRank]) != NOPIECE) &&
+      iscolor(gs->board[tFile][tRank], gs->onMove)) {
+    if(piecetype(move_piece) == KING && piecetype(victim) == ROOK) { // [HGM] could be FRC castling
+    }
+    if(gs->drops== 2 && piecetype(move_piece) == ROOK && piecetype(victim) == KING) { // [HGM] could be Seirawan reverse gating
+       return legal_king_move(gs, fFile, fRank, tFile, tRank);
+    }
+    return 0;  /* Can't capture own */
+  }
   if ((fFile == tFile) && (fRank == tRank))    /* Same square */
     return 0;
   switch (move_piece) {
   case PAWN:
     legal = legal_pawn_move(gs, fFile, fRank, tFile, tRank);
     break;
+  case HOPLITE:
+    legal = legal_hoplite_move(gs, fFile, fRank, tFile, tRank);
+    break;
   case KNIGHT:
     legal = legal_knight_move(gs, fFile, fRank, tFile, tRank);
     break;
@@ -1387,18 +1492,21 @@ int legal_move(struct game_state_t * gs,
   case ROOK:
     legal = legal_rook_move(gs, fFile, fRank, tFile, tRank);
     break;
-  case CARDINAL:\r
-  case PRINCESS:\r
-    legal = legal_cardinal_move(gs, fFile, fRank, tFile, tRank);\r
-    break;\r
-  case MARSHALL:\r
-  case EMPRESS:\r
-    legal = legal_marshall_move(gs, fFile, fRank, tFile, tRank);\r
-    break;\r
-  case MAN:\r
-  case MAN2:\r
-    legal = legal_man_move(gs, fFile, fRank, tFile, tRank);\r
-    break;\r
+  case WARLORD:
+  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);
+    break;
+  case MAN:
+  case MAN2:
+    legal = legal_man_move(gs, fFile, fRank, tFile, tRank);
+    break;
   case QUEEN:
     legal = legal_queen_move(gs, fFile, fRank, tFile, tRank);
     break;
@@ -1408,6 +1516,7 @@ int legal_move(struct game_state_t * gs,
   case AMAZON:
     legal = legal_amazon_move(gs, fFile, fRank, tFile, tRank);
     break;
+  case CAPTAIN:
   case WOODY:
     legal = legal_woody_move(gs, fFile, fRank, tFile, tRank);
     break;
@@ -1433,6 +1542,9 @@ int legal_move(struct game_state_t * gs,
   case WAZIR:
     legal = legal_wazir_move(gs, fFile, fRank, tFile, tRank);
     break;
+  case LIEUTENANT:
+    legal = legal_lieutenant_move(gs, fFile, fRank, tFile, tRank);
+    break;
   case ALFIL:
   case ALFIL2:
     legal = legal_alfil_move(gs, fFile, fRank, tFile, tRank);
@@ -1461,6 +1573,7 @@ int legal_move(struct game_state_t * gs,
   case DRAGONHORSE:
     legal = legal_dragonhorse_move(gs, fFile, fRank, tFile, tRank);
     break;
+  case GENERAL:
   case DRAGONKING:
     legal = legal_dragonking_move(gs, fFile, fRank, tFile, tRank);
     break;
@@ -1483,21 +1596,28 @@ int legal_move(struct game_state_t * gs,
  * the move is legal. Returns MOVE_ILLEGAL if move leaves you in check */
 static int move_calculate(struct game_state_t * gs, struct move_t * mt, int promote)
 {
-  struct game_state_t fakeMove;\r
-\r
-  mt->pieceCaptured = gs->board[mt->toFile][mt->toRank];\r
-  mt->enPassant = 0;           /* Don't know yet, let execute move take care\r
-                                  of it */\r
-  if (mt->fromFile == ALG_DROP) {\r
-    mt->piecePromotionTo = NOPIECE;\r
-    sprintf(mt->moveString, "%s/%c%c-%c%d",\r
-           wpstring[mt->fromRank],\r
-               DROP_CHAR, DROP_CHAR,\r
-           mt->toFile + 'a', mt->toRank + 1 - (gs->ranks>9));\r
+  struct game_state_t fakeMove;
+  int gating = 0, stm;
+
+  mt->pieceCaptured = gs->board[mt->toFile][mt->toRank];
+  mt->enPassant = 0;           /* Don't know yet, let execute move take care
+                                  of it */
+  if (mt->fromFile == ALG_DROP) {
+    mt->piecePromotionTo = NOPIECE;
+    sprintf(mt->moveString, "%s/%c%c-%c%d",
+           wpstring[mt->fromRank],
+               DROP_CHAR, DROP_CHAR,
+           mt->toFile + 'a', mt->toRank + 1 - (gs->ranks>9));
   } else if(mt->fromFile == ALG_CASTLE) { 
        // [HGM] castle: generalized castling, fr and tr give from and to file of Rook.
            sprintf(mt->moveString, mt->toRank > mt->toFile ? "o-o-o" : "o-o");
+       if(gs->drops == 2 && promote && gs->holding[gs->onMove == BLACK][abs(promote)-1]) { // promote can be flipped (reverse gating kludge)
+           int c = gs->onMove == WHITE ? 0 : gs->ranks-1;
+           mt->piecePromotionTo = promote; gating = 1;
+           if(promote < 0) sprintf(mt->moveString, "R/%c%d-e%d", mt->fromRank + 'a', c, c); // use RxK notation for Rook-square gatings
+       }
   } else {
+  stm = colorval(gs->board[mt->fromFile][mt->fromRank]);
   if(gs->promoType == 3) { // Shogi-style promotions: not just Pawns, but many pieces can promote
     int piece = gs->board[mt->fromFile][mt->fromRank];
     mt->piecePromotionTo = NOPIECE;
@@ -1528,56 +1648,115 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
           if(mt->toRank == 0 || mt->toRank == gs->files-1) promote = GOLD;
         default: break;
       }
-    if(promote) mt->piecePromotionTo = promote | (colorval(gs->board[mt->fromFile][mt->fromRank]));\r
+    if(promote) mt->piecePromotionTo = promote | (colorval(gs->board[mt->fromFile][mt->fromRank]));
   } else
   if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) && 
-       !gs->palace && // [HGM] XQ: no promotions in xiangqi\r
-      ((mt->toRank == 0) || (mt->toRank == gs->ranks-1))) {
+       !gs->palace && // [HGM] XQ: no promotions in xiangqi
+      ((mt->toRank < gs->promoZone) || (mt->toRank >= gs->ranks - gs->promoZone))) {
+    if(promote == KING) return MOVE_ILLEGAL; // no king in normal chess
+    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=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 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
-    mt->piecePromotionTo = promote |\r
-      (colorval(gs->board[mt->fromFile][mt->fromRank]));\r
-  } else {\r
-    mt->piecePromotionTo = NOPIECE;\r
-  }\r
-  if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&\r
-   ((mt->fromRank - mt->toRank == 2) || (mt->toRank - mt->fromRank == 2))) {\r
-    mt->doublePawn = mt->fromFile;\r
-  } else {\r
-    mt->doublePawn = -1;\r
+    // 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
+    if(promote == KNIGHT && gs->royalKnight) return MOVE_ILLEGAL; // Knight not allowed in Knightmate
+    if(gs->promoType != 2 && promote > QUEEN) { // for promoType != 2 we must check explicitly if the requested pieceis compatible with the variant
+       switch(promote) {
+         case HAWK:
+         case SELEPHANT:
+           if(gs->drops != 2) return MOVE_ILLEGAL; // allowed only in S-Chess
+           break;
+         case MARSHALL:
+         case CARDINAL:
+           if(!gs->capablancaPieces) return MOVE_ILLEGAL; // allowed when flagged so
+           break;
+         case FERZ:
+         case FERZ2:
+           if(!gs->pawnDblStep) return MOVE_ILLEGAL; // allowed in Shatranj and Courier
+           break;
+         case MAN2:
+           if(!gs->royalKnight) return MOVE_ILLEGAL; // allowed only in Knightmate
+           break;
+         default:
+           return MOVE_ILLEGAL;
+       }
+    }
+  } else
+  if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == HOPLITE) && 
+      ((mt->toRank < gs->promoZone) || (mt->toRank >= gs->ranks - gs->promoZone))) {
+    if(!promote || promote == KING) {
+       int f, r, k=0, king = gs->onMove == WHITE ? W_KING : B_KING;
+       for(r=0; r<gs->ranks;r++) for(f=0; f<gs->files; f++) k += (gs->board[f][r] == king);
+       if(k > 1) { // we already have two kings
+         if(promote == KING) return MOVE_ILLEGAL; // three kings not allowed
+         promote = WARLORD;   // use strongest piece as default
+       } else promote = KING; // if no promo-piece given, this could be mate test, so test if promoting to King evades
+    } else
+    if(promote == MASTODON) promote = GENERAL; else
+    if(promote == WOODY)    promote = WARLORD; else
+    if(promote == MARSHALL) promote = CAPTAIN; else
+    if(promote != LIEUTENANT) return MOVE_ILLEGAL;
+    mt->piecePromotionTo = (promote | stm);
+  } 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-1; i >= 0; i--) {
+      if (g->moveList[i].fromFile == mt->fromFile && g->moveList[i].fromRank == mt->fromRank ||
+          g->moveList[i].toFile   == mt->fromFile && g->moveList[i].toRank   == mt->fromRank ||
+         g->moveList[i].fromFile == ALG_CASTLE && (gs->onMove == WHITE ? 0 : gs->ranks-1) == mt->fromRank &&
+                (g->moveList[i].fromRank == mt->fromFile || gs->files>>1 == mt->fromFile )) return MOVE_ILLEGAL;
+    }
+    mt->piecePromotionTo = promote; // gating OK
+    gating = 1; // remember we did it for check test
+  } else {
+    mt->piecePromotionTo = NOPIECE;
+  }
+  if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&
+   ((mt->fromRank - mt->toRank == 2) || (mt->toRank - mt->fromRank == 2))) {
+    mt->doublePawn = mt->fromFile;
+  } else {
+    mt->doublePawn = -1;
   }
 #if 0
-  if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&\r
+  if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
       (mt->fromFile == gs->files/2) && (mt->toFile == 2) &&
-       mt->fromRank == mt->toRank) {\r
-    sprintf(mt->moveString, "o-o-o");\r
-  } else if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&\r
+       mt->fromRank == mt->toRank) {
+    sprintf(mt->moveString, "o-o-o");
+  } else if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
             (mt->fromFile == gs->files/2) && (mt->toFile == gs->files-2) &&
-               mt->fromRank == mt->toRank) {\r
+               mt->fromRank == mt->toRank) {
     sprintf(mt->moveString, "o-o");
   } else {
 #else
   {
-#endif\r
-    sprintf(mt->moveString, "%s/%c%d-%c%d",\r
-           wpstring[piecetype(gs->board[mt->fromFile][mt->fromRank])],\r
-           mt->fromFile + 'a', mt->fromRank + 1 - (gs->ranks>9),\r
-           mt->toFile + 'a', mt->toRank + 1 - (gs->ranks>9));\r
-  }\r
-  }\r
-  /* Replace this with an algabraic de-parser */\r
-\r
-  sprintf(mt->algString, alg_unparse(gs, mt));\r
-  fakeMove = *gs;\r
-  /* Calculates enPassant also */\r
-  execute_move(&fakeMove, mt, 0);\r
-\r
-  /* Does making this move leave ME in check? */\r
-  if (in_check(&fakeMove))\r
-    return MOVE_ILLEGAL;\r
-  /* IanO: bughouse variants: drop cannot be check/checkmate */\r
-\r
-  return MOVE_OK;\r
+#endif
+    sprintf(mt->moveString, "%s/%c%d-%c%d",
+           wpstring[piecetype(gs->board[mt->fromFile][mt->fromRank])],
+           mt->fromFile + 'a', mt->fromRank + 1 - (gs->ranks>9),
+           mt->toFile + 'a', mt->toRank + 1 - (gs->ranks>9));
+  }
+  }
+  /* Replace this with an algabraic de-parser */
+
+  sprintf(mt->algString, alg_unparse(gs, mt));
+  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))
+    return MOVE_ILLEGAL;
+  /* IanO: bughouse variants: drop cannot be check/checkmate */
+
+  return MOVE_OK;
 }
 
 int legal_andcheck_move(struct game_state_t * gs,
@@ -1585,6 +1764,7 @@ int legal_andcheck_move(struct game_state_t * gs,
                        int tFile, int tRank)
 {
   struct move_t mt;
+
   if (!legal_move(gs, fFile, fRank, tFile, tRank))
     return 0;
   mt.color = gs->onMove;
@@ -1593,7 +1773,7 @@ int legal_andcheck_move(struct game_state_t * gs,
   mt.toFile = tFile;
   mt.toRank = tRank;
   /* This should take into account a pawn promoting to another piece */
-  if (move_calculate(gs, &mt, QUEEN) == MOVE_OK)
+  if (move_calculate(gs, &mt, NOPIECE) == MOVE_OK) 
     return 1;
   else
     return 0;
@@ -1603,36 +1783,44 @@ int legal_andcheck_move(struct game_state_t * gs,
  */
 int in_check(struct game_state_t * gs)
 {
-  int f, r;\r
-  int kf = -1, kr = -1;\r
-\r
-  /* Find the king */\r
-  if (gs->onMove == WHITE) {\r
-    for (f = 0; f < gs->files && kf < 0; f++)\r
-      for (r = 0; r < gs->ranks && kf < 0; r++)\r
-       if (gs->board[f][r] == B_KING) {\r
-         kf = f;\r
-         kr = r;\r
-       }\r
-  } else {\r
-    for (f = 0; f < gs->files && kf < 0; f++)\r
-      for (r = 0; r < gs->ranks && kf < 0; r++)\r
-       if (gs->board[f][r] == W_KING) {\r
-         kf = f;\r
-         kr = r;\r
-       }\r
-  }\r
-  if (kf < 0) {\r
-    d_printf( "CHESSD: Error game with no king!\n");\r
-    return 0;\r
-  }\r
-  for (InitPieceLoop(gs->board, &f, &r, gs->onMove);\r
-       NextPieceLoop(gs->board, &f, &r, gs->onMove, gs->files, gs->ranks);) {\r
+  int f, r;
+  int kf = -1, kr = -1;
+
+  /* Find the king */
+  if (gs->onMove == WHITE) {
+    for (f = 0; f < gs->files && kf < 0; f++)
+      for (r = 0; r < gs->ranks && kf < 0; r++)
+       if (gs->board[f][r] == B_KING) {
+         kf = f;
+         kr = r;
+       }
+  } else {
+    for (f = 0; f < gs->files && kf < 0; f++)
+      for (r = 0; r < gs->ranks && kf < 0; r++)
+       if (gs->board[f][r] == W_KING) {
+         kf = f;
+         kr = r;
+       }
+  }
+  if (kf < 0) {
+//    d_printf( "CHESSD: Error game with no king!\n");
+    return -1;
+  }
+  for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+       NextPieceLoop(gs->board, &f, &r, gs->onMove, gs->files, gs->ranks);) {
     if (legal_move(gs, f, r, kf, kr)) {        /* In Check? */
-      return 1;\r
-    }\r
-  }\r
-  return 0;\r
+      if(gs->onMove == WHITE && !strcmp(gs->variant, "spartan")) { // first king is in check, but we might have spare
+//printf("spartan K-capt %c%d%c%d\n",f+'a',r+1,kf+'a',kr+1);
+       gs->board[kf][kr] = B_MAN; // temporarily cure the check on the first King by replacing the latter;
+       r = in_check(gs);
+       gs->board[kf][kr] = B_KING; // and put it back
+//printf("duple = %d\n",r);
+       return r != 0; // if we have no second king (r = -1) or the second is also attacked (r = 1) we are in check.
+      }
+      return 1;
+    }
+  }
+  return 0;
 }
 
 int has_legal_move(struct game_state_t * gs)
@@ -1649,6 +1837,9 @@ int has_legal_move(struct game_state_t * gs)
     case PAWN:
       possible_pawn_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
+    case HOPLITE:
+      possible_hoplite_moves(gs, f, r, possiblef, possibler, &numpossible);
+      break;
     case KNIGHT:
       possible_knight_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
@@ -1658,18 +1849,21 @@ int has_legal_move(struct game_state_t * gs)
     case ROOK:
       possible_rook_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
-    case CARDINAL:\r
-    case PRINCESS:\r
-      possible_cardinal_moves(gs, f, r, possiblef, possibler, &numpossible);\r
-      break;\r
-    case MARSHALL:\r
-    case EMPRESS:\r
-      possible_marshall_moves(gs, f, r, possiblef, possibler, &numpossible);\r
-      break;\r
-    case MAN:\r
-    case MAN2:\r
-      possible_man_moves(gs, f, r, possiblef, possibler, &numpossible);\r
-      break;\r
+    case WARLORD:
+    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);
+      break;
+    case MAN:
+    case MAN2:
+      possible_man_moves(gs, f, r, possiblef, possibler, &numpossible);
+      break;
     case QUEEN:
       possible_queen_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
@@ -1679,6 +1873,7 @@ int has_legal_move(struct game_state_t * gs)
     case AMAZON:
       possible_amazon_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
+    case CAPTAIN:
     case WOODY:
       possible_woody_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
@@ -1711,6 +1906,9 @@ int has_legal_move(struct game_state_t * gs)
     case MODERNELEPHANT:
       possible_modernelephant_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
+    case LIEUTENANT:
+      possible_lieutenant_moves(gs, f, r, possiblef, possibler, &numpossible);
+      break;
     case PRIESTESS:
       possible_priestess_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
@@ -1732,6 +1930,7 @@ int has_legal_move(struct game_state_t * gs)
     case DRAGONHORSE:
       possible_dragonhorse_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
+    case GENERAL:
     case DRAGONKING:
       possible_dragonking_moves(gs, f, r, possiblef, possibler, &numpossible);
       break;
@@ -1753,29 +1952,29 @@ int has_legal_move(struct game_state_t * gs)
       }
   }
 
-  /* IanO:  if we got here, then kf and kr must be set */\r
+  /* IanO:  if we got here, then kf and kr must be set */
   if (gs->gameNum >=0 && game_globals.garray[gs->gameNum].link >= 0
-       || gs->holdings) { // [HGM] zh: also in 2-player games with drops\r
-    /* bughouse: potential drops as check interpositions */\r
-    gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]++;\r
-    for (f=kf-1; f<=kf+1; f++) for (r=kr-1; r<=kr+1; r++) {\r
-      if (f>=0 && f<gs->files && r>=0 && r<gs->ranks && gs->board[f][r] == NOPIECE) {\r
-       /* try a drop next to the king */\r
-       if (legal_andcheck_move(gs, ALG_DROP, QUEEN, f, r)) {\r
+       || gs->holdings) { // [HGM] zh: also in 2-player games with drops
+    /* bughouse: potential drops as check interpositions */
+    gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]++;
+    for (f=kf-1; f<=kf+1; f++) for (r=kr-1; r<=kr+1; r++) {
+      if (f>=0 && f<gs->files && r>=0 && r<gs->ranks && gs->board[f][r] == NOPIECE) {
+       /* try a drop next to the king */
+       if (legal_andcheck_move(gs, ALG_DROP, QUEEN, f, r)) {
          gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--;
          // OK, so we have an interposing drop. But do we have something to drop?
          if(game_globals.garray[gs->gameNum].link < 0) {
                // we have no partner, so we must have something to drop now
                for(i=QUEEN; i>=PAWN; i--)
-                       if (legal_andcheck_move(gs, ALG_DROP, i, f, r)) return 1;\r
+                       if (legal_andcheck_move(gs, ALG_DROP, i, f, r)) return 1;
                return 0;
-         }\r
-         return 1;\r
-       }\r
-      }\r
-    }\r
-    gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--;\r
-  }\r
+         }
+         return 1;
+       }
+      }
+    }
+    gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--;
+  }
 
   return 0;
 }
@@ -1783,82 +1982,87 @@ int has_legal_move(struct game_state_t * gs)
 /* This will end up being a very complicated function */
 int parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt, int promote)
 {
-  int type = is_move(mstr);\r
-  int result;\r
-\r
-  mt->piecePromotionTo = NOPIECE;\r
-  mt->color = gs->onMove;\r
-  switch (type) {\r
-  case MS_NOTMOVE:\r
-    return MOVE_ILLEGAL;\r
-    break;\r
-  case MS_COMP:\r
-    mt->fromFile = mstr[0] - 'a';\r
-    mt->fromRank = mstr[1] - '1' + (gs->ranks>9);\r
-    mt->toFile = mstr[2] - 'a';\r
-    mt->toRank = mstr[3] - '1' + (gs->ranks>9);\r
-    break;\r
-  case MS_COMPDASH:\r
-    mt->fromFile = mstr[0] - 'a';\r
-    mt->fromRank = mstr[1] - '1' + (gs->ranks>9);\r
-    mt->toFile = mstr[3] - 'a';\r
-    mt->toRank = mstr[4] - '1' + (gs->ranks>9);\r
-    break;\r
-  case MS_KCASTLE:\r
+  int type = is_move(mstr);
+  int result, flipflag = 1;
+
+  mt->piecePromotionTo = NOPIECE;
+  mt->color = gs->onMove;
+  switch (type) {
+  case MS_NOTMOVE:
+    return MOVE_ILLEGAL;
+    break;
+  case MS_COMP:
+    mt->fromFile = mstr[0] - 'a';
+    mt->fromRank = mstr[1] - '1' + (gs->ranks>9);
+    mt->toFile = mstr[2] - 'a';
+    mt->toRank = mstr[3] - '1' + (gs->ranks>9);
+    break;
+  case MS_COMPDASH:
+    mt->fromFile = mstr[0] - 'a';
+    mt->fromRank = mstr[1] - '1' + (gs->ranks>9);
+    mt->toFile = mstr[3] - 'a';
+    mt->toRank = mstr[4] - '1' + (gs->ranks>9);
+    break;
+  case MS_KCASTLE:
 #if 0
-    mt->fromFile = gs->files/2;\r
-    mt->toFile = gs->files-2;\r
-    if (gs->onMove == WHITE) {\r
-      mt->fromRank = 0;\r
-      mt->toRank = 0;\r
-    } else {\r
-      mt->fromRank = gs->ranks-1;\r
-      mt->toRank = gs->ranks-1;\r
-    }\r
+    mt->fromFile = gs->files/2;
+    mt->toFile = gs->files-2;
+    if (gs->onMove == WHITE) {
+      mt->fromRank = 0;
+      mt->toRank = 0;
+    } else {
+      mt->fromRank = gs->ranks-1;
+      mt->toRank = gs->ranks-1;
+    }
     break;
 #endif
     // [HGM] castle: for now always assume Fischer-type castling (of which normal castling is a special case).
-    mt->fromFile = ALG_CASTLE;\r
-    mt->toFile = gs->files-2;\r
-    mt->fromRank = gs->onMove == WHITE ? gs->wkrmoved : gs->bkrmoved;\r
-    mt->toRank = mt->toFile-1; // R next to K\r
-    break;    \r
+    mt->fromFile = ALG_CASTLE;
+    mt->toFile = gs->files-2;
+    mt->fromRank = gs->onMove == WHITE ? gs->wkrmoved : gs->bkrmoved;
+    mt->toRank = mt->toFile-1; // R next to K
+    break;    
   case MS_QCASTLE:
-#if 0\r
-    mt->fromFile = gs->files/2;\r
-    mt->toFile = 2;\r
-    if (gs->onMove == WHITE) {\r
-      mt->fromRank = 0;\r
-      mt->toRank = 0;\r
-    } else {\r
-      mt->fromRank = gs->ranks-1;\r
-      mt->toRank = gs->ranks-1;\r
-    }\r
+#if 0
+    mt->fromFile = gs->files/2;
+    mt->toFile = 2;
+    if (gs->onMove == WHITE) {
+      mt->fromRank = 0;
+      mt->toRank = 0;
+    } else {
+      mt->fromRank = gs->ranks-1;
+      mt->toRank = gs->ranks-1;
+    }
     break;
-#endif\r
-    mt->fromFile = ALG_CASTLE;\r
-    mt->toFile = 2;\r
-    mt->fromRank = gs->onMove == WHITE ? gs->wqrmoved : gs->bqrmoved;\r
+#endif
+    mt->fromFile = ALG_CASTLE;
+    mt->toFile = 2;
+    mt->fromRank = gs->onMove == WHITE ? gs->wqrmoved : gs->bqrmoved;
     mt->toRank = mt->toFile+1;
-    break;\r
-  case MS_ALG:\r
-    /* Fills in the mt structure */\r
-    if ((result = alg_parse_move(mstr, gs, mt)) != MOVE_OK)\r
-      return result;\r
-    break;\r
-  default:\r
-    return MOVE_ILLEGAL;\r
-    break;\r
+    break;
+  case MS_ALG:
+    /* Fills in the mt structure */
+    if ((result = alg_parse_move(mstr, gs, mt)) != MOVE_OK)
+      return result;
+    break;
+  default:
+    return MOVE_ILLEGAL;
+    break;
   }
   if((mt->fromRank >= gs->ranks || mt->fromRank < 0 || mt->fromFile >= gs->files) &&
-     mt->fromFile != ALG_DROP && mt->fromFile != ALG_CASTLE\r
-     || mt->toRank < 0 || mt->toRank >= gs->ranks || mt->toFile >= gs->files)\r
+     mt->fromFile != ALG_DROP && mt->fromFile != ALG_CASTLE
+     || mt->toRank < 0 || mt->toRank >= gs->ranks || mt->toFile >= gs->files)
     return MOVE_ILLEGAL; // [HGM] make sure move stays on board
-\r
+
   if (!(result = legal_move(gs, mt->fromFile, mt->fromRank, mt->toFile, mt->toRank)))
-    return MOVE_ILLEGAL;\r
+    return MOVE_ILLEGAL;
 
   if(result == 2) { // [HGM] castle: orthodox castling was given as King move; convert it to new format
+       int ff=mt->fromFile, tf=mt->toFile;
+       if(piecetype(gs->board[tf][mt->toRank]) == KING) { // [HGM] RxK notation
+           mt->fromFile = tf; mt->toFile = ff > tf ? gs->files-2 : 2; // correct to coventional
+           flipflag = -1; // kludge: flip gated piece
+       }
        if(mt->fromFile - mt->toFile > 1) { // Q-side
                mt->fromRank = 0; 
                mt->toRank   = mt->toFile+1;
@@ -1867,14 +2071,17 @@ int parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt, int pro
                mt->toRank   = mt->toFile-1;
        }
        mt->fromFile = ALG_CASTLE;
-    }\r
-\r
+    }
+
   if (mt->piecePromotionTo != NOPIECE) {
-         promote = piecetype(mt->piecePromotionTo);\r
-printf("promotion piece = %d, type = %d",mt->piecePromotionTo, promote);\r
-  }\r
-\r
-  return move_calculate(gs, mt, promote);\r
+         promote = piecetype(mt->piecePromotionTo);
+  } else if (promote != NOPIECE) { // [HGM] promotion on long algebraic move; correct ambiguous types for variant
+    if(gs->promoType == 3 && promote == MASTODON) promote = GOLD;
+    if(gs->drops == 2 && promote == EMPRESS) promote = SELEPHANT;
+    if(gs->drops == 2 && promote == DRAGONHORSE) promote = HAWK;
+  }
+
+  return move_calculate(gs, mt, promote*flipflag);
 }
 
 /* Returns MOVE_OK, MOVE_NOMATERIAL, MOVE_CHECKMATE, or MOVE_STALEMATE */
@@ -1905,20 +2112,35 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
        gs->bkmoved = -gs->bkmoved-2;
     }
     // move Rook & King, in a way that is resistant to ending where they started (for FRC!)
-    rook = gs->board[mt->fromRank][backRank];    // first remember\r
-    king = gs->board[fKing][backRank];\r
-    gs->board[mt->fromRank][backRank] = NOPIECE; // then erase\r    gs->board[fKing][backRank] = NOPIECE;\r    gs->board[mt->toRank][backRank] = rook;      // then put back
+    rook = gs->board[mt->fromRank][backRank];    // first remember
+    king = gs->board[fKing][backRank];
+    gs->board[mt->fromRank][backRank] = NOPIECE; // then erase
+    gs->board[fKing][backRank] = NOPIECE;
+    gs->board[mt->toRank][backRank] = rook;      // then put back
     gs->board[mt->toFile][backRank] = king;
+    if(gs->drops == 2 && mt->piecePromotionTo != NOPIECE) { // [HGM] Seirawan-style gating
+      if(mt->piecePromotionTo > 0)
+       gs->board[fKing][backRank] = mt->piecePromotionTo | gs->onMove; // gate on King square
+      else
+       gs->board[mt->fromRank][backRank] = -mt->piecePromotionTo | gs->onMove; // gate on Rook square
+      gs->holding[gs->onMove==WHITE ? 0 : 1][abs(mt->piecePromotionTo)-1]--; // remove gated piece from holdings
+    }
   } 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)) {
@@ -1940,11 +2162,11 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
     }
     gs->board[mt->toFile][mt->fromRank] = NOPIECE;
   }
-  /* Check en-passant flags for next moves */\r
-  for (i = 0; i < gs->files; i++) {\r
-    gs->ep_possible[0][i] = 0;\r
-    gs->ep_possible[1][i] = 0;\r
-  }\r
+  /* Check en-passant flags for next moves */
+  for (i = 0; i < gs->files; i++) {
+    gs->ep_possible[0][i] = 0;
+    gs->ep_possible[1][i] = 0;
+  }
 /* Added by Sparky 3/16/95
 
    From soso@Viktoria.drp.fmph.uniba.sk Thu Mar 16 13:08:51 1995
@@ -1961,105 +2183,106 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
         if ((mt->toFile+1 < 7 ) ....  should be : (mt->toFile < 7 ) }
 */
 
-  if ((piecetype(movedPiece) == PAWN) &&\r
-   ((mt->fromRank == mt->toRank + 2) || (mt->fromRank + 2 == mt->toRank))) {\r
-    /* Should turn on enpassent flag if possible */\r
-    if (gs->onMove == WHITE) {\r
-      if ((mt->toFile < gs->files-1) && gs->board[mt->toFile + 1][mt->toRank] == B_PAWN) {\r
-       gs->ep_possible[1][mt->toFile + 1] = -1;\r
-      }\r
-      if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][mt->toRank] == B_PAWN) {\r
-       gs->ep_possible[1][mt->toFile - 1] = 1;\r
-      }\r
-    } else {\r
-      if ((mt->toFile < gs->files-1) && gs->board[mt->toFile + 1][mt->toRank] == W_PAWN) {\r
-       gs->ep_possible[0][mt->toFile + 1] = -1;\r
-      }\r
-      if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][mt->toRank] == W_PAWN) {\r
-       gs->ep_possible[0][mt->toFile - 1] = 1;\r
-      }\r
-    }\r
-  }\r
-  if ((piecetype(movedPiece) == ROOK) && (mt->fromRank == 0) && (gs->onMove == WHITE)) {\r
-    if (mt->fromFile == gs->wqrmoved) // [HGM] castle: flip w.r.t. -1 to remember original\r
-      gs->wqrmoved = -gs->wqrmoved-2;\r
-    if (mt->fromFile == gs->wkrmoved)\r
-      gs->wkrmoved = -gs->wkrmoved-2;\r
-  }\r
-  if ((piecetype(movedPiece) == ROOK) && (mt->fromRank == gs->ranks-1) && (gs->onMove == BLACK)) {\r
-    if (mt->fromFile == gs->bqrmoved)\r
-      gs->bqrmoved = -gs->bqrmoved-2;\r
-    if (mt->fromFile == gs->bkrmoved)\r
-      gs->bkrmoved = -gs->bkrmoved-2;\r
-  }\r
-  if (piecetype(movedPiece) == KING) {\r
-    if ((gs->onMove == WHITE) && (mt->fromFile == gs->wkmoved))\r
-      gs->wkmoved = -gs->wkmoved-2;\r
-    if ((gs->onMove == BLACK) && (mt->fromFile == gs->bkmoved))\r
-      gs->bkmoved = -gs->bkmoved-2;\r
-  }
-#if 0\r
-  if ((piecetype(movedPiece) == KING) &&\r
+  if ((piecetype(movedPiece) == PAWN) &&
+   ((mt->fromRank == mt->toRank + 2) || (mt->fromRank + 2 == mt->toRank))) {
+    /* Should turn on enpassent flag if possible */
+    if (gs->onMove == WHITE) {
+      if ((mt->toFile < gs->files-1) && gs->board[mt->toFile + 1][mt->toRank] == B_PAWN) {
+       gs->ep_possible[1][mt->toFile + 1] = -1;
+      }
+      if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][mt->toRank] == B_PAWN) {
+       gs->ep_possible[1][mt->toFile - 1] = 1;
+      }
+    } else {
+      if ((mt->toFile < gs->files-1) && gs->board[mt->toFile + 1][mt->toRank] == W_PAWN) {
+       gs->ep_possible[0][mt->toFile + 1] = -1;
+      }
+      if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][mt->toRank] == W_PAWN) {
+       gs->ep_possible[0][mt->toFile - 1] = 1;
+      }
+    }
+  }
+  if ((piecetype(movedPiece) == ROOK) && (mt->fromRank == 0) && (gs->onMove == WHITE)) {
+    if (mt->fromFile == gs->wqrmoved) // [HGM] castle: flip w.r.t. -1 to remember original
+      gs->wqrmoved = -gs->wqrmoved-2;
+    if (mt->fromFile == gs->wkrmoved)
+      gs->wkrmoved = -gs->wkrmoved-2;
+  }
+  if ((piecetype(movedPiece) == ROOK) && (mt->fromRank == gs->ranks-1) && (gs->onMove == BLACK)) {
+    if (mt->fromFile == gs->bqrmoved)
+      gs->bqrmoved = -gs->bqrmoved-2;
+    if (mt->fromFile == gs->bkrmoved)
+      gs->bkrmoved = -gs->bkrmoved-2;
+  }
+  if (piecetype(movedPiece) == KING) {
+    if ((gs->onMove == WHITE) && (mt->fromFile == gs->wkmoved))
+      gs->wkmoved = -gs->wkmoved-2;
+    if ((gs->onMove == BLACK) && (mt->fromFile == gs->bkmoved))
+      gs->bkmoved = -gs->bkmoved-2;
+  }
+#if 0
+  if ((piecetype(movedPiece) == KING) &&
       ((mt->fromFile == gs->files/2) && (mt->toFile == gs->files-2)) &&
-       mt->fromRank == mt->toRank) {   /* Check for KS castling */\r
-    gs->board[gs->files-3][mt->toRank] = gs->board[gs->files-1][mt->toRank];\r
-    gs->board[gs->files-1][mt->toRank] = NOPIECE;\r
-  }\r
-  if ((piecetype(movedPiece) == KING) &&\r
+       mt->fromRank == mt->toRank) {   /* Check for KS castling */
+    gs->board[gs->files-3][mt->toRank] = gs->board[gs->files-1][mt->toRank];
+    gs->board[gs->files-1][mt->toRank] = NOPIECE;
+  }
+  if ((piecetype(movedPiece) == KING) &&
       ((mt->fromFile == gs->files/2) && (mt->toFile == 2)) &&
-       mt->fromRank == mt->toRank) {   /* Check for QS castling */\r
-    gs->board[3][mt->toRank] = gs->board[0][mt->toRank];\r
-    gs->board[0][mt->toRank] = NOPIECE;\r
-  }
-#endif\r
-  }\r
-  if (gs->onMove == BLACK)\r
-    gs->moveNum++;\r
-\r
-  if (check_game_status) {\r
-    /* Does this move result in check? */\r
-    if (in_check(gs)) {\r
-      /* Check for checkmate */\r
-      gs->onMove = CToggle(gs->onMove);\r
-      if (!has_legal_move(gs))\r
-       return MOVE_CHECKMATE;\r
-    } else {\r
-      /* Check for stalemate */\r
-      gs->onMove = CToggle(gs->onMove);\r
-      if (!has_legal_move(gs))\r
-       return gs->stalemate ? MOVE_STALEMATE : MOVE_CHECKMATE; // [HGM] in XQ and shatranj stalemate loses\r
-    }\r
-/* loon: check for insufficient mating material, first try */\r
-      foobar = wCnt = bCnt = 0;\r
-      for (i=0; i<gs->files; i++) {\r
+       mt->fromRank == mt->toRank) {   /* Check for QS castling */
+    gs->board[3][mt->toRank] = gs->board[0][mt->toRank];
+    gs->board[0][mt->toRank] = NOPIECE;
+  }
+#endif
+  }
+  if (gs->onMove == BLACK)
+    gs->moveNum++;
+
+  if (check_game_status) {
+    /* Does this move result in check? */
+    if (in_check(gs)) {
+      /* Check for checkmate */
+      gs->onMove = CToggle(gs->onMove);
+      if (!has_legal_move(gs))
+       return MOVE_CHECKMATE;
+    } else {
+      /* Check for stalemate */
+      gs->onMove = CToggle(gs->onMove);
+      if (!has_legal_move(gs))
+       return gs->stalemate ? MOVE_STALEMATE : MOVE_CHECKMATE; // [HGM] in XQ and shatranj stalemate loses
+    }
+/* loon: check for insufficient mating material, first try */
+      foobar = wCnt = bCnt = 0;
+      for (i=0; i<gs->files; i++) {
         for (j=0; j<gs->ranks; j++) {
-         int p = gs->board[i][j];\r
-          switch(piecetype(p)) {\r
-            case KNIGHT:\r
-            case BISHOP:\r
-              foobar++;\r
-              break;\r
-            case KING:\r
-           case NOPIECE:\r
-             break;\r
-            default:\r
-              foobar = 2;\r
-              break;\r
+         int p = gs->board[i][j];
+          switch(piecetype(p)) {
+            case KNIGHT:
+            case BISHOP:
+              foobar++;
+              break;
+            case KING:
+           case NOPIECE:
+             break;
+            default:
+              foobar = 2;
+              break;
           }
          if(p != NOPIECE && iscolor(p, WHITE)) wCnt++;
-         if(iscolor(p, BLACK)) bCnt++;\r
-        }\r
+         if(iscolor(p, BLACK)) bCnt++;
+        }
       }
       if(gs->bareKingLoses) { // [HGM] with bare-King-loses rule only KK is insuff. material
        if(gs->onMove == BLACK && wCnt == 1 && bCnt > 1) return MOVE_BARE;
        if(gs->onMove == WHITE && bCnt == 1 && wCnt > 1) return MOVE_BARE;
        if(bCnt == 1 && wCnt == 1) return MOVE_NOMATERIAL;
-      } else if (foobar < 2)\r
-        return MOVE_NOMATERIAL;\r
-  } else {\r
-    gs->onMove = CToggle(gs->onMove);\r
-  }\r
-  return MOVE_OK;\r
+      } else if (foobar < 2)
+        return MOVE_NOMATERIAL;
+  } else {
+    gs->onMove = CToggle(gs->onMove);
+  }
+
+  return MOVE_OK;
 }
 
 int backup_move(int g, int mode)
@@ -2099,13 +2322,32 @@ int backup_move(int g, int mode)
     // remove first, as one might come back to a square the other left
     gs->board[m->toFile  ][rank] = NOPIECE; // King toSqr
     gs->board[m->toRank  ][rank] = NOPIECE; // Rook toSqr
+    if(gs->board[m->fromRank][rank] != NOPIECE)
+      gs->holding[gs->onMove==WHITE ? 1 : 0][piecetype(gs->board[m->fromRank][rank])-1]++; // put back in holdings (onMove not flipped yet!)
+    if(gs->board[kingFromFile][rank] != NOPIECE)
+      gs->holding[gs->onMove==WHITE ? 1 : 0][piecetype(gs->board[kingFromFile][rank])-1]++; // put back in holdings (onMove not flipped yet!)
     gs->board[m->fromRank][rank] = ROOK | m->color; // Rook fromSqr
     gs->board[kingFromFile][rank] = KING | m->color; // King fromSquare
     goto cleanupMove;
   }
+  if(gs->board[m->fromFile][m->fromRank] != NOPIECE) { // [HGM] from-square occupied; move 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!)
+  }
   gs->board[m->fromFile][m->fromRank] = gs->board[m->toFile][m->toRank];
   if (m->piecePromotionTo != NOPIECE) {
-    gs->board[m->fromFile][m->fromRank] = PAWN |
+    int piece;
+    switch(piecetype(m->piecePromotionTo)) { // Spartan pieces came from Hoplite, Shogi is problematic
+      case KING:
+      case CAPTAIN:
+      case LIEUTENANT:
+      case WARLORD:
+      case GENERAL: piece = HOPLITE; break;
+      case DRAGONHORSE: piece = BISHOP; break;
+      case DRAGONKING:  piece = ROOK;   break;
+      case GOLD: // TODO: figure out what original was
+      default: piece = PAWN;
+    }
+    gs->board[m->fromFile][m->fromRank] = piece |
       colorval(gs->board[m->fromFile][m->fromRank]);
   }
   /******************
@@ -2124,36 +2366,36 @@ int backup_move(int g, int mode)
        if (i == game_globals.garray[g].numHalfMoves - 1)
          gs->wqrmoved = m->fromFile;
       }
-      if ((m->fromFile == -gs->wkrmoved-2) && (m->fromRank == 0)) {\r
-       for (i = 2; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {\r
-         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];\r
-         if ((m1->fromFile == -gs->wkrmoved-2) && (m1->fromRank == 0))\r
-           break;\r
-       }\r
-       if (i == game_globals.garray[g].numHalfMoves - 1)\r
-         gs->wkrmoved = m->fromFile;\r
-      }\r
-    } else {\r
-      if ((m->fromFile == -gs->bqrmoved-2) && (m->fromRank == gs->ranks-1)) {\r
-       for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {\r
-         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];\r
-         if ((m1->fromFile == -gs->bkrmoved-2) && (m1->fromRank == gs->ranks-1))\r
-           break;\r
-       }\r
-       if (i == game_globals.garray[g].numHalfMoves - 1)\r
-         gs->bqrmoved = m->fromFile;\r
-      }\r
-      if ((m->fromFile == -gs->bkrmoved-2) && (m->fromRank == gs->ranks-1)) {\r
-       for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {\r
-         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];\r
-         if ((m1->fromFile == -gs->wkrmoved-2) && (m1->fromRank == gs->ranks-1))\r
-           break;\r
-       }\r
-       if (i == game_globals.garray[g].numHalfMoves - 1)\r
-         gs->bkrmoved = m->fromFile;\r
-      }\r
-    }\r
-  }\r
+      if ((m->fromFile == -gs->wkrmoved-2) && (m->fromRank == 0)) {
+       for (i = 2; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+         if ((m1->fromFile == -gs->wkrmoved-2) && (m1->fromRank == 0))
+           break;
+       }
+       if (i == game_globals.garray[g].numHalfMoves - 1)
+         gs->wkrmoved = m->fromFile;
+      }
+    } else {
+      if ((m->fromFile == -gs->bqrmoved-2) && (m->fromRank == gs->ranks-1)) {
+       for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+         if ((m1->fromFile == -gs->bkrmoved-2) && (m1->fromRank == gs->ranks-1))
+           break;
+       }
+       if (i == game_globals.garray[g].numHalfMoves - 1)
+         gs->bqrmoved = m->fromFile;
+      }
+      if ((m->fromFile == -gs->bkrmoved-2) && (m->fromRank == gs->ranks-1)) {
+       for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+         if ((m1->fromFile == -gs->wkrmoved-2) && (m1->fromRank == gs->ranks-1))
+           break;
+       }
+       if (i == game_globals.garray[g].numHalfMoves - 1)
+         gs->bkrmoved = m->fromFile;
+      }
+    }
+  }
   if (piecetype(gs->board[m->fromFile][m->fromRank]) == KING) {
     gs->board[m->toFile][m->toRank] = m->pieceCaptured;
 #if 0
@@ -2201,29 +2443,29 @@ int backup_move(int g, int mode)
        we should scan moveList.
     *******************/
 
-    if (m->color == WHITE) {\r
-\r
-      if ((m->fromFile == -gs->wkmoved-2) && (m->fromRank == 0)) {\r
-       for (i = 2; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {\r
-         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];\r
-         if ((m1->fromFile == gs->wkmoved-2) && (m1->fromRank == 0))\r
-           break;\r
-       }\r
-       if (i == game_globals.garray[g].numHalfMoves - 1)\r
-         gs->wkmoved = m->fromFile;\r
-      }\r
-    } else {\r
-      if ((m->fromFile == -gs->bkmoved-2) && (m->fromRank == gs->ranks-1)) {\r
-       for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {\r
-         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];\r
-         if ((m1->fromFile == -gs->bkmoved-2) && (m1->fromRank == gs->ranks-1))\r
-           break;\r
-       }\r
-       if (i == game_globals.garray[g].numHalfMoves - 1)\r
-         gs->bkmoved = m->fromFile;\r
-      }\r
-    }\r
-  }\r
+    if (m->color == WHITE) {
+
+      if ((m->fromFile == -gs->wkmoved-2) && (m->fromRank == 0)) {
+       for (i = 2; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+         if ((m1->fromFile == gs->wkmoved-2) && (m1->fromRank == 0))
+           break;
+       }
+       if (i == game_globals.garray[g].numHalfMoves - 1)
+         gs->wkmoved = m->fromFile;
+      }
+    } else {
+      if ((m->fromFile == -gs->bkmoved-2) && (m->fromRank == gs->ranks-1)) {
+       for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+         m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+         if ((m1->fromFile == -gs->bkmoved-2) && (m1->fromRank == gs->ranks-1))
+           break;
+       }
+       if (i == game_globals.garray[g].numHalfMoves - 1)
+         gs->bkmoved = m->fromFile;
+      }
+    }
+  }
   if (m->enPassant) {          /* Do enPassant */
     gs->board[m->toFile][m->fromRank] = PAWN |
       (colorval(gs->board[m->fromFile][m->fromRank]) == WHITE ? BLACK : WHITE);
@@ -2302,28 +2544,28 @@ cleanupMove:
      array.  (patch from Soso, added by Sparky 3/17/95)
   ********/
 
-  if (game_globals.garray[g].numHalfMoves > 0) {\r
-    m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[game_globals.garray[g].numHalfMoves - 1] : \r
-                            &game_globals.garray[g].examMoveList[game_globals.garray[g].numHalfMoves - 1];\r
-    if (piecetype(gs->board[m1->toFile][m1->toRank]) == PAWN) {\r
-      if ((m1->toRank - m1->fromRank) == 2) {\r
-       if ((m1->toFile < gs->files-1) && gs->board[m1->toFile + 1][m1->toRank] == B_PAWN) {\r
-         gs->ep_possible[1][m1->toFile + 1] = -1;\r
-       }\r
-       if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][m1->toRank] == B_PAWN) {\r
-         gs->ep_possible[1][m1->toFile - 1] = 1;\r
-       }\r
-      }\r
-      if ((m1->toRank - m1->fromRank) == -2) {\r
-       if ((m1->toFile < gs->files-1) && gs->board[m1->toFile + 1][m1->toRank] == W_PAWN) {\r
-         gs->ep_possible[0][m1->toFile + 1] = -1;\r
-       }\r
-       if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][m1->toRank] == W_PAWN) {\r
-         gs->ep_possible[0][m1->toFile - 1] = 1;\r
-       }\r
-      }\r
-    }\r
-  }\r
+  if (game_globals.garray[g].numHalfMoves > 0) {
+    m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[game_globals.garray[g].numHalfMoves - 1] : 
+                            &game_globals.garray[g].examMoveList[game_globals.garray[g].numHalfMoves - 1];
+    if (piecetype(gs->board[m1->toFile][m1->toRank]) == PAWN) {
+      if ((m1->toRank - m1->fromRank) == 2) {
+       if ((m1->toFile < gs->files-1) && gs->board[m1->toFile + 1][m1->toRank] == B_PAWN) {
+         gs->ep_possible[1][m1->toFile + 1] = -1;
+       }
+       if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][m1->toRank] == B_PAWN) {
+         gs->ep_possible[1][m1->toFile - 1] = 1;
+       }
+      }
+      if ((m1->toRank - m1->fromRank) == -2) {
+       if ((m1->toFile < gs->files-1) && gs->board[m1->toFile + 1][m1->toRank] == W_PAWN) {
+         gs->ep_possible[0][m1->toFile + 1] = -1;
+       }
+       if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][m1->toRank] == W_PAWN) {
+         gs->ep_possible[0][m1->toFile - 1] = 1;
+       }
+      }
+    }
+  }
   /************** and here's the end **************/
   return MOVE_OK;
 }