FinishMove(moveType, fromX, fromY, toX, toY, promoChar);
}
+int hTab[(int)EmptySquare/2+1] = { 1,1,1,1,1,1,2,1,2,3,2,3,3,3,2,3,4,3,3,4,4,3,4 };
+int wTab[(int)EmptySquare/2+1] = { 1,1,2,3,4,5,3,7,4,3,5,4,4,5,7,5,4,6,6,5,5,7,6 };
+Board promoBoard;
+int promotionChoice = 0;
+
+void
+PiecePopUp(int x, int y)
+{
+ int i, j, h, w, nWhite=0, nBlack=0;
+ ChessSquare list[EmptySquare];
+ for(i=0; i<EmptySquare/2; i++) {
+ if(PieceToChar(i) != '.') list[nWhite++] = i;
+ if(PieceToChar(i+EmptySquare/2) != '.') list[EmptySquare - ++nBlack] = i + EmptySquare/2;
+ }
+ CopyBoard(promoBoard, boards[currentMove]);
+ for(i=0; i<BOARD_HEIGHT; i++) for(j=BOARD_LEFT; j<BOARD_RGHT; j++) promoBoard[i][j] = EmptySquare;
+ j = nWhite + nBlack + 1;
+ h = sqrt((j+1)/2 + 1.); w = (j+h-1)/h;
+ if(w>BOARD_RGHT-BOARD_LEFT) { w = BOARD_RGHT - BOARD_LEFT; h = (j+w-1)/w; }
+ for(i=0; i<nWhite; i++) promoBoard[i/w][BOARD_LEFT+i%w] = list[nWhite-1-i];
+ if(h==2 && nWhite == nBlack)
+ for(i=0; i<nWhite; i++) promoBoard[1][BOARD_LEFT+i%w] = list[EmptySquare-nBlack+i];
+ else
+ for(i=0; i<nBlack; i++) promoBoard[h-1-i/w][BOARD_LEFT+w-1-i%w] = list[EmptySquare-nBlack+i];
+ promotionChoice = 3;
+ ClearHighlights();
+ PromoDialog(h, w, promoBoard, TRUE, _("Select piece:"), x, y);
+}
+
+void
+PromoPopUp(ChessSquare piece)
+{ // determine the layout of the piece-choice dialog
+ int w, h, i, j, nr;
+ ChessSquare list[EmptySquare];
+
+ for(i=0; i<BOARD_HEIGHT; i++) for(j=BOARD_LEFT; j<BOARD_RGHT; j++) promoBoard[i][j] = EmptySquare;
+ if(gameInfo.variant == VariantShogi) {
+ // non-Pawn promotes; must be shogi
+ h = 1; w = 1; promoBoard[0][BOARD_LEFT+0] = piece;
+ if(PieceToChar(PROMOTED piece) != '.') {
+ // promoted version is enabled
+ w = 2; promoBoard[0][BOARD_LEFT+1] = PROMOTED piece;
+ }
+ } else {
+ // Pawn, promotes to any enabled other piece
+ h = 1; w = nr = 0;
+ for(i=1; i<EmptySquare/2; i++) {
+ if(PieceToChar(piece+i) != '.'
+ && PieceToChar(piece + i) != '~' // suppress bughouse true pieces
+ ) {
+ list[w++] = piece+i; nr++;
+ }
+ }
+ if(appData.testLegality && gameInfo.variant != VariantSuicide
+ && gameInfo.variant != VariantGiveaway) nr--,w--; // remove King
+ h = hTab[nr]; w = wTab[nr]; // factorize with nice ratio
+ for(i=0; i < nr; i++) promoBoard[i/w][BOARD_LEFT+i%w] = list[i]; // layout
+ }
+ promotionChoice = 2; // wait for click on board
+ PromoDialog(h, w, promoBoard, FALSE, _("Promote to:"), -1, -1);
+}
+
void
Mark(board, flags, kind, rf, ff, rt, ft, closure)
Board board;
{
int x, y;
Boolean saveAnimate;
- static int second = 0, promotionChoice = 0;
+ static int second = 0;
char promoChoice = NULLCHAR;
if(appData.seekGraph && appData.icsActive && loggedOn &&
}
if(promotionChoice) { // we are waiting for a click to indicate promotion piece
+ ChessSquare p = EmptySquare; Boolean inHoldings;
+ if(promotionChoice == 3) {
+ if(clickType == Press) EditPositionMenuEvent(promoBoard[y][x], fromX, fromY);
+ else if(clickType == Release) promotionChoice = 0;
+ fromX = fromY = -1;
+ return;
+ }
if(clickType == Release) return; // ignore upclick of click-click destination
- promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel
if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y);
- if(gameInfo.holdingsWidth &&
+ inHoldings = gameInfo.holdingsWidth &&
(WhiteOnMove(currentMove)
? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0
- : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) {
+ : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1);
// click in right holdings, for determining promotion piece
- ChessSquare p = boards[currentMove][y][x];
+ if(promotionChoice == 1 && inHoldings || promotionChoice == 2 && x >= BOARD_LEFT && x < BOARD_RGHT) {
+ p = promoBoard[y][x];
if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p);
if(p != EmptySquare) {
- FinishMove(NormalMove, fromX, fromY, toX, toY, ToLower(PieceToChar(p)));
+ char promoChar = PieceToChar(p);
+ if(gameInfo.variant == VariantShogi && promoChar != '+') promoChar = '=';
+ FinishMove(NormalMove, fromX, fromY, toX, toY, ToLower(promoChar));
fromX = fromY = -1;
+ promotionChoice = 0;
return;
}
}
+ promotionChoice = 0; // only one chance: if click not OK it is interpreted as cancel
DrawPosition(FALSE, boards[currentMove]);
return;
}
SetHighlights(fromX, fromY, toX, toY);
if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
// [HGM] super: promotion to captured piece selected from holdings
- ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];
- promotionChoice = TRUE;
+ ChessSquare p = boards[currentMove][fromY][fromX];
+ promotionChoice = 1;
+ CopyBoard(promoBoard, boards[currentMove]);
// kludge follows to temporarily execute move on display, without promoting yet
- boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank
- boards[currentMove][toY][toX] = p;
- DrawPosition(FALSE, boards[currentMove]);
- boards[currentMove][fromY][fromX] = p; // take back, but display stays
- boards[currentMove][toY][toX] = q;
+ promoBoard[fromY][fromX] = EmptySquare; // move Pawn to 8th rank
+ promoBoard[toY][toX] = p;
+ DrawPosition(FALSE, promoBoard);
DisplayMessage("Click in holdings to choose piece", "");
return;
}
- PromotionPopUp();
+ CopyBoard(promoBoard, boards[currentMove]);
+ PromoPopUp(boards[currentMove][fromY][fromX]);
} else {
UserMoveEvent(fromX, fromY, toX, toY, promoChoice);
if (!appData.highlightLastMove || gotPremove) ClearHighlights();
}
}
-int RightClick(ClickType action, int x, int y, int *fromX, int *fromY)
+int RightClick(ClickType action, int x, int y, int *xx, int *yy)
{ // front-end-free part taken out of PieceMenuPopup
int whichMenu; int xSqr, ySqr;
xSqr = EventToSquare(x, BOARD_WIDTH);
ySqr = EventToSquare(y, BOARD_HEIGHT);
+ if (flipView)
+ xSqr = BOARD_WIDTH - 1 - xSqr;
+ else
+ ySqr = BOARD_HEIGHT - 1 - ySqr;
+ if(promotionChoice == 3 && action == Release) {
+ EditPositionMenuEvent(promoBoard[ySqr][xSqr], fromX, fromY);
+ fromX = fromY = -1;
+ promotionChoice = 0;
+ return -1;
+ }
if (action == Release) UnLoadPV(); // [HGM] pv
if (action != Press) return -2; // return code to be ignored
switch (gameMode) {
return -1;
}
- if (((*fromX = xSqr) < 0) ||
- ((*fromY = ySqr) < 0)) {
- *fromX = *fromY = -1;
+ if (((*xx = xSqr) < 0) ||
+ ((*yy = ySqr) < 0)) {
+ *xx = *yy = -1;
return -1;
}
- if (flipView)
- *fromX = BOARD_WIDTH - 1 - *fromX;
- else
- *fromY = BOARD_HEIGHT - 1 - *fromY;
+
+ fromX = *xx; fromY = *yy;
+ if(whichMenu == 0) { PiecePopUp(x, y); return -1; } // suppress EditPosition menu
return whichMenu;
}