X-Git-Url: http://winboard.nl/cgi-bin?p=xboard.git;a=blobdiff_plain;f=backend.c;h=0c12671053242c27c3da450913f2f8add05038cc;hp=d879de7108642b7fc957bdc8cbf144174fa803b2;hb=d0955e6b0d0f5a00a65ed05a14fd8fa73121ab3c;hpb=fc59a21875f42703ed57bc69f44a48bcee2f89ec diff --git a/backend.c b/backend.c index d879de7..0c12671 100644 --- a/backend.c +++ b/backend.c @@ -261,6 +261,7 @@ void ics_update_width P((int new_width)); extern char installDir[MSG_SIZ]; VariantClass startVariant; /* [HGM] nicks: initial variant */ Boolean abortMatch; +int deadRanks; extern int tinyLayout, smallLayout; ChessProgramStats programStats; @@ -564,8 +565,8 @@ ChessSquare KnightmateArray[2][BOARD_FILES] = { ChessSquare SpartanArray[2][BOARD_FILES] = { { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen, WhiteKing, WhiteBishop, WhiteKnight, WhiteRook }, - { BlackAlfil, BlackMarshall, BlackKing, BlackDragon, - BlackDragon, BlackKing, BlackAngel, BlackAlfil } + { BlackAlfil, BlackDragon, BlackKing, BlackTower, + BlackTower, BlackKing, BlackAngel, BlackAlfil } }; ChessSquare fairyArray[2][BOARD_FILES] = { /* [HGM] Queen side differs from King side */ @@ -691,18 +692,18 @@ ChessSquare CourierArray[2][BOARD_FILES] = { BlackFerz, BlackWazir, BlackBishop, BlackAlfil, BlackKnight, BlackRook } }; ChessSquare ChuArray[6][BOARD_FILES] = { - { WhiteLance, WhiteUnicorn, WhiteMan, WhiteFerz, WhiteWazir, WhiteKing, - WhiteAlfil, WhiteWazir, WhiteFerz, WhiteMan, WhiteUnicorn, WhiteLance }, - { BlackLance, BlackUnicorn, BlackMan, BlackFerz, BlackWazir, BlackAlfil, - BlackKing, BlackWazir, BlackFerz, BlackMan, BlackUnicorn, BlackLance }, - { WhiteCannon, EmptySquare, WhiteBishop, EmptySquare, WhiteNightrider, WhiteMarshall, - WhiteAngel, WhiteNightrider, EmptySquare, WhiteBishop, EmptySquare, WhiteCannon }, - { BlackCannon, EmptySquare, BlackBishop, EmptySquare, BlackNightrider, BlackAngel, - BlackMarshall, BlackNightrider, EmptySquare, BlackBishop, EmptySquare, BlackCannon }, - { WhiteFalcon, WhiteSilver, WhiteRook, WhiteCardinal, WhiteDragon, WhiteLion, - WhiteQueen, WhiteDragon, WhiteCardinal, WhiteRook, WhiteSilver, WhiteFalcon }, - { BlackFalcon, BlackSilver, BlackRook, BlackCardinal, BlackDragon, BlackQueen, - BlackLion, BlackDragon, BlackCardinal, BlackRook, BlackSilver, BlackFalcon } + { WhiteLance, WhiteCat, WhiteCopper, WhiteFerz, WhiteWazir, WhiteKing, + WhiteAlfil, WhiteWazir, WhiteFerz, WhiteCopper, WhiteCat, WhiteLance }, + { BlackLance, BlackCat, BlackCopper, BlackFerz, BlackWazir, BlackAlfil, + BlackKing, BlackWazir, BlackFerz, BlackCopper, BlackCat, BlackLance }, + { WhiteAxe, EmptySquare, WhiteBishop, EmptySquare, WhiteClaw, WhiteMarshall, + WhiteAngel, WhiteClaw, EmptySquare, WhiteBishop, EmptySquare, WhiteAxe }, + { BlackAxe, EmptySquare, BlackBishop, EmptySquare, BlackClaw, BlackAngel, + BlackMarshall, BlackClaw, EmptySquare, BlackBishop, EmptySquare, BlackAxe }, + { WhiteDagger, WhiteSword, WhiteRook, WhiteCardinal, WhiteDragon, WhiteLion, + WhiteQueen, WhiteDragon, WhiteCardinal, WhiteRook, WhiteSword, WhiteDagger }, + { BlackDagger, BlackSword, BlackRook, BlackCardinal, BlackDragon, BlackQueen, + BlackLion, BlackDragon, BlackCardinal, BlackRook, BlackSword, BlackDagger } }; #else // !(BOARD_FILES>=12) #define CourierArray CapablancaArray @@ -3395,7 +3396,8 @@ read_from_ics (InputSourceRef isr, VOIDSTAR closure, char *data, int count, int #if ZIPPY if (loggedOn == TRUE) if (ZippyControl(buf, &backup) || ZippyConverse(buf, &backup) || - (appData.zippyPlay && ZippyMatch(buf, &backup))); + (appData.zippyPlay && ZippyMatch(buf, &backup))) + ; #endif } // [DM] 'else { ' deleted if ( @@ -5161,14 +5163,14 @@ SendMoveToProgram (int moveNum, ChessProgramState *cps) if(moveList[moveNum][4] == ';') { // [HGM] lion: move is double-step over intermediate square char *m = moveList[moveNum]; static char c[2]; - *c = m[7]; // promoChar + *c = m[7]; if(*c == '\n') *c = NULLCHAR; // promoChar if((boards[moveNum][m[6]-ONE][m[5]-AAA] < BlackPawn) == (boards[moveNum][m[1]-ONE][m[0]-AAA] < BlackPawn)) // move is kludge to indicate castling snprintf(buf, MSG_SIZ, "%c%d%c%d,%c%d%c%d\n", m[0], m[1] - '0', // convert to two moves 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 - *c = m[9]; + *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', m[7], m[8] - '0', @@ -6279,8 +6281,10 @@ InitPosition (int redraw) gameInfo.boardWidth = 12; gameInfo.boardHeight = 12; nrCastlingRights = 0; - SetCharTableEsc(pieceToChar, "P.BRQSEXOGCATHD.VMLIFN.........^T..^L......^A^H/^F^G^M.^E^X^O^I.^P.^B^R..^D^S^C^VK" - "p.brqsexogcathd.vmlifn.........^t..^l......^a^h/^f^g^m.^e^x^o^i.^p.^b^r..^d^s^c^vk", SUFFIXES); +// SetCharTableEsc(pieceToChar, "P.BRQSEXOGCATHD.VMLIFN.........^T..^L......^A^H/^F^G^M.^E^X^O^I.^P.^B^R..^D^S^C^VK" + // "p.brqsexogcathd.vmlifn.........^t..^l......^a^h/^f^g^m.^e^x^o^i.^p.^b^r..^d^s^c^vk", SUFFIXES); + SetCharTableEsc(pieceToChar, "P.BRQSEXOG...HD..^DLI^HNV........^T..^L.C...A^AFT/^F^G^M.^E^X^O^I.^P.^B^R..M^S^C^VK" + "p.brqsexog...hd..^dli^hnv........^t..^l.c...a^aft/^f^g^m.^e^x^o^i.^p.^b^r..m^s^c^vk", SUFFIXES); break; case VariantCourier: pieces = CourierArray; @@ -6294,7 +6298,7 @@ InitPosition (int redraw) break; case VariantSpartan: pieces = SpartanArray; - SetCharTable(pieceToChar, "PNBRQ................K......lwg.....c...h..k"); + SetCharTable(pieceToChar, "PNBRQ.....................K......lw......g...h......ck"); break; case VariantLion: pieces = lionArray; @@ -6982,6 +6986,7 @@ char lastLoadGameTitle[MSG_SIZ], lastLoadPositionTitle[MSG_SIZ]; ChessMove lastLoadGameStart = EndOfFile; int doubleClick; Boolean addToBookFlag; +static Board rightsBoard, nullBoard; void UserMoveEvent (int fromX, int fromY, int toX, int toY, int promoChar) @@ -7109,8 +7114,13 @@ UserMoveEvent (int fromX, int fromY, int toX, int toY, int promoChar) if(!appData.pieceMenu && toX == fromX && toY == fromY && boards[0][rf][ff] != EmptySquare) { ChessSquare p = boards[0][rf][ff]; if(PieceToChar(p) == '+') gatingPiece = CHUDEMOTED(p); else - if(PieceToChar(CHUPROMOTED(p)) =='+') gatingPiece = CHUPROMOTED(p); - } + if(PieceToChar(CHUPROMOTED(p)) =='+') gatingPiece = CHUPROMOTED(p); else + if(p == WhiteKing || p == BlackKing || p == WhiteRook || p == BlackRook || p == WhitePawn || p == BlackPawn) { + int n = rightsBoard[toY][toX] ^= 1; // toggle virginity of K or R + DisplayMessage("", n ? _("rights granted") : _("rights revoked")); + gatingPiece = p; + } + } else rightsBoard[toY][toX] = 0; // revoke rights on moving boards[0][toY][toX] = boards[0][fromY][fromX]; if(fromX == BOARD_LEFT-2) { // handle 'moves' out of holdings if(boards[0][fromY][0] != EmptySquare) { @@ -7168,6 +7178,7 @@ UserMoveEvent (int fromX, int fromY, int toX, int toY, int promoChar) if(ExcludeOneMove(fromY, fromX, toY, toX, promoChar, '*')) // toggle ClearPremoveHighlights(); // was included else ClearHighlights(), SetPremoveHighlights(ff, rf, ft, rt); // exclusion indicated by premove highlights + DrawPosition(FALSE, NULL); return; } @@ -7387,7 +7398,7 @@ MarkByFEN(char *fen) int r, f; if(!appData.markers || !appData.highlightDragging) return; for(r=0; rlastPong) { if(gameInfo.variant == VariantUnknown) { DisplayError(_("Engine did not send setup for non-standard variant"), 0); - *engineVariant = NULLCHAR; appData.variant = VariantNormal; // back to normal as error recovery? + *engineVariant = NULLCHAR; ASSIGN(appData.variant, "normal"); // back to normal as error recovery? GameEnds(GameUnfinished, NULL, GE_XBOARD); } initPing = -1; @@ -10316,7 +10332,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX > fromX+1) { - for(rookX=fromX+1; board[toY][rookX] == EmptySquare && rookX < BOARD_RGHT-1; rookX++); // castle with nearest piece + for(rookX=fromX+1; board[toY][rookX] == EmptySquare && rookX < BOARD_RGHT-1; rookX++) + ; // castle with nearest piece board[fromY][toX-1] = board[fromY][rookX]; board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; @@ -10324,7 +10341,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX < fromX-1) { - for(rookX=fromX-1; board[toY][rookX] == EmptySquare && rookX > 0; rookX--); // castle with nearest piece + for(rookX=fromX-1; board[toY][rookX] == EmptySquare && rookX > 0; rookX--) + ; // castle with nearest piece board[fromY][toX+1] = board[fromY][rookX]; board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; @@ -10367,7 +10385,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX > fromX+1) { - for(rookX=toX+1; board[toY][rookX] == EmptySquare && rookX < BOARD_RGHT - 1; rookX++); + for(rookX=toX+1; board[toY][rookX] == EmptySquare && rookX < BOARD_RGHT - 1; rookX++) + ; board[fromY][toX-1] = board[fromY][rookX]; board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; @@ -10375,7 +10394,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX < fromX-1) { - for(rookX=toX-1; board[toY][rookX] == EmptySquare && rookX > 0; rookX--); + for(rookX=toX-1; board[toY][rookX] == EmptySquare && rookX > 0; rookX--) + ; board[fromY][toX+1] = board[fromY][rookX]; board[fromY][rookX] = EmptySquare; board[fromY][fromX] = EmptySquare; @@ -11070,8 +11090,10 @@ Substitute (char *participants, int expunge) p++; q++; } if(*p) { // difference - while(*p && *p++ != '\n'); - while(*q && *q++ != '\n'); + while(*p && *p++ != '\n') + ; + while(*q && *q++ != '\n') + ; changed = nPlayers; changes = 1 + (strcmp(p, q) != 0); } @@ -11998,6 +12020,7 @@ Reset (int redraw, int init) redraw, init, gameMode); } pieceDefs = FALSE; // [HGM] gen: reset engine-defined piece moves + deadRanks = 0; // assume entire board is used for(i=0; i= 0 ? "+" : "", pvInfoList[i].score / 100.0, @@ -15285,10 +15312,10 @@ EditGameEvent () SetGameInfo(); } - void EditPositionEvent () { + int i; if (gameMode == EditPosition) { EditGameEvent(); return; @@ -15300,8 +15327,11 @@ EditPositionEvent () gameMode = EditPosition; ModeHighlight(); SetGameInfo(); + CopyBoard(rightsBoard, nullBoard); if (currentMove > 0) CopyBoard(boards[0], boards[currentMove]); + for(i=0; i>1; - if(boards[0][0][BOARD_WIDTH>>1] == king) { - boards[0][CASTLING][1] = boards[0][0][BOARD_LEFT] == WhiteRook ? BOARD_LEFT : NoRights; - boards[0][CASTLING][0] = boards[0][0][BOARD_RGHT-1] == WhiteRook ? BOARD_RGHT-1 : NoRights; - } else boards[0][CASTLING][2] = NoRights; - if(boards[0][BOARD_HEIGHT-1][BOARD_WIDTH>>1] == WHITE_TO_BLACK king) { - boards[0][CASTLING][4] = boards[0][BOARD_HEIGHT-1][BOARD_LEFT] == BlackRook ? BOARD_LEFT : NoRights; - boards[0][CASTLING][3] = boards[0][BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook ? BOARD_RGHT-1 : NoRights; - } else boards[0][CASTLING][5] = NoRights; - if(gameInfo.variant == VariantSChess) { - int i; - for(i=BOARD_LEFT; i=0; r--) for(f=BOARD_RGHT-1; f>=BOARD_LEFT; f--) { // first pass: Kings & e.p. + if(rightsBoard[r][f]) { + ChessSquare p = boards[0][r][f]; + if(p == (blackPlaysFirst ? WhitePawn : BlackPawn)) boards[0][EP_STATUS] = f; + else if(p == king) boards[0][CASTLING][2] = f; + else if(p == WHITE_TO_BLACK king) boards[0][CASTLING][5] = f; + else rightsBoard[r][f] = 2; // mark for second pass + } + } + for(r=BOARD_HEIGHT-1; r>=0; r--) for(f=BOARD_RGHT-1; f>=BOARD_LEFT; f--) { // second pass: Rooks + if(rightsBoard[r][f] == 2) { + ChessSquare p = boards[0][r][f]; + if(p == WhiteRook) boards[0][CASTLING][(f < boards[0][CASTLING][2])] = f; else + if(p == BlackRook) boards[0][CASTLING][(f < boards[0][CASTLING][5])+3] = f; } } } @@ -15449,6 +15480,7 @@ EditPositionMenuEvent (ChessSquare selection, int x, int y) ChessSquare piece = boards[0][y][x]; static Board erasedBoard, currentBoard, menuBoard, nullBoard; static int lastVariant; + int baseRank = BOARD_HEIGHT-1, hasRights = 0; if (gameMode != EditPosition && gameMode != IcsExamining) return; @@ -15481,14 +15513,16 @@ EditPositionMenuEvent (ChessSquare selection, int x, int y) } } } + CopyBoard(rightsBoard, nullBoard); if(gameMode != IcsExamining) { // [HGM] editpos: cycle trough boards - int r; + int r, i; for(r = 0; r < BOARD_HEIGHT; r++) { for(x = BOARD_LEFT; x < BOARD_RGHT; x++) { // create 'menu board' by removing duplicates ChessSquare p = menuBoard[r][x]; for(y = x + 1; y < BOARD_RGHT; y++) if(menuBoard[r][y] == p) menuBoard[r][y] = EmptySquare; } } + menuBoard[CASTLING][0] = menuBoard[CASTLING][3] = NoRights; // h-side Rook was deleted DisplayMessage("Clicking clock again restores position", ""); if(gameInfo.variant != lastVariant) lastVariant = gameInfo.variant, CopyBoard(erasedBoard, boards[0]); if(!nonEmpty) { // asked to clear an empty board @@ -15503,6 +15537,8 @@ EditPositionMenuEvent (ChessSquare selection, int x, int y) } else CopyBoard(erasedBoard, currentBoard); + for(i=0; i>1 || appData.fischerCastling)) hasRights = 1; + goto defaultlabel; + case WhiteKing: + baseRank = 0; case BlackKing: if(gameInfo.variant == VariantXiangqi) selection = (ChessSquare)((int)selection - (int)WhiteKing + (int)WhiteWazir); if(gameInfo.variant == VariantKnightmate) selection = (ChessSquare)((int)selection - (int)WhiteKing + (int)WhiteUnicorn); + if(y == baseRank && (x == BOARD_WIDTH>>1 || appData.fischerCastling)) hasRights = 1; default: defaultlabel: if (gameMode == IcsExamining) { @@ -15579,6 +15624,7 @@ EditPositionMenuEvent (ChessSquare selection, int x, int y) PieceToChar(selection), AAA + x, ONE + y); SendToICS(buf); } else { + rightsBoard[y][x] = hasRights; if(x < BOARD_LEFT || x >= BOARD_RGHT) { int n; if(x == BOARD_LEFT-2 && selection >= BlackPawn) { @@ -16778,7 +16824,11 @@ GetInfoFromComment (int index, char * text) pvInfoList[index-1].score = score; pvInfoList[index-1].time = 10*time; // centi-sec if(*sep == '}') *sep = 0; else *--sep = '{'; - if(p != text) { while(*p++ = *sep++); sep = text; } // squeeze out space between PV and comment, and return both + if(p != text) { + while(*p++ = *sep++) + ; + sep = text; + } // squeeze out space between PV and comment, and return both } return sep; } @@ -17766,11 +17816,13 @@ ResetClocks () #define FUDGE 25 /* 25ms = 1/40 sec; should be plenty even for 50 Hz clocks */ +static int timeSuffix; // [HGM] This should realy be a passed parameter, but it has to pass through too many levels for my laziness... + /* Decrement running clock by amount of time that has passed */ void DecrementClocks () { - long timeRemaining; + long tRemaining; long lastTickLength, fudge; TimeMark now; @@ -17787,28 +17839,32 @@ DecrementClocks () if (WhiteOnMove(forwardMostMove)) { if(whiteNPS >= 0) lastTickLength = 0; - timeRemaining = whiteTimeRemaining -= lastTickLength; - if(timeRemaining < 0 && !appData.icsActive) { + tRemaining = whiteTimeRemaining -= lastTickLength; + if( tRemaining < 0 && !appData.icsActive) { GetTimeQuota((forwardMostMove-whiteStartMove-1)/2, 0, whiteTC); // sets suddenDeath & nextSession; if(suddenDeath) { // [HGM] if we run out of a non-last incremental session, go to the next whiteStartMove = forwardMostMove; whiteTC = nextSession; - lastWhite= timeRemaining = whiteTimeRemaining += GetTimeQuota(-1, 0, whiteTC); + lastWhite= tRemaining = whiteTimeRemaining += GetTimeQuota(-1, 0, whiteTC); } } + if(forwardMostMove && appData.moveTime) timeSuffix = timeRemaining[0][forwardMostMove-1] - tRemaining; DisplayWhiteClock(whiteTimeRemaining - fudge, WhiteOnMove(currentMove < forwardMostMove ? currentMove : forwardMostMove)); + timeSuffix = 0; } else { if(blackNPS >= 0) lastTickLength = 0; - timeRemaining = blackTimeRemaining -= lastTickLength; - if(timeRemaining < 0 && !appData.icsActive) { // [HGM] if we run out of a non-last incremental session, go to the next + tRemaining = blackTimeRemaining -= lastTickLength; + if( tRemaining < 0 && !appData.icsActive) { // [HGM] if we run out of a non-last incremental session, go to the next GetTimeQuota((forwardMostMove-blackStartMove-1)/2, 0, blackTC); if(suddenDeath) { blackStartMove = forwardMostMove; - lastBlack = timeRemaining = blackTimeRemaining += GetTimeQuota(-1, 0, blackTC=nextSession); + lastBlack = tRemaining = blackTimeRemaining += GetTimeQuota(-1, 0, blackTC=nextSession); } } + if(forwardMostMove && appData.moveTime) timeSuffix = timeRemaining[1][forwardMostMove-1] - tRemaining; DisplayBlackClock(blackTimeRemaining - fudge, !WhiteOnMove(currentMove < forwardMostMove ? currentMove : forwardMostMove)); + timeSuffix = 0; } if (CheckFlags()) return; @@ -17823,7 +17879,7 @@ DecrementClocks () } tickStartTM = now; - intendedTickLength = NextTickLength(timeRemaining - fudge) + fudge; + intendedTickLength = NextTickLength( tRemaining - fudge) + fudge; StartClockTimer(intendedTickLength); /* if the time remaining has fallen below the alarm threshold, sound the @@ -17839,9 +17895,9 @@ DecrementClocks () ((gameMode == IcsPlayingBlack) && !WhiteOnMove(currentMove)) )) return; - if (alarmSounded && (timeRemaining > appData.icsAlarmTime)) { + if (alarmSounded && ( tRemaining > appData.icsAlarmTime)) { alarmSounded = FALSE; - } else if (!alarmSounded && (timeRemaining <= appData.icsAlarmTime)) { + } else if (!alarmSounded && ( tRemaining <= appData.icsAlarmTime)) { PlayAlarmSound(); alarmSounded = TRUE; } @@ -17982,7 +18038,7 @@ TimeString (long ms) { long second, minute, hour, day; char *sign = ""; - static char buf[32]; + static char buf[40], moveTime[8]; if (ms > 0 && ms <= 9900) { /* convert milliseconds to tenths, rounding up */ @@ -18009,13 +18065,16 @@ TimeString (long ms) minute = second / 60; second = second % 60; + if(timeSuffix) snprintf(moveTime, 8, " (%d)", timeSuffix/1000); // [HGM] kludge alert; fraction contains move time + else *moveTime = NULLCHAR; + if (day > 0) - snprintf(buf, sizeof(buf)/sizeof(buf[0]), " %s%ld:%02ld:%02ld:%02ld ", - sign, day, hour, minute, second); + snprintf(buf, sizeof(buf)/sizeof(buf[0]), " %s%ld:%02ld:%02ld:%02ld%s ", + sign, day, hour, minute, second, moveTime); else if (hour > 0) - snprintf(buf, sizeof(buf)/sizeof(buf[0]), " %s%ld:%02ld:%02ld ", sign, hour, minute, second); + snprintf(buf, sizeof(buf)/sizeof(buf[0]), " %s%ld:%02ld:%02ld%s ", sign, hour, minute, second, moveTime); else - snprintf(buf, sizeof(buf)/sizeof(buf[0]), " %s%2ld:%02ld ", sign, minute, second); + snprintf(buf, sizeof(buf)/sizeof(buf[0]), " %s%2ld:%02ld%s ", sign, minute, second, moveTime); return buf; } @@ -18140,7 +18199,7 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) p = buf; /* Piece placement data */ - for (i = BOARD_HEIGHT - 1; i >= 0; i--) { + for (i = BOARD_HEIGHT - 1 - deadRanks; i >= 0; i--) { if(MSG_SIZ - (p - buf) < BOARD_RGHT - BOARD_LEFT + 20) { *p = 0; return StrSave(buf); } emptycount = 0; for (j = BOARD_LEFT; j < BOARD_RGHT; j++) { @@ -18222,7 +18281,9 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) } if(q = overrideCastling) { // [HGM] FRC: override castling & e.p fields for non-compliant engines - while(*p++ = *q++); if(q != overrideCastling+1) p[-1] = ' '; else --p; + while(*p++ = *q++) + ; + if(q != overrideCastling+1) p[-1] = ' '; else --p; } else { if(haveRights) { int handW=0, handB=0; @@ -18354,8 +18415,10 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) p = fen; + for(i=1; i<=deadRanks; i++) for(j=BOARD_LEFT; j= 0; i--) { + for (i = BOARD_HEIGHT - 1 - deadRanks; i >= 0; i--) { j = 0; for (;;) { if (*p == '/' || *p == ' ' || *p == '[' ) {