From 3f31178e2168d0dc5ca0db4e245c63c25bb7ed1d Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Tue, 29 Nov 2011 22:59:48 +0100 Subject: [PATCH] Debug Seirawan Chess --- lasker-2.2.3/src/algcheck.c | 14 +++++++++----- lasker-2.2.3/src/gameproc.c | 2 +- lasker-2.2.3/src/movecheck.c | 28 ++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/lasker-2.2.3/src/algcheck.c b/lasker-2.2.3/src/algcheck.c index aa7d5af..1c1ff75 100644 --- a/lasker-2.2.3/src/algcheck.c +++ b/lasker-2.2.3/src/algcheck.c @@ -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: diff --git a/lasker-2.2.3/src/gameproc.c b/lasker-2.2.3/src/gameproc.c index 52f42e2..4f50fa4 100644 --- a/lasker-2.2.3/src/gameproc.c +++ b/lasker-2.2.3/src/gameproc.c @@ -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': diff --git a/lasker-2.2.3/src/movecheck.c b/lasker-2.2.3/src/movecheck.c index 6996d09..edeeea7 100644 --- a/lasker-2.2.3/src/movecheck.c +++ b/lasker-2.2.3/src/movecheck.c @@ -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 -- 1.7.0.4