From 07a436432ceac681e3e06f8a035d4f4d6413fb15 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 6 Dec 2016 17:19:00 +0100 Subject: [PATCH] Generalize FEN e.p. field to handle diagonal and triple pushes In Berolina Chess a single square canot unambiguously indicate which e.p. capture ispossible, as two initial double-pushes could cross over the same square (and a 4th-rank Pawn could have come from two 2nd-rank locations). So both the skipped square and the location of the corresponding e.p.victim have to be mentioned in the e.p. field of a FEN. This is now supported (in variant Berolina) on both reading and writing. In addition, the test for when an e.p. field has to be added is improved. It was still using hard-coded rank numbers, only acting on 2->4 and 7->5 Pawn moves that stayed on the same file. Now it works on any advance of more than one rank. For pushes of more than one rank the e.p. square is biased towards the from-square. This makes it possible to distinguish between a triple and a double-push that end on the same rank. --- backend.c | 35 ++++++++++++++++++++++++----------- 1 files changed, 24 insertions(+), 11 deletions(-) diff --git a/backend.c b/backend.c index 57c06b9..baead2f 100644 --- a/backend.c +++ b/backend.c @@ -18445,13 +18445,15 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) 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++ = '-'; } @@ -18828,11 +18830,22 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) 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; + } + } } } -- 1.7.0.4