#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 (
ChessMove lastLoadGameStart = EndOfFile;
int doubleClick;
Boolean addToBookFlag;
+static Board rightsBoard, nullBoard;
void
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) {
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;
}
flashing = 1; // prevent recursive calling (by release of to-click) while flashing piece
UserMoveEvent(fromX, fromY, toX, toY, promoChoice);
if (!appData.highlightLastMove || gotPremove) ClearHighlights();
- if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
+ if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY), DrawPosition(FALSE, NULL);
if(saveAnimate && !appData.animate && currentMove != oldMove && // drag-move was performed
Explode(boards[currentMove-1], fromX, fromY, toX, toY))
DrawPosition(TRUE, boards[currentMove]);
if(initPing == cps->lastPong) {
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;
} 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;
} 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;
} 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;
} 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;
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);
}
SetGameInfo();
}
-
void
EditPositionEvent ()
{
+ int i;
if (gameMode == EditPosition) {
EditGameEvent();
return;
gameMode = EditPosition;
ModeHighlight();
SetGameInfo();
+ CopyBoard(rightsBoard, nullBoard);
if (currentMove > 0)
CopyBoard(boards[0], boards[currentMove]);
+ for(i=0; i<nrCastlingRights; i++) if(boards[0][CASTLING][i] != NoRights)
+ rightsBoard[castlingRank[i]][boards[0][CASTLING][i]] = 1; // copy remaining rights
blackPlaysFirst = !WhiteOnMove(currentMove);
ResetClocks();
startedFromSetupPosition = TRUE;
InitChessProgram(&first, FALSE);
if(fakeRights) { // [HGM] suppress this if we just pasted a FEN.
+ int r, f;
boards[0][EP_STATUS] = EP_NONE;
- boards[0][CASTLING][2] = boards[0][CASTLING][5] = BOARD_WIDTH>>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<BOARD_RGHT; i++) { // pieces in their original position are assumed virgin
- boards[0][VIRGIN][i] = 0;
- if(boards[0][0][i] == FIDEArray[0][i-BOARD_LEFT]) boards[0][VIRGIN][i] |= VIRGIN_W;
- if(boards[0][BOARD_HEIGHT-1][i] == FIDEArray[1][i-BOARD_LEFT]) boards[0][VIRGIN][i] |= VIRGIN_B;
+ for(f=0; f<=nrCastlingRights; f++) boards[0][CASTLING][f] = NoRights;
+ for(r=BOARD_HEIGHT-1; r>=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;
}
}
}
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;
}
}
}
+ 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
} else
CopyBoard(erasedBoard, currentBoard);
+ for(i=0; i<nrCastlingRights; i++) if(boards[0][CASTLING][i] != NoRights)
+ rightsBoard[castlingRank[i]][boards[0][CASTLING][i]] = 1; // copy remaining rights
}
}
if (gameMode == EditPosition) {
selection = (ChessSquare)((int)selection - (int)WhiteQueen + (int)WhiteFerz);
goto defaultlabel;
+ case WhiteRook:
+ baseRank = 0;
+ case BlackRook:
+ if(y == baseRank && (x == BOARD_LEFT || x == BOARD_RGHT-1 || appData.fischerCastling)) hasRights = 1;
+ if(y == baseRank && (x == BOARD_WIDTH>>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) {
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) {
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;
}
}
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;