Implement Spartan Chess
[capablanca.git] / lasker-2.2.3 / src / algcheck.c
index aa7d5af..219b5de 100644 (file)
@@ -247,12 +247,15 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
                return;
        }
 
-       if (piecetype(gs->board[mt->fromFile][mt->fromRank]) != PAWN) {
+      if(gs->drops != 2 || (gs->onMove == WHITE ? 0 : gs->ranks-1) != mt->fromRank) { // [HGM] always accept if backrank mover in Seirawan
+       if (piecetype(gs->board[mt->fromFile][mt->fromRank]) != PAWN &&
+           piecetype(gs->board[mt->fromFile][mt->fromRank]) != HOPLITE) {
                return;
        }
        if (mt->toRank < gs->ranks - gs->promoZone && mt->toRank >= gs->promoZone) {
                return;
        }
+      }
 
        switch (tolower(s[1])) {
        case 'f':
@@ -262,6 +265,7 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
                piece = QUEEN;
                break;
        case 'c':
+               if(piecetype(gs->board[mt->fromFile][mt->fromRank]) == HOPLITE) piece = CAPTAIN; else
                if(!gs->capablancaPieces) return; // [HGM] should make variant-dependent piece mask
                piece = MARSHALL;
                break;
@@ -285,14 +289,24 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
                break;
        // Superchess promotons: filtered out later by promoType
        case 'g':
+               if(piecetype(gs->board[mt->fromFile][mt->fromRank]) == HOPLITE) piece = GENERAL; else
                piece = MASTODON;
                break;
        case 'o':
                piece = SQUIRREL;
                break;
        case 'w':
+               if(piecetype(gs->board[mt->fromFile][mt->fromRank]) == HOPLITE) piece = WARLORD; else
                piece = WOODY;
                break;
+       case 'k':
+               if(piecetype(gs->board[mt->fromFile][mt->fromRank]) != HOPLITE) return;
+               piece = KING;
+               break;
+       case 'l':
+               if(piecetype(gs->board[mt->fromFile][mt->fromRank]) != HOPLITE) return;
+               piece = LIEUTENANT;
+               break;
        case 'v':
                piece = CENTAUR;
                break;
@@ -338,6 +352,7 @@ int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
   switch(piece) {
     case ELEPHANT:
       if(strstr(gs->variant, "super"))   piece = EMPRESS; else
+      if(strstr(gs->variant, "seirawan"))piece = SELEPHANT; else
       if(strstr(gs->variant, "great"))   piece = MODERNELEPHANT; else
       if(strstr(gs->variant, "courier")) piece = ALFIL2;
       break;
@@ -368,8 +383,9 @@ int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
       if(strstr(gs->variant, "great")) piece = MINISTER;
       break;
     case HORSE:
+      if(strstr(gs->variant, "shogi")) piece = DRAGONHORSE; else
+      if(strstr(gs->variant, "seirawan")) piece = HAWK; else
       if(strstr(gs->variant, "great")) piece = PRIESTESS;
-      if(strstr(gs->variant, "shogi")) piece = DRAGONHORSE;
       break;
     case GOLD:
       if(strstr(gs->variant, "great")) piece = MASTODON;
@@ -525,12 +541,18 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     piece = piecetype(gs->board[mt->fromFile][mt->fromRank]);
   }
 
-  if ((mt->fromFile == ALG_CASTLE) && (mt->toFile > mt->toRank)) { // [HGM] castle: K ends right of R
-    strcpy(mStr, "O-O");
-    goto check;
-  }
-  if ((mt->fromFile == ALG_CASTLE) && (mt->toFile < mt->toRank)) { // [HGM] castle: K ends left of R
-    strcpy(mStr, "O-O-O");
+  if (mt->fromFile == ALG_CASTLE) {
+    int r = gs->onMove == WHITE ? 1 : gs->ranks;
+    if(mt->toFile > mt->toRank) { // [HGM] castle: K ends right of R
+      strcpy(mStr, "O-O");
+    }
+    if (mt->toFile < mt->toRank) { // [HGM] castle: K ends left of R
+      strcpy(mStr, "O-O-O");
+    }
+    if(gs->drops == 2) {
+       if(mt->piecePromotionTo < 0) snprintf(mStr, 20, "%c%de%d", mt->fromRank + 'a', r, r);
+       goto suffix; // [HGM] in Seirawan castling can have gating suffix
+    }
     goto check;
   }
   strcpy(mStr, "");
@@ -558,6 +580,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
   case CARDINAL:
     strcpy(mStr, "A");
     break;
+  case CAPTAIN:
   case CANNON:
   case MARSHALL:
     strcpy(mStr, "C");
@@ -571,6 +594,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     break;
   case EMPRESS:
   case ELEPHANT:
+  case SELEPHANT:
     strcpy(mStr, "E");
     break;
   case ALFIL:
@@ -579,6 +603,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
   case FERZ2:
     strcpy(mStr, "F");
     break;
+  case WARLORD:
   case WOODY:
   case WAZIR:
     strcpy(mStr, "W");
@@ -590,6 +615,9 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     strcpy(mStr, "V");
     break;
   case HORSE:
+  case DRAGONHORSE:
+  case HAWK:
+  case HOPLITE:
     strcpy(mStr, "H");
     break;
   case HONORABLEHORSE:
@@ -598,9 +626,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
   case DRAGONKING:
     strcpy(mStr, "D");
     break;
-  case DRAGONHORSE:
-    strcpy(mStr, "H");
-    break;
+  case LIEUTENANT:
   case LANCE:
     strcpy(mStr, "L");
     break;
@@ -609,6 +635,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     strcpy(mStr, "S");
     break;
   case MASTODON:
+  case GENERAL:
   case GOLD:
     strcpy(mStr, "G");
     break;
@@ -686,10 +713,13 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
   }
   sprintf(tmp, "%c%d", mt->toFile + 'a', mt->toRank + 1 - (gs->ranks > 9));
   strcat(mStr, tmp);
-
-  if ((piece == PAWN || gs->promoType == 3) && (mt->piecePromotionTo != NOPIECE)) {
+suffix:
+  if ((piece == PAWN || piece == HOPLITE || gs->promoType == 3 || gs->drops == 2) && (mt->piecePromotionTo != NOPIECE)) {
     strcat(mStr, "=");         /* = before promoting piece */
-    switch (piecetype(mt->piecePromotionTo)) {
+    switch (piecetype(abs(mt->piecePromotionTo))) {
+    case KING:
+      strcat(mStr, "K");
+      break;
     case KNIGHT:
       strcat(mStr, "N");
       break;
@@ -703,6 +733,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
       strcat(mStr, "A");
       break;
     case MARSHALL:
+    case CAPTAIN:
       strcat(mStr, "C");
       break;
     case MAN:
@@ -714,6 +745,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     case FERZ2:
       strcat(mStr, "F");
       break;
+    case WARLORD:
     case WOODY:
       strcat(mStr, "W");
       break;
@@ -731,8 +763,7 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
       strcat(mStr, "O");
       break;
     case MASTODON:
-      strcat(mStr, "G");
-      break;
+    case GENERAL:
     case GOLD: // [HGM] Shogi promotions: avoid use of '+'
       strcat(mStr, "G");
       break;
@@ -743,6 +774,9 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     case DRAGONKING:
       strcat(mStr, "D");
       break;
+    case LIEUTENANT:
+      strcat(mStr, "L");
+      break;
     default:
       break;
     }