Implement Grand Chess
[capablanca.git] / lasker-2.2.3 / src / algcheck.c
old mode 100755 (executable)
new mode 100644 (file)
index d043445..3efc4ce
@@ -152,6 +152,8 @@ static int get_move_info(const char *str, int *piece, int *ff, int *fr, int *tf,
          lpiece = KNIGHT;
        else if (c == 'p')
          lpiece = PAWN;
+       else if (c == 'd')
+         lpiece = DRAGONKING;
        else
          goto nomatch;
        break;
@@ -197,6 +199,7 @@ static int get_move_info(const char *str, int *piece, int *ff, int *fr, int *tf,
     matchVal = i;
 nomatch:;
   }
+
   if (matchVal != -1)
     return MS_ALG;
   else
@@ -219,11 +222,35 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
        if (s == NULL) {
                return;
        }
-       
+       if(gs->promoType == 3) { // handle Shogi promotions
+               piece = gs->board[mt->fromFile][mt->fromRank];
+               if(colorval(piece) == WHITE && mt->fromRank < gs->ranks - gs->ranks/3
+                                           && mt->toRank   < gs->ranks - gs->ranks/3 ) return;
+               if(colorval(piece) == BLACK && mt->fromRank >= gs->ranks/3
+                                           && mt->toRank   >= gs->ranks/3 ) return;
+                switch(piecetype(piece)) {
+                   case PAWN:
+                   case LANCE:
+                   case HONORABLEHORSE:
+                   case SILVER:
+                       if(s[1] != '+' && s[1] != '^' && s[1] != 'G' && s[1] != 'g') return;
+                       piece = GOLD; break;
+                   case BISHOP:
+                       if(s[1] != '+' && s[1] != '^' && s[1] != 'H' && s[1] != 'h') return;
+                       piece = DRAGONHORSE; break;
+                   case ROOK:
+                       if(s[1] != '+' && s[1] != '^' && s[1] != 'D' && s[1] != 'd') return;
+                       piece = DRAGONKING; break;
+                   default: return; // others do not promote, so ignore
+               }
+               mt->piecePromotionTo = piece | colorval(gs->board[mt->fromFile][mt->fromRank]);
+               return;
+       }
+
        if (piecetype(gs->board[mt->fromFile][mt->fromRank]) != PAWN) {
                return;
        }
-       if (mt->toRank != gs->ranks-1 && mt->toRank != 0) {
+       if (mt->toRank < gs->ranks - gs->promoZone && mt->toRank >= gs->promoZone) {
                return;
        }
 
@@ -278,9 +305,9 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
        default:
                return;
        }
-
        i = colorval(gs->board[mt->fromFile][mt->fromRank]) == WHITE ? 0 : 1;
-       if(piece >= WOODY && (gs->promoType != 2 || gs->holding[i][piece-1] == 0)) return;
+       if(gs->promoType == 2 && gs->holding[i][piece-1] == 0) return; // only if piece was captured
+       if(piece >= WOODY && (gs->promoType != 2 || gs->promoZone == 3)) return; // reserved for Superchess
 
        mt->piecePromotionTo = piece | colorval(gs->board[mt->fromFile][mt->fromRank]);
 }
@@ -295,7 +322,6 @@ int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
     d_printf( "CHESSD: Shouldn't try to algebraicly parse non-algabraic move string.\n");
     return MOVE_ILLEGAL;
   }
-  \r
   // [HGM] check if move does not stray off board\r
   if(gs->ranks < 10) { \r
     if(tr == 0 || fr == 0) return MOVE_ILLEGAL; // used nonexistent 0-rank\r
@@ -339,6 +365,7 @@ int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
       break;
     case HORSE:
       if(strstr(gs->variant, "great")) piece = PRIESTESS;
+      if(strstr(gs->variant, "shogi")) piece = DRAGONHORSE;
       break;
     case GOLD:
       if(strstr(gs->variant, "great")) piece = MASTODON;
@@ -403,7 +430,6 @@ int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
                    // note that the interpretation Bxc4 is matched last, and has set piece to BISHOP
                    continue;
            }
-
            if (legal_andcheck_move(gs, f, r, tf, tr)) {
                    if ((piecetype(gs->board[f][r]) == PAWN) && (f != tolower(mstr[0]) - 'a')) {
                            continue;
@@ -566,10 +592,10 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     strcpy(mStr, "N");
     break;
   case DRAGONKING:
-    strcpy(mStr, "J");
+    strcpy(mStr, "D");
     break;
   case DRAGONHORSE:
-    strcpy(mStr, "I");
+    strcpy(mStr, "H");
     break;
   case LANCE:
     strcpy(mStr, "L");
@@ -656,8 +682,8 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
   }\r
   sprintf(tmp, "%c%d", mt->toFile + 'a', mt->toRank + 1 - (gs->ranks > 9));\r
   strcat(mStr, tmp);\r
-\r
-  if ((piece == PAWN) && (mt->piecePromotionTo != NOPIECE)) {\r
+
+  if ((piece == PAWN || gs->promoType == 3) && (mt->piecePromotionTo != NOPIECE)) {\r
     strcat(mStr, "=");         /* = before promoting piece */\r
     switch (piecetype(mt->piecePromotionTo)) {\r
     case KNIGHT:\r
@@ -702,6 +728,15 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     case MASTODON:\r
       strcat(mStr, "G");\r
       break;\r
+    case GOLD: // [HGM] Shogi promotions: avoid use of '+'\r
+      strcat(mStr, "G");\r
+      break;\r
+    case DRAGONHORSE:\r
+      strcat(mStr, "H");\r
+      break;\r
+    case DRAGONKING:\r
+      strcat(mStr, "D");\r
+      break;\r
     default:\r
       break;\r
     }\r