Fix bugs in Shogi Knight moves and promotions
[capablanca.git] / lasker-2.2.3 / src / movecheck.c
index c0dd853..30ada65 100644 (file)
@@ -218,7 +218,7 @@ static int legal_honorablehorse_move(struct game_state_t * gs, int ff, int fr, i
 
   dx = ff - tf;
   dy = fr - tr;
-  if (dy == gs->onMove == WHITE ? 2 : -2) {
+  if (dy == (gs->onMove == WHITE ? -2 : 2)) {
     if (abs(dx) == 1)
       return 1;
   }
@@ -1303,6 +1303,21 @@ int legal_move(struct game_state_t * gs,
       return 0;
     if (gs->board[tFile][tRank] != NOPIECE)
       return 0;
+    if (gs->promoType == 3) { // Shogi
+      int r;
+      switch(move_piece) {
+       case PAWN:  // check for own Pawn in same file
+         for(r=0; r<gs->ranks; r++) if(gs->board[tFile][r] == (gs->onMove|PAWN)) return 0;
+       case LANCE: // Pawns and Lances not on last rank
+         if(gs->onMove == WHITE && tRank >= gs->ranks-1) return 0;
+         if(gs->onMove == BLACK && tRank < 1) return 0;
+         break;
+       case HONORABLEHORSE: // Knights at least two ranks from edge
+         if(gs->onMove == WHITE && tRank >= gs->ranks-2) return 0;
+         if(gs->onMove == BLACK && tRank < 2) return 0;
+       default: ;
+      }
+    } else
     if (move_piece == PAWN && (tRank == 0 || tRank == gs->ranks-1))
       return 0;
     return 1;
@@ -1495,7 +1510,7 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
       switch(piecetype(piece)) {
         case PAWN:
         case LANCE:
-        case KNIGHT:
+        case HONORABLEHORSE:
         case SILVER:
           promote = GOLD; break;
         case BISHOP:
@@ -1506,7 +1521,7 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
       }
     } else
       switch(piecetype(piece)) { // force mandatory promotions
-        case KNIGHT:
+        case HONORABLEHORSE:
           if(mt->toRank == 1 || mt->toRank == gs->files-2) promote = GOLD;
         case PAWN:
         case LANCE:
@@ -1613,7 +1628,7 @@ int in_check(struct game_state_t * gs)
   }\r
   for (InitPieceLoop(gs->board, &f, &r, gs->onMove);\r
        NextPieceLoop(gs->board, &f, &r, gs->onMove, gs->files, gs->ranks);) {\r
-    if (legal_move(gs, f, r, kf, kr)) {        /* In Check? */\r
+    if (legal_move(gs, f, r, kf, kr)) {        /* In Check? */
       return 1;\r
     }\r
   }\r