int promoDefaultAltered;
int keepInfo = 0; /* [HGM] to protect PGN tags in auto-step game analysis */
static int initPing = -1;
-static Boolean pieceDefs;
+int border; /* [HGM] width of board rim, needed to size seek graph */
/* States for ics_getting_history */
#define H_FALSE 0
{
int i;
if(!seekGraphUp) return FALSE;
- h = BOARD_HEIGHT * (squareSize + lineGap) + lineGap;
- w = BOARD_WIDTH * (squareSize + lineGap) + lineGap;
+ h = BOARD_HEIGHT * (squareSize + lineGap) + lineGap + 2*border;
+ w = BOARD_WIDTH * (squareSize + lineGap) + lineGap + 2*border;
DrawSeekBackground(0, 0, w, h);
DrawSeekAxis(hMargin, h-1-vMargin, w-5, h-1-vMargin);
gameInfo.boardHeight = 8;
gameInfo.holdingsSize = 0;
nrCastlingRights = -1; /* [HGM] Kludge to indicate default should be used */
- for(i=0; i<BOARD_FILES-2; i++)
+ for(i=0; i<BOARD_FILES-6; i++)
initialPosition[CASTLING][i] = initialRights[i] = NoRights; /* but no rights yet */
initialPosition[EP_STATUS] = EP_NONE;
+ initialPosition[TOUCHED_W] = initialPosition[TOUCHED_B] = 0;
SetCharTable(pieceToChar, "PNBRQ...........Kpnbrq...........k");
if(startVariant == gameInfo.variant) // [HGM] nicks: enable nicknames in original variant
SetCharTable(pieceNickName, appData.pieceNickNames);
char buf[MSG_SIZ]; // Inform engine of what user does
int r, f;
if(action[0] == 'l') // mark any target square of a lifted piece as legal to-square, clear markers
- for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) legal[r][f] = !pieceDefs, marker[r][f] = 0;
+ for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++)
+ legal[r][f] = !pieceDefs || !appData.markers, marker[r][f] = 0;
if(!first.highlight || gameMode == EditPosition) return;
snprintf(buf, MSG_SIZ, "%s %c%d%s\n", action, x+AAA, y+ONE-'0', controlKey && action[0]=='p' ? "," : "");
SendToProgram(buf, &first);
if(sscanf(message, "piece %s %s", buf2, buf1) == 2) {
ChessSquare piece = WhitePawn;
char *p=buf2;
- if(cps != &first || appData.testLegality) return;
+ if(cps != &first || appData.testLegality && *engineVariant == NULLCHAR
+ /* For variants we don't have */ && gameInfo.variant != VariantBerolina
+ /* correct rules for, we cannot */ && gameInfo.variant != VariantCylinder
+ /* enforce legality on our own! */ && gameInfo.variant != VariantUnknown
+ && gameInfo.variant != VariantFairy ) return;
if(*p == '+') piece = CHUPROMOTED WhitePawn, p++;
piece += CharToPiece(*p) - WhitePawn;
if(piece < EmptySquare) {
if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A;
oldEP = (signed char)board[EP_STATUS];
board[EP_STATUS] = EP_NONE;
+ board[EP_FILE] = board[EP_RANK] = 100;
if (fromY == DROP_RANK) {
/* must be first */
if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers
board[EP_STATUS] = EP_PAWN_MOVE;
if( toY-fromY==2) {
+ board[EP_FILE] = (fromX + toX)/2; board[EP_RANK] = (fromY + toY)/2;
if(toX>BOARD_LEFT && board[toY][toX-1] == BlackPawn &&
gameInfo.variant != VariantBerolina || toX < fromX)
board[EP_STATUS] = toX | berolina;
if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers
board[EP_STATUS] = EP_PAWN_MOVE;
if( toY-fromY== -2) {
+ board[EP_FILE] = (fromX + toX)/2; board[EP_RANK] = (fromY + toY)/2;
if(toX>BOARD_LEFT && board[toY][toX-1] == WhitePawn &&
gameInfo.variant != VariantBerolina || toX < fromX)
board[EP_STATUS] = toX | berolina;
}
}
+ if(fromY == 0) board[TOUCHED_W] |= 1<<fromX; else // new way to keep track of virginity
+ if(fromY == BOARD_HEIGHT-1) board[TOUCHED_B] |= 1<<fromX;
+ if(toY == 0) board[TOUCHED_W] |= 1<<toX; else
+ if(toY == BOARD_HEIGHT-1) board[TOUCHED_B] |= 1<<toX;
+
for(i=0; i<nrCastlingRights; i++) {
if(board[CASTLING][i] == fromX && castlingRank[i] == fromY ||
board[CASTLING][i] == toX && castlingRank[i] == toY
/* FRC castling assumed when king captures friendly rook. [HGM] or RxK for S-Chess */
if (board[fromY][fromX] == WhiteKing && board[toY][toX] == WhiteRook ||
board[fromY][fromX] == WhiteRook && board[toY][toX] == WhiteKing) {
+ board[EP_STATUS] = EP_NONE; // capture was fake!
board[fromY][fromX] = EmptySquare;
board[toY][toX] = EmptySquare;
if((toX > fromX) != (piece == WhiteRook)) {
}
} else if (board[fromY][fromX] == BlackKing && board[toY][toX] == BlackRook ||
board[fromY][fromX] == BlackRook && board[toY][toX] == BlackKing) {
+ board[EP_STATUS] = EP_NONE;
board[fromY][fromX] = EmptySquare;
board[toY][toX] = EmptySquare;
if((toX > fromX) != (piece == BlackRook)) {
board[toY][toX] = (ChessSquare) (PROMOTED board[toY][toX]);
board[fromY][fromX] = EmptySquare;
} else if ((fromY >= BOARD_HEIGHT>>1)
- && (oldEP == toX || oldEP == EP_UNKNOWN || appData.testLegality)
+ && (oldEP == toX || oldEP == EP_UNKNOWN || appData.testLegality || abs(toX - fromX) > 4)
&& (toX != fromX)
&& gameInfo.variant != VariantXiangqi
&& gameInfo.variant != VariantBerolina
board[toY][toX] = (ChessSquare) (PROMOTED board[toY][toX]);
board[fromY][fromX] = EmptySquare;
} else if ((fromY < BOARD_HEIGHT>>1)
- && (oldEP == toX || oldEP == EP_UNKNOWN || appData.testLegality)
+ && (oldEP == toX || oldEP == EP_UNKNOWN || appData.testLegality || abs(toX - fromX) > 4)
&& (toX != fromX)
&& gameInfo.variant != VariantXiangqi
&& gameInfo.variant != VariantBerolina
b = SupportedVariant(cps->variants, gameInfo.variant, gameInfo.boardWidth,
gameInfo.boardHeight, gameInfo.holdingsSize, cps->protocolVersion, cps->tidy);
if (b == NULL) {
- DisplayFatalError(variantError, 0, 1);
+ VariantClass v;
+ char c, *q = cps->variants, *p = strchr(q, ',');
+ if(p) *p = NULLCHAR;
+ v = StringToVariant(q);
+ DisplayError(variantError, 0);
+ if(v != VariantUnknown && cps == &first) {
+ int w, h, s;
+ if(sscanf(q, "%dx%d+%d_%c", &w, &h, &s, &c) == 4) // get size overrides the engine needs with it (if any)
+ appData.NrFiles = w, appData.NrRanks = h, appData.holdingsSize = s, q = strchr(q, '_') + 1;
+ ASSIGN(appData.variant, q);
+ Reset(TRUE, FALSE);
+ }
+ if(p) *p = ',';
return;
}
if(!SupportedVariant(second.variants, gameInfo.variant, gameInfo.boardWidth,
gameInfo.boardHeight, gameInfo.holdingsSize, second.protocolVersion, second.tidy)) {
- startingEngine = FALSE;
+ startingEngine = matchMode = FALSE;
DisplayError("second engine does not play this", 0);
+ gameMode = TwoMachinesPlay; ModeHighlight(); // Needed to make sure menu item is unchecked
+ EditGameEvent(); // switch back to EditGame mode
return;
}