extern char installDir[MSG_SIZ];
VariantClass startVariant; /* [HGM] nicks: initial variant */
Boolean abortMatch;
-int deadRanks;
+int deadRanks, handSize;
extern int tinyLayout, smallLayout;
ChessProgramStats programStats;
q = firstChessProgramNames;
if(nickName[0]) snprintf(buf, MSG_SIZ, "\"%s\" -fcp ", nickName); else buf[0] = NULLCHAR;
quote = strchr(p, '"') ? '\'' : '"'; // use single quotes around engine command if it contains double quotes
- snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), "%c%s%c -fd \"%s\"%s%s%s%s%s%s%s%s\n",
+ snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), "%c%s%c -fd \"%s\"%s%s%s%s%s%s%s%s",
quote, p, quote, appData.directory[i],
useNick ? " -fn \"" : "",
useNick ? nickName : "",
isUCI ? (isUCI == TRUE ? " -fUCI" : gameInfo.variant == VariantShogi ? " -fUSI" : " -fUCCI") : "",
storeVariant ? " -variant " : "",
storeVariant ? VariantName(gameInfo.variant) : "");
- if(wbOptions && wbOptions[0]) snprintf(buf+strlen(buf)-1, MSG_SIZ-strlen(buf), " %s\n", wbOptions);
- firstChessProgramNames = malloc(len = strlen(q) + strlen(buf) + 1);
+ if(wbOptions && wbOptions[0]) snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " %s", wbOptions);
+ firstChessProgramNames = malloc(len = strlen(q) + strlen(buf) + 2);
if(insert != q) insert[-1] = NULLCHAR;
- snprintf(firstChessProgramNames, len, "%s\n%s%s", q, buf, insert);
+ snprintf(firstChessProgramNames, len, "%s\n%s\n%s", q, buf, insert);
if(q) free(q);
FloatToFront(&appData.recentEngineList, buf);
ASSIGN(currentEngine[i], buf);
NextMatchGame();
}
-char *comboLine = NULL; // [HGM] recent: WinBoard's first-engine combobox line
-
void
InitBackEnd3 P((void))
{
free(programVersion);
programVersion = (char*) malloc(8 + strlen(PACKAGE_STRING) + strlen(first.tidy));
sprintf(programVersion, "%s + %s", PACKAGE_STRING, first.tidy);
- FloatToFront(&appData.recentEngineList, comboLine ? comboLine : appData.firstChessProgram);
+ FloatToFront(&appData.recentEngineList, currentEngine[0] ? currentEngine[0] : appData.firstChessProgram);
}
if (appData.icsActive) {
if( (int)lowestPiece >= BlackPawn ) {
holdingsColumn = 0;
countsColumn = 1;
- holdingsStartRow = BOARD_HEIGHT-1;
+ holdingsStartRow = handSize-1;
direction = -1;
} else {
holdingsColumn = BOARD_WIDTH-1;
direction = 1;
}
- for(i=0; i<BOARD_HEIGHT; i++) { /* clear holdings */
+ for(i=0; i<BOARD_RANKS-1; i++) { /* clear holdings */
board[i][holdingsColumn] = EmptySquare;
board[i][countsColumn] = (ChessSquare) 0;
}
parse, currentMove);
if (sscanf(parse, " game %d", &gamenum) == 1) {
if(gamenum == ics_gamenum) { // [HGM] bughouse: old code if part of foreground game
+ new_piece[0] = NULLCHAR;
+ sscanf(parse, "game %d white [%s black [%s <- %s",
+ &gamenum, white_holding, black_holding,
+ new_piece);
+ white_holding[strlen(white_holding)-1] = NULLCHAR;
+ black_holding[strlen(black_holding)-1] = NULLCHAR;
if (gameInfo.variant == VariantNormal) {
/* [HGM] We seem to switch variant during a game!
* Presumably no holdings were displayed, so we have
switch(gameInfo.boardWidth) { // base guess on board width
case 9: newVariant = VariantShogi; break;
case 10: newVariant = VariantGreat; break;
- default: newVariant = VariantCrazyhouse; break;
+ default: newVariant = VariantCrazyhouse;
+ if(strchr(white_holding, 'E') || strchr(black_holding, 'E') ||
+ strchr(white_holding, 'H') || strchr(black_holding, 'H') )
+ newVariant = VariantSChess;
}
VariantSwitch(boards[currentMove], newVariant); /* temp guess */
/* Get a move list just to see the header, which
SendToICS(str);
}
}
- new_piece[0] = NULLCHAR;
- sscanf(parse, "game %d white [%s black [%s <- %s",
- &gamenum, white_holding, black_holding,
- new_piece);
- white_holding[strlen(white_holding)-1] = NULLCHAR;
- black_holding[strlen(black_holding)-1] = NULLCHAR;
/* [HGM] copy holdings to board holdings area */
CopyHoldings(boards[forwardMostMove], white_holding, WhitePawn);
CopyHoldings(boards[forwardMostMove], black_holding, BlackPawn);
j = seed%4; seed /= 4;
p = board[0][BOARD_LEFT+j]; board[0][BOARD_LEFT+j] = EmptySquare; k = PieceToNumber(p);
board[k][BOARD_WIDTH-1] = p; board[k][BOARD_WIDTH-2]++;
- board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p; board[BOARD_HEIGHT-1-k][1]++;
+ board[handSize-1-k][0] = WHITE_TO_BLACK p; board[handSize-1-k][1]++;
j = seed%3 + (seed%3 >= j); seed /= 3;
p = board[0][BOARD_LEFT+j]; board[0][BOARD_LEFT+j] = EmptySquare; k = PieceToNumber(p);
board[k][BOARD_WIDTH-1] = p; board[k][BOARD_WIDTH-2]++;
- board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p; board[BOARD_HEIGHT-1-k][1]++;
+ board[handSize-1-k][0] = WHITE_TO_BLACK p; board[handSize-1-k][1]++;
j = seed%3; seed /= 3;
p = board[0][BOARD_LEFT+j+5]; board[0][BOARD_LEFT+j+5] = EmptySquare; k = PieceToNumber(p);
board[k][BOARD_WIDTH-1] = p; board[k][BOARD_WIDTH-2]++;
- board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p; board[BOARD_HEIGHT-1-k][1]++;
+ board[handSize-1-k][0] = WHITE_TO_BLACK p; board[handSize-1-k][1]++;
j = seed%2 + (seed%2 >= j); seed /= 2;
p = board[0][BOARD_LEFT+j+5]; board[0][BOARD_LEFT+j+5] = EmptySquare; k = PieceToNumber(p);
board[k][BOARD_WIDTH-1] = p; board[k][BOARD_WIDTH-2]++;
- board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p; board[BOARD_HEIGHT-1-k][1]++;
+ board[handSize-1-k][0] = WHITE_TO_BLACK p; board[handSize-1-k][1]++;
j = seed%4; seed /= 4; put(board, exoPieces[3], 0, j, ANY);
j = seed%3; seed /= 3; put(board, exoPieces[2], 0, j, ANY);
j = seed%2; seed /= 2; put(board, exoPieces[1], 0, j, ANY);
if(BOARD_HEIGHT > BOARD_RANKS || BOARD_WIDTH > BOARD_FILES)
DisplayFatalError(_("Recompile to support this BOARD_RANKS or BOARD_FILES!"), 0, 2);
+ handSize = BOARD_HEIGHT;
pawnRow = gameInfo.boardHeight - 7; /* seems to work in all common variants */
if(pawnRow < 1) pawnRow = 1;
if(gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN ||
if(gameInfo.variant == VariantGreat) { // promotion commoners
initialPosition[PieceToNumber(WhiteMan)][BOARD_WIDTH-1] = WhiteMan;
initialPosition[PieceToNumber(WhiteMan)][BOARD_WIDTH-2] = 9;
- initialPosition[BOARD_HEIGHT-1-PieceToNumber(WhiteMan)][0] = BlackMan;
- initialPosition[BOARD_HEIGHT-1-PieceToNumber(WhiteMan)][1] = 9;
+ initialPosition[handSize-1-PieceToNumber(WhiteMan)][0] = BlackMan;
+ initialPosition[handSize-1-PieceToNumber(WhiteMan)][1] = 9;
}
if( gameInfo.variant == VariantSChess ) {
initialPosition[1][0] = BlackMarshall;
initialPosition[1][1] = initialPosition[2][1] =
initialPosition[6][BOARD_WIDTH-2] = initialPosition[5][BOARD_WIDTH-2] = 1;
}
+ initialPosition[CHECK_COUNT] = (gameInfo.variant == Variant3Check ? 0x303 : 0);
if (appData.debugMode) {
fprintf(debugFP, "shuffleOpenings = %d\n", shuffleOpenings);
}
piece = boards[currentMove][fromY][fromX];
if(gameInfo.variant == VariantChu) {
- promotionZoneSize = BOARD_HEIGHT/3;
+ promotionZoneSize = (BOARD_HEIGHT - deadRanks)/3;
if(legal[toY][toX] == 6) return FALSE; // no promotion if highlights deny it
highestPromotingPiece = (PieceToChar(piece) == '+' || PieceToChar(CHUPROMOTED(piece)) != '+') ? WhitePawn : WhiteKing;
} else if(gameInfo.variant == VariantShogi) {
- promotionZoneSize = BOARD_HEIGHT/3 +(BOARD_HEIGHT == 8);
+ promotionZoneSize = (BOARD_HEIGHT- deadRanks)/3 +(BOARD_HEIGHT == 8);
highestPromotingPiece = (int)WhiteAlfil;
+ if(PieceToChar(piece) != '+' || PieceToChar(CHUPROMOTED(piece)) == '+') highestPromotingPiece = piece;
} else if(gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand || gameInfo.variant == VariantChuChess) {
promotionZoneSize = 3;
}
if(fromY < promotionZoneSize && gameInfo.variant == VariantChuChess) return FALSE;
highestPromotingPiece = WHITE_TO_BLACK highestPromotingPiece;
} else {
- if( toY < BOARD_HEIGHT - promotionZoneSize &&
- fromY < BOARD_HEIGHT - promotionZoneSize) return FALSE;
- if(fromY >= BOARD_HEIGHT - promotionZoneSize && gameInfo.variant == VariantChuChess)
+ if( toY < BOARD_HEIGHT - deadRanks - promotionZoneSize &&
+ fromY < BOARD_HEIGHT - deadRanks - promotionZoneSize) return FALSE;
+ if(fromY >= BOARD_HEIGHT - deadRanks - promotionZoneSize && gameInfo.variant == VariantChuChess)
return FALSE;
}
return FALSE;
}
} else {
- if(toY == BOARD_HEIGHT-1 && piece == WhitePawn ||
- toY == BOARD_HEIGHT-1 && piece == WhiteQueen ||
- toY >= BOARD_HEIGHT-2 && piece == WhiteKnight) {
+ if(toY == BOARD_HEIGHT-deadRanks-1 && piece == WhitePawn ||
+ toY == BOARD_HEIGHT-deadRanks-1 && piece == WhiteQueen ||
+ toY >= BOARD_HEIGHT-deadRanks-2 && piece == WhiteKnight) {
*promoChoice = '+';
return FALSE;
}
if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n",
moveType, currentMove, fromX, fromY, boards[currentMove][fromY][fromX]);
// holdings might not be sent yet in ICS play; we have to figure out which piece belongs here
- if(fromX == 0) fromY = BOARD_HEIGHT-1 - fromY; // black holdings upside-down
+ if(fromX == 0) fromY = handSize-1 - fromY; // black holdings upside-down
fromX = fromX ? WhitePawn : BlackPawn; // first piece type in selected holdings
while(PieceToChar(fromX) == '.' || PieceToChar(fromX) == '+' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) fromX++;
fromY = DROP_RANK;
if(WhiteOnMove(currentMove)) {
if(!boards[currentMove][k][BOARD_WIDTH-2]) return 0;
} else {
- if(!boards[currentMove][BOARD_HEIGHT-1-k][1]) return 0;
+ if(!boards[currentMove][handSize-1-k][1]) return 0;
}
}
if(PosFlags(0) & F_MANDATORY_CAPTURE) {
for(x=0; x<BOARD_WIDTH; x++) for(y=0; y<BOARD_HEIGHT; y++) if(marker[y][x]>1) capt++;
if(capt)
- for(x=0; x<BOARD_WIDTH; x++) for(y=0; y<BOARD_HEIGHT; y++) if(marker[y][x] == 1) marker[y][x] = 0;
+ for(x=0; x<BOARD_WIDTH; x++) for(y=0; y<BOARD_HEIGHT; y++) if(marker[y][x] == 1) marker[y][x] = legal[y][x] = 0;
}
}
DrawPosition(FALSE, NULL);
(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier ||
gameInfo.variant == VariantMakruk) && !*engineVariant) return FALSE;
return (piece == BlackPawn && y <= zone ||
- piece == WhitePawn && y >= BOARD_HEIGHT-1-zone ||
+ piece == WhitePawn && y >= BOARD_HEIGHT-1-deadRanks-zone ||
piece == BlackLance && y <= zone ||
- piece == WhiteLance && y >= BOARD_HEIGHT-1-zone );
+ piece == WhiteLance && y >= BOARD_HEIGHT-1-deadRanks-zone );
}
void
if(x == BOARD_LEFT-2 && piece >= BlackPawn) {
n = PieceToNumber(piece - (int)BlackPawn);
if(n >= gameInfo.holdingsSize) { n = 0; piece = BlackPawn; }
- boards[currentMove][BOARD_HEIGHT-1 - n][0] = piece;
- boards[currentMove][BOARD_HEIGHT-1 - n][1]++;
+ boards[currentMove][handSize-1 - n][0] = piece;
+ boards[currentMove][handSize-1 - n][1]++;
} else
if(x == BOARD_RGHT+1 && piece < BlackPawn) {
n = PieceToNumber(piece);
ParseGameHistory (char *game)
{
ChessMove moveType;
- int fromX, fromY, toX, toY, boardIndex;
+ int fromX, fromY, toX, toY, boardIndex, mask;
char promoChar;
char *p, *q;
char buf[MSG_SIZ];
strcat(moveList[boardIndex], "\n");
boardIndex++;
ApplyMove(fromX, fromY, toX, toY, promoChar, boards[boardIndex]);
+ mask = (WhiteOnMove(boardIndex) ? 0xFF : 0xFF00);
switch (MateTest(boards[boardIndex], PosFlags(boardIndex)) ) {
case MT_NONE:
case MT_STALEMATE:
default:
break;
case MT_CHECK:
- if(!IS_SHOGI(gameInfo.variant))
- strcat(parseList[boardIndex - 1], "+");
- break;
+ if(boards[boardIndex][CHECK_COUNT]) boards[boardIndex][CHECK_COUNT] -= mask & 0x101;
+ if(!boards[boardIndex][CHECK_COUNT] || boards[boardIndex][CHECK_COUNT] & mask) {
+ if(!IS_SHOGI(gameInfo.variant)) strcat(parseList[boardIndex - 1], "+");
+ break;
+ }
case MT_CHECKMATE:
case MT_STAINMATE:
strcat(parseList[boardIndex - 1], "#");
/* we can always do that 'in place', now pointers to these rights are passed to ApplyMove */
if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A;
- oldEP = (signed char)board[EP_STATUS]; epRank = board[EP_RANK]; epFile = board[EP_FILE]; lastFile = board[LAST_FILE],lastRank = board[LAST_RANK];
+ oldEP = (signed char)board[EP_STATUS]; epRank = board[EP_RANK]; epFile = board[EP_FILE]; lastFile = board[LAST_TO] & 255,lastRank = board[LAST_TO] >> 8;
board[EP_STATUS] = EP_NONE;
- board[EP_FILE] = board[EP_RANK] = board[LAST_FILE] = board[LAST_RANK] = 100;
+ board[EP_FILE] = board[EP_RANK] = 100, board[LAST_TO] = 0x4040;
if (fromY == DROP_RANK) {
/* must be first */
if(toX<BOARD_RGHT-1 && board[toY][toX+1] == BlackPawn &&
gameInfo.variant != VariantBerolina || toX > fromX)
board[EP_STATUS] = toX;
- board[LAST_FILE] = toX; board[LAST_RANK] = toY;
+ board[LAST_TO] = toX + 256*toY;
}
} else
if( pawn == BlackPawn ) {
if(toX<BOARD_RGHT-1 && board[toY][toX+1] == WhitePawn &&
gameInfo.variant != VariantBerolina || toX > fromX)
board[EP_STATUS] = toX;
- board[LAST_FILE] = toX; board[LAST_RANK] = toY;
+ board[LAST_TO] = toX + 256*toY;
}
}
p -= (int)BlackPawn;
p = PieceToNumber((ChessSquare)p);
if(p >= gameInfo.holdingsSize) p = 0;
- if(--board[BOARD_HEIGHT-1-p][1] <= 0)
- board[BOARD_HEIGHT-1-p][0] = EmptySquare;
- if((int)board[BOARD_HEIGHT-1-p][1] < 0)
- board[BOARD_HEIGHT-1-p][1] = 0;
+ if(--board[handSize-1-p][1] <= 0)
+ board[handSize-1-p][0] = EmptySquare;
+ if((int)board[handSize-1-p][1] < 0)
+ board[handSize-1-p][1] = 0;
}
}
if (captured != EmptySquare && gameInfo.holdingsSize > 0
}
p = PieceToNumber((ChessSquare)p);
if(p >= gameInfo.holdingsSize) { p = 0; captured = WhitePawn; }
- board[BOARD_HEIGHT-1-p][1]++;
- board[BOARD_HEIGHT-1-p][0] = WHITE_TO_BLACK captured;
+ board[handSize-1-p][1]++;
+ board[handSize-1-p][0] = WHITE_TO_BLACK captured;
}
}
} else if (gameInfo.variant == VariantAtomic) {
if(!--board[k][BOARD_WIDTH-2])
board[k][BOARD_WIDTH-1] = EmptySquare;
} else {
- if(!--board[BOARD_HEIGHT-1-k][1])
- board[BOARD_HEIGHT-1-k][0] = EmptySquare;
+ if(!--board[handSize-1-k][1])
+ board[handSize-1-k][0] = EmptySquare;
}
}
}
void
MakeMove (int fromX, int fromY, int toX, int toY, int promoChar)
{
- int x = toX, y = toY;
+ int x = toX, y = toY, mask;
char *s = parseList[forwardMostMove];
ChessSquare p = boards[forwardMostMove][toY][toX];
// forwardMostMove++; // [HGM] bare: moved downstream
}
CoordsToComputerAlgebraic(fromY, fromX, toY, toX, promoChar,
moveList[forwardMostMove - 1]);
+ mask = (WhiteOnMove(forwardMostMove) ? 0xFF : 0xFF00);
switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove)) ) {
case MT_NONE:
case MT_STALEMATE:
default:
break;
case MT_CHECK:
- if(!IS_SHOGI(gameInfo.variant))
- strcat(parseList[forwardMostMove - 1], "+");
- break;
+ if(boards[forwardMostMove][CHECK_COUNT]) boards[forwardMostMove][CHECK_COUNT] -= mask & 0x101;
+ if(!boards[forwardMostMove][CHECK_COUNT] || boards[forwardMostMove][CHECK_COUNT] & mask) {
+ if(!IS_SHOGI(gameInfo.variant)) strcat(parseList[forwardMostMove - 1], "+");
+ break;
+ }
case MT_CHECKMATE:
case MT_STAINMATE:
strcat(parseList[forwardMostMove - 1], "#");
SaveEngineSettings (int n)
{
int len; char *p, *q, *s, buf[MSG_SIZ], *optionSettings;
- if(!currentEngine[n] || !currentEngine[n][0]) return; // no engine from list is loaded
+ if(!currentEngine[n] || !currentEngine[n][0]) { DisplayMessage("saving failed: engine not from list", ""); return; } // no engine from list is loaded
p = strstr(firstChessProgramNames, currentEngine[n]);
- if(!p) return; // sanity check; engine could be deleted from list after loading
+ if(!p) { DisplayMessage("saving failed: engine not found in list", ""); return; } // sanity check; engine could be deleted from list after loading
optionSettings = ResendOptions(n ? &second : &first, FALSE);
len = strlen(currentEngine[n]);
q = p + len; *p = 0; // cut list into head and tail piece
if(n == 1) SwapEngines(n);
ParseArgsFromString(buf);
if(n == 1) SwapEngines(n);
+ if(n < 2) { ASSIGN(currentEngine[n], command[i]); }
if(n == 0 && *appData.secondChessProgram == NULLCHAR) {
SwapEngines(1); // set second same as first if not yet set (to suppress WB startup dialog)
ParseArgsFromString(buf);
if(x == BOARD_LEFT-2 && selection >= BlackPawn) {
n = PieceToNumber(selection - BlackPawn);
if(n >= gameInfo.holdingsSize) { n = 0; selection = BlackPawn; }
- boards[0][BOARD_HEIGHT-1-n][0] = selection;
- boards[0][BOARD_HEIGHT-1-n][1]++;
+ boards[0][handSize-1-n][0] = selection;
+ boards[0][handSize-1-n][1]++;
} else
if(x == BOARD_RGHT+1 && selection < BlackPawn) {
n = PieceToNumber(selection);
fromY = moveList[move - 1][1] - ONE;
toX = moveList[move - 1][2] - AAA;
toY = moveList[move - 1][3] - ONE;
- if (fromY == (whiteToPlay ? BOARD_HEIGHT-2 : 1) &&
- toY == (whiteToPlay ? BOARD_HEIGHT-4 : 3) &&
- boards[move][toY][toX] == (whiteToPlay ? BlackPawn : WhitePawn) &&
- fromX == toX) {
+ if ((whiteToPlay ? toY < fromY - 1 : toY > fromY + 1) &&
+ boards[move][toY][toX] == (whiteToPlay ? BlackPawn : WhitePawn) ) {
/* 2-square pawn move just happened */
- *p++ = toX + AAA;
- *p++ = whiteToPlay ? '6'+BOARD_HEIGHT-8 : '3';
+ *p++ = (3*toX + 5*fromX + 4)/8 + AAA;
+ *p++ = (3*toY + 5*fromY + 4)/8 + ONE;
+ if(gameInfo.variant == VariantBerolina) {
+ *p++ = toX + AAA;
+ *p++ = toY + ONE;
+ }
} else {
*p++ = '-';
}
}
}
+ i = boards[move][CHECK_COUNT];
+ if(i) {
+ sprintf(p, "%d+%d ", i&255, i>>8);
+ while(*p) p++;
+ }
+
if(moveCounts)
{ int i = 0, j=move;
i = (int)piece - (int)BlackPawn;
i = PieceToNumber((ChessSquare)i);
if( i >= gameInfo.holdingsSize ) return FALSE;
- board[BOARD_HEIGHT-1-i][0] = piece; /* black holdings */
- board[BOARD_HEIGHT-1-i][1]++; /* black counts */
+ board[handSize-1-i][0] = piece; /* black holdings */
+ board[handSize-1-i][1]++; /* black counts */
bcnt++;
} else {
i = (int)piece - (int)WhitePawn;
if(*p=='-') {
p++; board[EP_STATUS] = EP_NONE;
} else {
- char c = *p++ - AAA;
-
- if(c < BOARD_LEFT || c >= BOARD_RGHT) return TRUE;
- if(*p >= '0' && *p <='9') p++;
- board[EP_STATUS] = c;
+ int d, r, c = *p - AAA;
+
+ if(c >= BOARD_LEFT && c < BOARD_RGHT) {
+ p++;
+ board[EP_STATUS] = board[EP_FILE] = c; r = 0;
+ if(*p >= '0' && *p <='9') r = board[EP_RANK] = *p++ - ONE;
+ d = (r < BOARD_HEIGHT << 1 ? 1 : -1); // assume double-push (P next to e.p. square nearer center)
+ if(board[r+d][c] == EmptySquare) d *= 2; // but if no Pawn there, triple push
+ board[LAST_TO] = 256*(r + d) + c;
+ c = *p++ - AAA;
+ if(c >= BOARD_LEFT && c < BOARD_RGHT) { // mover explicitly mentioned
+ if(*p >= '0' && *p <='9') r = board[EP_RANK] = *p++ - ONE;
+ board[LAST_TO] = 256*r + c;
+ if(!(board[EP_RANK]-r & 1)) board[EP_RANK] |= 128;
+ }
+ }
}
}
+ while(*p == ' ') p++;
+
+ board[CHECK_COUNT] = 0; // [HGM] 3check: check-count field
+ if(sscanf(p, "%d+%d", &i, &j) == 2) {
+ board[CHECK_COUNT] = i + 256*j;
+ while(*p && *p != ' ') p++;
+ }
- if(sscanf(p, "%d", &i) == 1) {
+ c = sscanf(p, "%d%*d +%d+%d", &i, &j, &k);
+ if(c > 0) {
FENrulePlies = i; /* 50-move ply counter */
/* (The move number is still ignored) */
+ if(c == 3 && !board[CHECK_COUNT]) board[CHECK_COUNT] = (3 - j) + 256*(3 - k); // SCIDB-style check count
}
return TRUE;