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',
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);
}
}
!(fromX >=0 && fromY >= 0 && toX >= 0 && toY >= 0) ) // invalid move
return FALSE;
+ if(legal[toY][toX] == 4) return FALSE;
+
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);
{
int r, f;
if(!appData.markers || !appData.highlightDragging) return;
- for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) legal[r][f] = 0;
+ for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) legal[r][f] = marker[r][f] = 0;
r=BOARD_HEIGHT-1-deadRanks; f=BOARD_LEFT;
while(*fen) {
int s = 0;
- marker[r][f] = 0;
if(*fen == 'M') legal[r][f] = 2; else // request promotion choice
- if(*fen >= 'A' && *fen <= 'Z') legal[r][f] = 3; else
+ if(*fen == 'B') legal[r][f] = 4; else // request auto-promotion to victim
+ 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
}
Boolean right; // instructs front-end to use button-1 events as if they were button 3
+Boolean deferChoice;
void
LeftClick (ClickType clickType, int xPix, int yPix)
{
int x, y;
- Boolean saveAnimate;
+ static Boolean saveAnimate;
static int second = 0, promotionChoice = 0, clearFlag = 0, sweepSelecting = 0, flashing = 0, saveFlash;
char promoChoice = NULLCHAR;
ChessSquare piece;
if(flashing) return;
+ if(!deferChoice) { // when called for a retry, skip everything to the point where we left off
x = EventToSquare(xPix, BOARD_WIDTH);
y = EventToSquare(yPix, BOARD_HEIGHT);
if (!flipView && y >= 0) {
else ReportClick("put", x, y);
if(gatingPiece != EmptySquare && gameInfo.variant == VariantSChess) promoChoice = ToLower(PieceToChar(gatingPiece));
+ }
if(legal[toY][toX] == 2) { // highlight-induced promotion
if(piece == defaultPromoChoice) promoChoice = NULLCHAR; // deferral
else promoChoice = ToLower(PieceToChar(defaultPromoChoice));
+ } else if(legal[toY][toX] == 4) { // blue target square: engine must supply promotion choice
+ if(!*promoRestrict) { // but has not done that yet
+ deferChoice = TRUE; // set up retry for when it does
+ return; // and wait for that
+ }
+ promoChoice = ToLower(*promoRestrict); // force engine's choice
+ deferChoice = FALSE;
}
if (legal[toY][toX] == 2 && !appData.sweepSelect || HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, appData.sweepSelect)) {
}
return;
}
- if(sscanf(message, "choice %s", promoRestrict) == 1 && promoSweep != EmptySquare) {
- promoSweep = CharToPiece(currentMove&1 ? ToLower(*promoRestrict) : ToUpper(*promoRestrict));
- Sweep(0);
+ if(sscanf(message, "choice %s", promoRestrict) == 1) {
+ if(deferChoice) {
+ LeftClick(Press, 0, 0); // finish the click that was interrupted
+ } else if(promoSweep != EmptySquare) {
+ promoSweep = CharToPiece(currentMove&1 ? ToLower(*promoRestrict) : ToUpper(*promoRestrict));
+ if(strlen(promoRestrict) > 1) Sweep(0);
+ }
return;
}
/* [HGM] Allow engine to set up a position. Don't ask me why one would
if(appData.trueColors != 2) // 2 is a kludge to suppress this in WinBoard
snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -trueColors %s", appData.trueColors ? "true" : "false");
}
- if(!appData.pieceDirectory[0] && !appData.trueColors)
+ if(!appData.pieceDirectory[0] || !appData.trueColors)
snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -wpc %s -bpc %s",
Col2Text(0), // whitePieceColor
Col2Text(1) ); // blackPieceColor