From: H.G.Muller Date: Sat, 7 May 2016 21:33:35 +0000 (+0200) Subject: Fix multi-leg promotions X-Git-Url: http://winboard.nl/cgi-bin?p=xboard.git;a=commitdiff_plain;h=efefb3388ee26548a47df361bb60ce113b1d96e4 Fix multi-leg promotions Two-leg promotions were sent as gibberish to the engine (and thus rejected). It was also pretty annoying that XBoard's own idea of what should be promotions was still applied even when highlighting denied promotions (because the zone was different than assumed, or a promotion-on-entry rule applies). Now the legality markers from the GUI move generator are different from the red and yellow markers from an engine highlight command, and the latter are taken as a denial of promotion, and will suppress it. --- diff --git a/backend.c b/backend.c index 241bf96..79d04fb 100644 --- a/backend.c +++ b/backend.c @@ -5169,7 +5169,7 @@ SendMoveToProgram (int moveNum, ChessProgramState *cps) m[2], m[3] - '0', m[5], m[6] - '0', m[2] + (m[0] > m[5] ? 1 : -1), m[3] - '0'); - else if(*c && m[8]) { // kill square followed by 2 characters: 2nd kill square rather than promo suffix + else if(*c && m[8] != '\n') { // kill square followed by 2 characters: 2nd kill square rather than promo suffix *c = m[9]; if(*c == '\n') *c = NULLCHAR; snprintf(buf, MSG_SIZ, "%c%d%c%d,%c%d%c%d,%c%d%c%d%s\n", m[0], m[1] - '0', // convert to three moves m[7], m[8] - '0', @@ -5386,7 +5386,7 @@ CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char sprintf(move, "%c%c%c%c%c\n", AAA + ff, ONE + rf, AAA + ft, ONE + rt, promoChar); if(killX >= 0 && killY >= 0) { - sprintf(move+4, ";%c%c\n", AAA + killX, ONE + killY); + sprintf(move+4, ";%c%c%c\n", AAA + killX, ONE + killY, promoChar); if(kill2X >= 0 && kill2Y >= 0) sprintf(move+7, "%c%c%c\n", AAA + kill2X, ONE + kill2Y, promoChar); } } @@ -6707,6 +6707,7 @@ HasPromotionChoice (int fromX, int fromY, int toX, int toY, char *promoChoice, i piece = boards[currentMove][fromY][fromX]; if(gameInfo.variant == VariantChu) { promotionZoneSize = BOARD_HEIGHT/3; + if(legal[toY][toX] == 6) return FALSE; // no promotion if highlights deny it highestPromotingPiece = (PieceToChar(piece) == '+' || PieceToChar(CHUPROMOTED(piece)) != '+') ? WhitePawn : WhiteKing; } else if(gameInfo.variant == VariantShogi) { promotionZoneSize = BOARD_HEIGHT/3 +(BOARD_HEIGHT == 8); @@ -7405,7 +7406,7 @@ MarkByFEN(char *fen) int s = 0; if(*fen == 'M') legal[r][f] = 2; else // request promotion choice if(*fen == 'B') legal[r][f] = 4; else // request auto-promotion to victim - if(*fen >= 'A' && *fen <= 'Z') legal[r][f] = 3; else + if(*fen >= 'A' && *fen <= 'Z') legal[r][f] = 6; else if(*fen >= 'a' && *fen <= 'z') *fen += 'A' - 'a'; if(*fen == '/' && f > BOARD_LEFT) f = BOARD_LEFT, r--; else if(*fen == 'T') marker[r][f++] = 0; else