From: H.G.Muller Date: Sun, 15 Dec 2019 22:52:43 +0000 (+0100) Subject: Implement auto-gating in holdingless S-Chess X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=1ca6e13d14c1ef508f9e3918c33a46ec4b8bac62;p=xboard.git Implement auto-gating in holdingless S-Chess When there are no holdings in (parent) variant seirawan, the first and last rank are supposed to act as file-specific holdings, and pieces on it will automatically be gated if the virgin piece standing before them is moved away by the user. (Engines must still specify a gating through the promotion suffix.) The old location of the gated piece on the holdings rank will then be blacked out (and the unused squares on the holdings raks should also be black). --- diff --git a/backend.c b/backend.c index 02144c5..7c9bcfb 100644 --- a/backend.c +++ b/backend.c @@ -7774,6 +7774,14 @@ LeftClick (ClickType clickType, int xPix, int yPix) ReportClick("lift", x, y); MarkTargetSquares(0); if(gameMode == EditPosition && controlKey) gatingPiece = boards[currentMove][fromY][fromX]; + if(gameInfo.variant == VariantSChess && !gameInfo.holdingsWidth) { // auto-gating + int white = (boards[currentMove][fromY][fromX] < BlackPawn); + if(fromY == (white ? 1 : BOARD_HEIGHT - 2) // piece on shifted back-rank + && boards[currentMove][VIRGIN][fromX] & (white ? VIRGIN_W : VIRGIN_B)) { // and is virgin + int p = boards[currentMove][fromY - 2*white + 1][fromX]; + if(p != DarkSquare) gatingPiece = p; + } + } DragPieceBegin(xPix, yPix, FALSE); dragging = 1; if(appData.sweepSelect && CanPromote(piece = boards[currentMove][fromY][fromX], fromY)) { promoSweep = defaultPromoChoice; @@ -7831,7 +7839,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) } if (OKToStartUserMove(x, y)) { if(gameInfo.variant == VariantSChess && // S-Chess: back-rank piece selected after holdings means gating - (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && + (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && gameInfo.holdingsWidth && y == (toP < BlackPawn ? 0 : BOARD_HEIGHT-1)) gatingPiece = boards[currentMove][fromY][fromX]; else gatingPiece = doubleClick ? fromP : EmptySquare; @@ -10509,10 +10517,11 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } if(gameInfo.variant == VariantSChess) { // update virginity - if(fromY == 0) board[VIRGIN][fromX] &= ~VIRGIN_W; // loss by moving - if(fromY == BOARD_HEIGHT-1) board[VIRGIN][fromX] &= ~VIRGIN_B; - if(toY == 0) board[VIRGIN][toX] &= ~VIRGIN_W; // loss by capture - if(toY == BOARD_HEIGHT-1) board[VIRGIN][toX] &= ~VIRGIN_B; + int offs = !gameInfo.holdingsSize; + if(fromY == offs) board[VIRGIN][fromX] &= ~VIRGIN_W; // loss by moving + if(fromY == BOARD_HEIGHT-1-offs) board[VIRGIN][fromX] &= ~VIRGIN_B; + if(toY == offs) board[VIRGIN][toX] &= ~VIRGIN_W; // loss by capture + if(toY == BOARD_HEIGHT-1-offs) board[VIRGIN][toX] &= ~VIRGIN_B; } if (fromX == toX && fromY == toY && killX < 0) return; @@ -10766,6 +10775,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) if(gameInfo.variant == VariantSChess && promoChar != NULLCHAR && promoChar != '=' && piece != WhitePawn && piece != BlackPawn) { board[fromY][fromX] = CharToPiece(piece < BlackPawn ? ToUpper(promoChar) : ToLower(promoChar)); // S-Chess gating + int white = (piece < BlackPawn); + if(!gameInfo.holdingsSize) board[fromY-2*white+1][fromX] = DarkSquare; } else if(promoChar == '+') { /* [HGM] Shogi-style promotions, to piece implied by original (Might overwrite ordinary Pawn promotion) */