Debug Seirawan Chess
authorH.G. Muller <h.g.muller@hccnet.nl>
Tue, 29 Nov 2011 21:59:48 +0000 (22:59 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 29 Nov 2011 21:59:48 +0000 (22:59 +0100)
lasker-2.2.3/src/algcheck.c
lasker-2.2.3/src/gameproc.c
lasker-2.2.3/src/movecheck.c

index aa7d5af..1c1ff75 100644 (file)
@@ -247,12 +247,14 @@ static void add_promotion(struct game_state_t *gs, const char *mstr, struct move
                return;
        }
 
+      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) {
                return;
        }
        if (mt->toRank < gs->ranks - gs->promoZone && mt->toRank >= gs->promoZone) {
                return;
        }
+      }
 
        switch (tolower(s[1])) {
        case 'f':
@@ -338,6 +340,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 +371,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;
@@ -571,6 +575,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:
@@ -590,6 +595,8 @@ char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
     strcpy(mStr, "V");
     break;
   case HORSE:
+  case DRAGONHORSE:
+  case HAWK:
     strcpy(mStr, "H");
     break;
   case HONORABLEHORSE:
@@ -598,9 +605,6 @@ 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 LANCE:
     strcpy(mStr, "L");
     break;
@@ -687,7 +691,7 @@ 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)) {
+  if ((piece == PAWN || gs->promoType == 3 || gs->drops == 2) && (mt->piecePromotionTo != NOPIECE)) {
     strcat(mStr, "=");         /* = before promoting piece */
     switch (piecetype(mt->piecePromotionTo)) {
     case KNIGHT:
index 52f42e2..4f50fa4 100644 (file)
@@ -573,7 +573,7 @@ void process_move(int p, char *command)
   }
   pp->promote = NOPIECE; // [HGM] this seemed to be uninitialized, which caused spurious promotion in Shogi
   if ((len = strlen(command)) > 1) {
-    if (command[len - 2] == '=' || gg->gameState.drops == 2 && command[len - 2] == '/') { // [HGM] encode gating as promotion
+    if (command[len - 2] == '=' || gg->game_state.drops == 2 && command[len - 2] == '/') { // [HGM] encode gating as promotion
 printf("promo '%s'\n", command);
       switch (tolower(command[strlen(command) - 1])) {
       case 'n':
index 6996d09..edeeea7 100644 (file)
@@ -1486,7 +1486,7 @@ int legal_move(struct game_state_t * gs,
 static int move_calculate(struct game_state_t * gs, struct move_t * mt, int promote)
 {
   struct game_state_t fakeMove;
-  int gating = 0;
+  int gating = 0, stm;
 
   mt->pieceCaptured = gs->board[mt->toFile][mt->toRank];
   mt->enPassant = 0;           /* Don't know yet, let execute move take care
@@ -1500,7 +1500,10 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   } 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][promote-1])
+           mt->piecePromotionTo = promote, gating = 1;
   } 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;
@@ -1536,7 +1539,6 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) && 
        !gs->palace && // [HGM] XQ: no promotions in xiangqi
       ((mt->toRank < gs->promoZone) || (mt->toRank >= gs->ranks - gs->promoZone))) {
-    int stm = colorval(gs->board[mt->fromFile][mt->fromRank]);
     if(!promote && (mt->toRank == 0 || mt->toRank == gs->ranks-1)) { // promotion obligatory, but not specified
        if(gs->promoType != 2) promote = QUEEN; else { // choose a default
            for(promote=PIECES-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break;
@@ -1552,10 +1554,12 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
     int i; struct game *g = &game_globals.garray[gs->gameNum];
     if(!gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified
     // now we must test virginity of the moved piece. Yegh!
-    for (i = g->numHalfMoves-2; i > 0; i -= 2) {
-      if (g->moveList[i].toFile == mt->fromFile && g->moveList[i].toRank == mt->fromRank) return MOVE_ILLEGAL;
+    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) return MOVE_ILLEGAL;
     }
-    gating = 1; // gating OK; remember we did it for check test
+    mt->piecePromotionTo = promote; // gating OK
+    gating = 1; // remember we did it for check test
   } else {
     mt->piecePromotionTo = NOPIECE;
   }
@@ -1590,7 +1594,7 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   fakeMove = *gs;
   /* Calculates enPassant also */
   execute_move(&fakeMove, mt, 0);
-  if(gating) fakeMove.board[mt-fromFile][mt->fromRank] = NOPIECE; // [HGM] gating is only legal if non-gating move was (weird, but true)
+  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))
@@ -1894,7 +1898,11 @@ int parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt, int pro
 
   if (mt->piecePromotionTo != NOPIECE) {
          promote = piecetype(mt->piecePromotionTo);
-  } else if(gs->promoType == 3 && promote == MASTODON) promote = GOLD;
+  } 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);
 }
@@ -1933,10 +1941,14 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
     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
+      gs->board[fKing][backRank] = mt->piecePromotionTo | gs->onMove;   // for now always on King square
+      gs->holding[gs->onMove==WHITE ? 0 : 1][mt->piecePromotionTo-1]--; // remove gated piece from holdings
+    }
   } else {
   movedPiece = gs->board[mt->fromFile][mt->fromRank];
   tookPiece = gs->board[mt->toFile][mt->toRank];
-  if(gs->drops == 2 && mt->piecePromotionTo != NOPIECE && pieceType(movedPiece) != PAWN) { // [HGM] Seirawan-style gating
+  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