From 0673decdb041b796d55fe77e7e4eaf32895265b3 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Mon, 11 Jul 2011 21:38:07 +0200 Subject: [PATCH] Fix use of promoChar G,D,H in long-algebraic Shogi moves D and H were not recognized at all, and G was MASTODON. Now D&H are added, and MASTODON is redefined in parse_move as GOLD when promoType==3. SAN moves do their own interpretation of the promo suffix, which was already OK. --- lasker-2.2.3/src/gameproc.c | 6 + lasker-2.2.3/src/movecheck.c | 2006 +++++++++++++++++++++--------------------- 2 files changed, 1010 insertions(+), 1002 deletions(-) diff --git a/lasker-2.2.3/src/gameproc.c b/lasker-2.2.3/src/gameproc.c index 53147a8..b7aab88 100644 --- a/lasker-2.2.3/src/gameproc.c +++ b/lasker-2.2.3/src/gameproc.c @@ -609,6 +609,12 @@ printf("promo '%s'\n", command); pp->promote = MASTODON; break; // Shogi promotions + case 'h': + pp->promote = DRAGONHORSE; + break; + case 'd': + pp->promote = DRAGONKING; + break; case '^': case '+': pp->promote = GOLD; diff --git a/lasker-2.2.3/src/movecheck.c b/lasker-2.2.3/src/movecheck.c index 30405fa..8f0dd9c 100644 --- a/lasker-2.2.3/src/movecheck.c +++ b/lasker-2.2.3/src/movecheck.c @@ -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) { - 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 (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 { - 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; - } + } 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 + 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 + 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; @@ -366,16 +366,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) -{ - 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); -} - +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 +387,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 + 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 +412,148 @@ 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) -{ - 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) -{ +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; - 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) -{ + 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; - 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 (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 - 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) -{ + 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); -} - -static int legal_mastodon_move(struct game_state_t * gs, int ff, int fr, int tf, int tr) -{ + || 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); -} - -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_priestess_move(struct game_state_t * gs, int ff, int fr, int tf, int tr) -{ + || 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_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); -} - -static int legal_minister_move(struct game_state_t * gs, int ff, int fr, int tf, int tr) -{ + || 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); -} - + || 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) - result = legal_knight_move(gs, ff, fr, tf, tr); + 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 +562,50 @@ 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 + } else result = legal_man_move(gs, ff, fr, tf, tr); - if(result) return 1; + if(result) return 1; // [HGM] castle: orthodox legal castlings given as King move return 2 - if (gs->onMove == WHITE) { - /* King side castling */ - if ((fr == 0) && (tr == 0) && (ff == gs->files/2) && (tf == gs->files-2) && (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->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->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->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; - } - } - + if (gs->onMove == WHITE) { + /* King side castling */ + if ((fr == 0) && (tr == 0) && (ff == gs->files/2) && (tf == gs->files-2) && (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->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->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->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 +620,375 @@ static void possible_pawn_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { - 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 (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 && + 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 + !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 - } + } if (onf < gs->files-1) { - if (gs->board[onf + 1][onr + 1] != NOPIECE && + 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 + !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 - } - if (gs->ep_possible[0][onf] == -1) - add_pos(onf - 1, onr + 1, posf, posr, numpos); - if (gs->ep_possible[0][onf] == 1) + } + 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 { - 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); - } + } 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 && - iscolor(gs->board[onf - 1][onr - 1], WHITE) && - !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi + 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 - } + } if (onf < gs->files-1) { - 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 + 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 - } - 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); - } + } + 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_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}, - {-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 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}, - {-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; + 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))))) - add_pos(f, r, posf, posr, numpos); - } + ((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; - - /* 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; - } + 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; - - /* 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; - } + 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; - - /* Left */ - f = onf; - r = onr; - for (i=0;;) { - f--; - if ((f < 0) || (f >= gs->files)) - break; - if ((r < 0) || (r >= gs->ranks)) - break; + 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 - 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; + 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 - 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; + 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 - 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; + 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 - if (gs->board[f][r] != NOPIECE) - break; - } + 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; - - /* 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); -} - + 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 +997,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, - 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)) +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) || - (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 ((r < 0) || (r >= gs->ranks)) + 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; - 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; + 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; - 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, + 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 +1116,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, +static void possible_dragonking_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1124,7 +1124,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, +static void possible_dragonhorse_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1132,7 +1132,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, +static void possible_centaur_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1140,7 +1140,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, +static void possible_woody_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1148,7 +1148,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, +static void possible_squirrel_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1157,7 +1157,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, +static void possible_mastodon_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1166,7 +1166,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, +static void possible_amazon_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1174,7 +1174,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, +static void possible_modernelephant_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1182,7 +1182,7 @@ 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, +static void possible_priestess_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1191,7 +1191,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, +static void possible_minister_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1200,7 +1200,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, +static void possible_gold_moves(struct game_state_t * gs, int onf, int onr, int *posf, int *posr, int *numpos) { @@ -1208,83 +1208,83 @@ 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); + 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); + 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); + 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); + add_pos(onf+1, onr-1, posf, posr, numpos); } } -static void possible_silver_moves(struct game_state_t * gs, +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); + 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); + add_pos(onf, onr-1, posf, posr, numpos); } } -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); +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; + if(r < 0 || r >= gs->ranks) return; if(onf > 0) { - 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 ((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) || - (iscolor(gs->board[onf+1][r], CToggle(gs->onMove)))) - add_pos(onf + 1, r, posf, posr, numpos); - } -} - + 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) - possible_knight_moves(gs, onf, onr, posf, posr, numpos); + 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 - possible_man_moves(gs, onf, onr, posf, posr, numpos); + 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) -{ - 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); - } -} +{ + 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, @@ -1387,18 +1387,18 @@ int legal_move(struct game_state_t * gs, case ROOK: legal = legal_rook_move(gs, fFile, fRank, tFile, tRank); break; - case CARDINAL: - case PRINCESS: - legal = legal_cardinal_move(gs, fFile, fRank, tFile, tRank); - break; - 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 CARDINAL: + case PRINCESS: + legal = legal_cardinal_move(gs, fFile, fRank, tFile, tRank); + break; + 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; @@ -1483,17 +1483,17 @@ 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; - - 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)); + struct game_state_t fakeMove; + + 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"); @@ -1528,10 +1528,10 @@ 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])); + 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 + !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 @@ -1545,47 +1545,47 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom // 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 - } 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; + } 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) && + if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) && (mt->fromFile == gs->files/2) && (mt->toFile == 2) && - mt->fromRank == mt->toRank) { - sprintf(mt->moveString, "o-o-o"); - } else if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) && + 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) { + mt->fromRank == mt->toRank) { sprintf(mt->moveString, "o-o"); } else { #else { -#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; +#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); - - /* 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; + execute_move(&fakeMove, mt, 0); + + /* 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, @@ -1612,36 +1612,36 @@ int legal_andcheck_move(struct game_state_t * gs, */ int in_check(struct game_state_t * gs) { - 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 0; - } - for (InitPieceLoop(gs->board, &f, &r, gs->onMove); - NextPieceLoop(gs->board, &f, &r, gs->onMove, gs->files, gs->ranks);) { + 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 0; + } + 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; - } - } - return 0; + return 1; + } + } + return 0; } int has_legal_move(struct game_state_t * gs) @@ -1667,18 +1667,18 @@ int has_legal_move(struct game_state_t * gs) case ROOK: possible_rook_moves(gs, f, r, possiblef, possibler, &numpossible); break; - case CARDINAL: - case PRINCESS: - possible_cardinal_moves(gs, f, r, possiblef, possibler, &numpossible); - break; - 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 CARDINAL: + case PRINCESS: + possible_cardinal_moves(gs, f, r, possiblef, possibler, &numpossible); + break; + 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; @@ -1762,29 +1762,29 @@ int has_legal_move(struct game_state_t * gs) } } - /* IanO: if we got here, then kf and kr must be set */ + /* 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 - /* 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 && ffiles && r>=0 && rranks && gs->board[f][r] == NOPIECE) { - /* try a drop next to the king */ - if (legal_andcheck_move(gs, ALG_DROP, QUEEN, f, 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 && ffiles && r>=0 && rranks && 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; + if (legal_andcheck_move(gs, ALG_DROP, i, f, r)) return 1; return 0; - } - return 1; - } - } - } - gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--; - } + } + return 1; + } + } + } + gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--; + } return 0; } @@ -1792,80 +1792,80 @@ 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); - int result; - - 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: + int type = is_move(mstr); + int result; + + 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; - 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; - } + 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; - mt->toFile = gs->files-2; - mt->fromRank = gs->onMove == WHITE ? gs->wkrmoved : gs->bkrmoved; - mt->toRank = mt->toFile-1; // R next to K - break; + 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 - 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; - } +#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 - mt->fromFile = ALG_CASTLE; - mt->toFile = 2; - mt->fromRank = gs->onMove == WHITE ? gs->wqrmoved : gs->bqrmoved; +#endif + mt->fromFile = ALG_CASTLE; + mt->toFile = 2; + mt->fromRank = gs->onMove == WHITE ? gs->wqrmoved : gs->bqrmoved; mt->toRank = mt->toFile+1; - 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; + 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 - || mt->toRank < 0 || mt->toRank >= gs->ranks || mt->toFile >= gs->files) + 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 - + if (!(result = legal_move(gs, mt->fromFile, mt->fromRank, mt->toFile, mt->toRank))) - return MOVE_ILLEGAL; + return MOVE_ILLEGAL; if(result == 2) { // [HGM] castle: orthodox castling was given as King move; convert it to new format if(mt->fromFile - mt->toFile > 1) { // Q-side @@ -1876,13 +1876,13 @@ 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; - } - + } + if (mt->piecePromotionTo != NOPIECE) { - promote = piecetype(mt->piecePromotionTo); - } - - return move_calculate(gs, mt, promote); + promote = piecetype(mt->piecePromotionTo); + } else if(gs->promoType == 3 && promote == MASTODON) promote = GOLD; + + return move_calculate(gs, mt, promote); } /* Returns MOVE_OK, MOVE_NOMATERIAL, MOVE_CHECKMATE, or MOVE_STALEMATE */ @@ -1913,9 +1913,11 @@ 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 - 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 + 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; } else { movedPiece = gs->board[mt->fromFile][mt->fromRank]; @@ -1948,10 +1950,10 @@ 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 */ - for (i = 0; i < gs->files; i++) { - gs->ep_possible[0][i] = 0; - gs->ep_possible[1][i] = 0; + /* 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 @@ -1969,106 +1971,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) && - ((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) && + 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 */ - 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->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 */ - 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; ifiles; i++) { + 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; ifiles; i++) { for (j=0; jranks; j++) { - int p = gs->board[i][j]; - switch(piecetype(p)) { - case KNIGHT: - case BISHOP: - foobar++; - break; - case KING: - case NOPIECE: - break; - default: - foobar = 2; - break; + 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++; - } + 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) - return MOVE_NOMATERIAL; - } else { - gs->onMove = CToggle(gs->onMove); + } else if (foobar < 2) + return MOVE_NOMATERIAL; + } else { + gs->onMove = CToggle(gs->onMove); } - - return MOVE_OK; + + return MOVE_OK; } int backup_move(int g, int mode) @@ -2133,36 +2135,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)) { - 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 ((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 @@ -2210,29 +2212,29 @@ int backup_move(int g, int mode) we should scan moveList. *******************/ - 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->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); @@ -2311,28 +2313,28 @@ cleanupMove: array. (patch from Soso, added by Sparky 3/17/95) ********/ - 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; - } - } - } - } + 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; } -- 1.7.0.4