X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=f8c277a74ed9bceec3fbae1b5e8c0ab9c61780f9;hb=0d8809c4ffb488470b972032a69426b787fb9879;hp=ab347379d074f3776995f568e8e84355fd1e9807;hpb=1a74e7cd3bed2116e9bcfc4d2b5f270895dff16c;p=xboard.git diff --git a/backend.c b/backend.c index ab34737..f8c277a 100644 --- a/backend.c +++ b/backend.c @@ -148,6 +148,7 @@ extern int gettimeofday(struct timeval *, struct timezone *); #endif #include "backendz.h" #include "evalgraph.h" +#include "engineoutput.h" #include "gettext.h" #ifdef ENABLE_NLS @@ -250,7 +251,6 @@ static int NonStandardBoardSize P((VariantClass v, int w, int h, int s)); #endif ChessProgramState *WhitePlayer(); -void InsertIntoMemo P((int which, char *text)); // [HGM] kibitz: in engineo.c int VerifyDisplayMode P(()); char *GetInfoFromComment( int, char * ); // [HGM] PV time: returns stripped comment @@ -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; @@ -5647,6 +5647,9 @@ LoadMultiPV (int x, int y, char *buf, int index, int *start, int *end, int pane) } else if(strstr(buf+lineStart, "exclude:") == buf+lineStart) { // exclude moves clicked ExcludeClick(origIndex - lineStart); return FALSE; + } else if(!strncmp(buf+lineStart, "dep\t", 4)) { // column headers clicked + Collapse(origIndex - lineStart); + return FALSE; } ParsePV(buf+startPV, FALSE, gameMode != AnalyzeMode); *start = startPV; *end = index-1; @@ -5968,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 */ { @@ -6009,6 +6012,7 @@ InitPosition (int redraw) switch (gameInfo.variant) { case VariantFischeRandom: shuffleOpenings = TRUE; + appData.fischerCastling = TRUE; default: break; case VariantShatranj: @@ -6039,6 +6043,7 @@ InitPosition (int redraw) break; case VariantCapaRandom: shuffleOpenings = TRUE; + appData.fischerCastling = TRUE; case VariantCapablanca: pieces = CapablancaArray; gameInfo.boardWidth = 10; @@ -7441,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 && @@ -8624,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) { @@ -14208,7 +14213,10 @@ AnalyzeModeEvent () first.maybeThinking = FALSE; /* avoid killing GNU Chess */ EngineOutputPopUp(); } - if (!appData.icsEngineAnalyze) gameMode = AnalyzeMode; + if (!appData.icsEngineAnalyze) { + gameMode = AnalyzeMode; + ClearEngineOutputPane(0); // [TK] exclude: to print exclusion/multipv header + } pausing = FALSE; ModeHighlight(); SetGameInfo(); @@ -17640,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 ) @@ -17748,7 +17756,7 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) Boolean ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) { - int i, j, k, w=0; + int i, j, k, w=0, subst=0, shuffle=0; char *p, c; int emptycount, virgin[BOARD_FILES]; ChessSquare piece; @@ -17787,6 +17795,16 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) if (j + emptycount > gameInfo.boardWidth) return FALSE; while (emptycount--) board[i][(j++)+gameInfo.holdingsWidth] = EmptySquare; + } else if (*p == '<') { + if(i == BOARD_HEIGHT-1) shuffle = 1; + else if (i != 0 || !shuffle) return FALSE; + p++; + } else if (shuffle && *p == '>') { + p++; // for now ignore closing shuffle range, and assume rank-end + } else if (*p == '?') { + if (j >= gameInfo.boardWidth) return FALSE; + if (i != 0 && i != BOARD_HEIGHT-1) return FALSE; // only on back-rank + board[i][(j++)+gameInfo.holdingsWidth] = ClearBoard; p++; subst++; // placeHolder } else if (*p == '+' || isalpha(*p)) { if (j >= gameInfo.boardWidth) return FALSE; if(*p=='+') { @@ -17825,7 +17843,9 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) /* [HGM] look for Crazyhouse holdings here */ while(*p==' ') p++; if( gameInfo.holdingsWidth && p[-1] == '/' || *p == '[') { + int swap=0, wcnt=0, bcnt=0; if(*p == '[') p++; + if(*p == '<') swap++, p++; if(*p == '-' ) p++; /* empty holdings */ else { if( !gameInfo.holdingsWidth ) return FALSE; /* no room to put holdings! */ /* if we would allow FEN reading to set board size, we would */ @@ -17838,18 +17858,46 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) if( i >= gameInfo.holdingsSize ) return FALSE; board[BOARD_HEIGHT-1-i][0] = piece; /* black holdings */ board[BOARD_HEIGHT-1-i][1]++; /* black counts */ + bcnt++; } else { i = (int)piece - (int)WhitePawn; i = PieceToNumber((ChessSquare)i); if( i >= gameInfo.holdingsSize ) return FALSE; board[i][BOARD_WIDTH-1] = piece; /* white holdings */ board[i][BOARD_WIDTH-2]++; /* black holdings */ + wcnt++; + } + } + if(subst) { // substitute back-rank question marks by holdings pieces + for(j=BOARD_LEFT; j= bcnt) n = rand() % bcnt; // use same randomization for black and white if possible + for(k=0, m=n; k= 'A' && *p <= 'Z' || *p >= 'a' && *p <= 'z' || *p=='-') { /* castling indicator present, so default becomes no castlings */ @@ -17898,7 +17947,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) } } while(*p=='K' || *p=='Q' || *p=='k' || *p=='q' || *p=='-' || - (gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom || gameInfo.variant == VariantSChess) && + (appData.fischerCastling || gameInfo.variant == VariantSChess) && ( *p >= 'a' && *p < 'a' + gameInfo.boardWidth) || ( *p >= 'A' && *p < 'A' + gameInfo.boardWidth) ) { int c = *p++, whiteKingFile=NoRights, blackKingFile=NoRights; @@ -17920,6 +17969,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) board[CASTLING][2] = whiteKingFile; if(board[CASTLING][0] != NoRights) virgin[board[CASTLING][0]] |= VIRGIN_W; if(board[CASTLING][2] != NoRights) virgin[board[CASTLING][2]] |= VIRGIN_W; + if(whiteKingFile != BOARD_WIDTH>>1|| i != BOARD_RGHT-1) fischer = 1; break; case'Q': for(i=BOARD_LEFT; i>1|| i != BOARD_LEFT) fischer = 1; break; case'k': for(i=BOARD_RGHT-1; board[BOARD_HEIGHT-1][i]!=BlackRook && i>blackKingFile; i--); @@ -17934,6 +17985,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) board[CASTLING][5] = blackKingFile; if(board[CASTLING][3] != NoRights) virgin[board[CASTLING][3]] |= VIRGIN_B; if(board[CASTLING][5] != NoRights) virgin[board[CASTLING][5]] |= VIRGIN_B; + if(blackKingFile != BOARD_WIDTH>>1|| i != BOARD_RGHT-1) fischer = 1; break; case'q': for(i=BOARD_LEFT; i>1|| i != BOARD_LEFT) fischer = 1; case '-': break; default: /* FRC castlings */ @@ -17974,7 +18027,9 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) } for(i=0; i