From 36a3483dd6f8361b0ccb7c5648e83922883bb9a6 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Sun, 2 Feb 2014 10:22:25 +0100 Subject: [PATCH] Make Fischer castling generally available A new volatile option -fischerCastlings allows every variant to be played with Fischer castling, which so far was only allowed in variants FRC/CRC. This only makes sense in shuffle variants, where King and Rooks might not be in their orthodox locations. But even when they are, it has consequences for the user interface, which will require dragging King on Rook as the only way to enter castling. Like -shuffleOpenings the setting will be cleared as soon as you switch variant (unless you switch to FRC/CRC, where they Fischer castling is on by default). It can be set from the New Shuffle dialog. --- args.h | 1 + backend.c | 18 ++++++++++-------- common.h | 1 + dialogs.c | 2 ++ moves.c | 32 ++++++++++++++++++++++++-------- po/da.po | 2 +- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/args.h b/args.h index 2bc0211..dec7a5c 100644 --- a/args.h +++ b/args.h @@ -558,6 +558,7 @@ ArgDescriptor argDescriptors[] = { { "pgnEventHeader", ArgString, (void *) &appData.pgnEventHeader, TRUE, (ArgIniType) "Computer Chess Game" }, { "defaultFrcPosition", ArgInt, (void *) &appData.defaultFrcPosition, TRUE, (ArgIniType) -1 }, { "shuffleOpenings", ArgTrue, (void *) &shuffleOpenings, FALSE, INVALID }, + { "fischerCastling", ArgTrue, (void *) &appData.fischerCastling, FALSE, INVALID }, { "gameListTags", ArgString, (void *) &appData.gameListTags, TRUE, (ArgIniType) GLT_DEFAULT_TAGS }, { "saveOutOfBookInfo", ArgBoolean, (void *) &appData.saveOutOfBookInfo, TRUE, (ArgIniType) TRUE }, { "showEvalInMoveHistory", ArgBoolean, (void *) &appData.showEvalInMoveHistory, TRUE, (ArgIniType) TRUE }, diff --git a/backend.c b/backend.c index dfaef74..0af55fa 100644 --- a/backend.c +++ b/backend.c @@ -415,6 +415,7 @@ PosFlags (index) default: break; } + if(appData.fischerCastling) flags |= F_FRC_TYPE_CASTLING, flags &= ~F_ALL_CASTLE_OK; // [HGM] fischer return flags; } @@ -5093,8 +5094,7 @@ SendMoveToProgram (int moveNum, ChessProgramState *cps) /* Added by Tord: Send castle moves in "O-O" in FRC games if required by * the engine. It would be nice to have a better way to identify castle * moves here. */ - if((gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom) - && cps->useOOCastle) { + if(appData.fischerCastling && cps->useOOCastle) { int fromX = moveList[moveNum][0] - AAA; int fromY = moveList[moveNum][1] - ONE; int toX = moveList[moveNum][2] - AAA; @@ -5971,7 +5971,7 @@ InitPosition (int redraw) oldh = gameInfo.holdingsWidth; static int oldv; - if(appData.icsActive) shuffleOpenings = FALSE; // [HGM] shuffle: in ICS mode, only shuffle on ICS request + if(appData.icsActive) shuffleOpenings = appData.fischerCastling = FALSE; // [HGM] shuffle: in ICS mode, only shuffle on ICS request /* [AS] Initialize pv info list [HGM] and game status */ { @@ -6012,6 +6012,7 @@ InitPosition (int redraw) switch (gameInfo.variant) { case VariantFischeRandom: shuffleOpenings = TRUE; + appData.fischerCastling = TRUE; default: break; case VariantShatranj: @@ -6042,6 +6043,7 @@ InitPosition (int redraw) break; case VariantCapaRandom: shuffleOpenings = TRUE; + appData.fischerCastling = TRUE; case VariantCapablanca: pieces = CapablancaArray; gameInfo.boardWidth = 10; @@ -7444,7 +7446,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) /* Check if clicking again on the same color piece */ fromP = boards[currentMove][fromY][fromX]; toP = boards[currentMove][y][x]; - frc = gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom || gameInfo.variant == VariantSChess; + frc = appData.fischerCastling || gameInfo.variant == VariantSChess; if( (killX < 0 || x != fromX || y != fromY) && // [HGM] lion: do not interpret igui as deselect! ((WhitePawn <= fromP && fromP <= WhiteKing && WhitePawn <= toP && toP <= WhiteKing && @@ -8627,7 +8629,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h GameEnds(machineWhite ? BlackWins : WhiteWins, buf1, GE_XBOARD); return; - } else if(gameInfo.variant != VariantFischeRandom && gameInfo.variant != VariantCapaRandom) + } else if(!appData.fischerCastling) /* [HGM] Kludge to handle engines that send FRC-style castling when they shouldn't (like TSCP-Gothic) */ switch(moveType) { @@ -17646,7 +17648,7 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) } else { if(nrCastlingRights) { q = p; - if(gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom) { + if(appData.fischerCastling) { /* [HGM] write directly from rights */ if(boards[move][CASTLING][2] != NoRights && boards[move][CASTLING][0] != NoRights ) @@ -17882,7 +17884,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) board[EP_STATUS] = EP_UNKNOWN; for(i=0; i= 'a' && *p < 'a' + gameInfo.boardWidth) || ( *p >= 'A' && *p < 'A' + gameInfo.boardWidth) ) { int c = *p++, whiteKingFile=NoRights, blackKingFile=NoRights; diff --git a/common.h b/common.h index 96c060e..8cd93ce 100644 --- a/common.h +++ b/common.h @@ -512,6 +512,7 @@ typedef struct { char *loadPositionFile; int loadPositionIndex; /* position # within file */ char *savePositionFile; + Boolean fischerCastling;/* [HGM] fischer: allow Fischr castling in any variant */ Boolean matchMode; int matchGames; Boolean monoMode; diff --git a/dialogs.c b/dialogs.c index fd68fb2..92845b5 100644 --- a/dialogs.c +++ b/dialogs.c @@ -533,6 +533,7 @@ Pick (int n) shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */ startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */ + appData.fischerCastling = FALSE; /* [HGM] fischer: no longer valid in new variant */ appData.NrRanks = ranksTmp; appData.NrFiles = filesTmp; appData.holdingsSize = sizeTmp; @@ -1455,6 +1456,7 @@ ShuffleOK (int n) static Option shuffleOptions[] = { { 0, 0, 0, NULL, (void*) &shuffleOpenings, NULL, NULL, CheckBox, N_("shuffle") }, + { 0, 0, 0, NULL, (void*) &appData.fischerCastling, NULL, NULL, CheckBox, N_("Fischer castling") }, { 0,-1,2000000000, NULL, (void*) &appData.defaultFrcPosition, "", NULL, Spin, N_("Start-position number:") }, { 0, 0, 0, NULL, (void*) &SetRandom, NULL, NULL, Button, N_("randomize") }, { 0, SAME_ROW, 0, NULL, (void*) &SetRandom, NULL, NULL, Button, N_("pick fixed") }, diff --git a/moves.c b/moves.c index 856454c..9b891b8 100644 --- a/moves.c +++ b/moves.c @@ -1215,8 +1215,10 @@ GenLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure, Ches if(k != ft && board[0][k] != EmptySquare) ft = NoRights; for(k=left; k BOARD_LEFT+2) for(k=left+1; k<=right && ft != NoRights; k++) /* then if not checked */ if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = NoRights; - if(ft != NoRights && board[0][ft] == WhiteRook) - callback(board, flags, WhiteASideCastleFR, 0, swap ? ft : ff, 0, swap ? ff : ft, closure); + if(ft != NoRights && board[0][ft] == WhiteRook) { + if(flags & F_FRC_TYPE_CASTLING) callback(board, flags, WhiteASideCastleFR, 0, ff, 0, ft, closure); + if(swap) callback(board, flags, WhiteASideCastleFR, 0, ft, 0, ff, closure); + } } } else { ff = castlingRights[5]; /* King file if we have any rights */ @@ -1242,8 +1246,10 @@ GenLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure, Ches if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = NoRights; for(k=left; k BOARD_LEFT+2) for(k=left+1; k<=right && ft != NoRights; k++) /* then if not checked */ if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = NoRights; - if(ft != NoRights && board[BOARD_HEIGHT-1][ft] == BlackRook) - callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, swap ? ft : ff, BOARD_HEIGHT-1, swap ? ff : ft, closure); + if(ft != NoRights && board[BOARD_HEIGHT-1][ft] == BlackRook) { + if(flags & F_FRC_TYPE_CASTLING) callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure); + if(swap) callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, ft, BOARD_HEIGHT-1, ff, closure); + } } } @@ -1478,10 +1486,14 @@ LegalityTest (Board board, int flags, int rf, int ff, int rt, int ft, int promoC if(rf != 0) return IllegalMove; // must be on back rank if(!(board[VIRGIN][ff] & VIRGIN_W)) return IllegalMove; // non-virgin if(board[PieceToNumber(CharToPiece(ToUpper(promoChar)))][BOARD_WIDTH-2] == 0) return ImpossibleMove;// must be in stock + if(cl.kind == WhiteHSideCastleFR && (ff == BOARD_RGHT-2 || ff == BOARD_RGHT-3)) return ImpossibleMove; + if(cl.kind == WhiteASideCastleFR && (ff == BOARD_LEFT+2 || ff == BOARD_LEFT+3)) return ImpossibleMove; } else { if(rf != BOARD_HEIGHT-1) return IllegalMove; if(!(board[VIRGIN][ff] & VIRGIN_B)) return IllegalMove; // non-virgin if(board[BOARD_HEIGHT-1-PieceToNumber(CharToPiece(ToLower(promoChar)))][1] == 0) return ImpossibleMove; + if(cl.kind == BlackHSideCastleFR && (ff == BOARD_RGHT-2 || ff == BOARD_RGHT-3)) return ImpossibleMove; + if(cl.kind == BlackASideCastleFR && (ff == BOARD_LEFT+2 || ff == BOARD_LEFT+3)) return ImpossibleMove; } } else if(gameInfo.variant == VariantChu) { @@ -1726,10 +1738,14 @@ Disambiguate (Board board, int flags, DisambiguateClosure *closure) if(closure->rf != 0) closure->kind = IllegalMove; // must be on back rank if(!(board[VIRGIN][closure->ff] & VIRGIN_W)) closure->kind = IllegalMove; // non-virgin if(board[PieceToNumber(CharToPiece(ToUpper(c)))][BOARD_WIDTH-2] == 0) closure->kind = ImpossibleMove;// must be in stock + if(closure->kind == WhiteHSideCastleFR && (closure->ff == BOARD_RGHT-2 || closure->ff == BOARD_RGHT-3)) closure->kind = ImpossibleMove; + if(closure->kind == WhiteASideCastleFR && (closure->ff == BOARD_LEFT+2 || closure->ff == BOARD_LEFT+3)) closure->kind = ImpossibleMove; } else { if(closure->rf != BOARD_HEIGHT-1) closure->kind = IllegalMove; if(!(board[VIRGIN][closure->ff] & VIRGIN_B)) closure->kind = IllegalMove; // non-virgin if(board[BOARD_HEIGHT-1-PieceToNumber(CharToPiece(ToLower(c)))][1] == 0) closure->kind = ImpossibleMove; + if(closure->kind == BlackHSideCastleFR && (closure->ff == BOARD_RGHT-2 || closure->ff == BOARD_RGHT-3)) closure->kind = ImpossibleMove; + if(closure->kind == BlackASideCastleFR && (closure->ff == BOARD_LEFT+2 || closure->ff == BOARD_LEFT+3)) closure->kind = ImpossibleMove; } } else if(gameInfo.variant == VariantChu) { diff --git a/po/da.po b/po/da.po index 4929daf..0c2e38f 100644 --- a/po/da.po +++ b/po/da.po @@ -25,10 +25,10 @@ msgstr "" "PO-Revision-Date: 2012-03-06 12:27+0100\n" "Last-Translator: Byrial Ole Jensen \n" "Language-Team: Danish \n" -"Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: da\n" "X-Generator: Lokalize 1.2\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -- 1.7.0.4