En passant square in FEN (in UCI)

Discussion of chess software programming and technical issues.

Moderator: Ras

UncombedCoconut
Posts: 319
Joined: Fri Dec 18, 2009 11:40 am
Location: Naperville, IL

En passant square in FEN (in UCI)

Post by UncombedCoconut »

Hi! My favorite chess GUI (pychess) and engine (stockfish) disagree on when the e.p. square should be blank. I'd appreciate help deciding which of them is wrong before I make any bug reports. (The effects on stockfish are fatal assert()s and false belief that it's out of book.)

pychess: e.p. square is provided if and only if the last move was a two-square pawn move.

stockfish: e.p. square is provided if and only if an e.p. capture is possible.

The "Portable Game Notation Specification and Implementation Guide" agrees with pychess. Is that a relevant standard, or some document that disagrees with the behavior of the more popular GUIs?

Thanks for your help. :)
P. Villanueva
Posts: 85
Joined: Sat May 17, 2008 10:57 pm
Location: Bilbao, Spain

Re: En passant square in FEN (in UCI)

Post by P. Villanueva »

http://en.wikipedia.org/wiki/Forsyth%E2 ... s_Notation
A FEN record contains six fields. The separator between fields is a space. The fields are:

1. Piece placement (from white's perspective). Each rank is described, starting with rank 8 and ending with rank 1; within each rank, the contents of each square are described from file a through file h. Following the Standard Algebraic Notation (SAN), each piece is identified by a single letter taken from the standard English names (pawn = "P", knight = "N", bishop = "B", rook = "R", queen = "Q" and king = "K").[1] White pieces are designated using upper-case letters ("PNBRQK") while Black take lowercase ("pnbrqk"). Blank squares are noted using digits 1 through 8 (the number of blank squares), and "/" separate ranks.
2. Active color. "w" means white moves next, "b" means black.
3. Castling availability. If neither side can castle, this is "–". Otherwise, this has one or more letters: "K" (White can castle kingside), "Q" (White can castle queenside), "k" (Black can castle kingside), and/or "q" (Black can castle queenside).
4. En passant target square in algebraic notation. If there's no en passant target square, this is "–". If a pawn has just made a 2-square move, this is the position "behind" the pawn. This is recorded regardless of whether there is a pawn in position to make an en passant capture.
5. Halfmove clock: This is the number of halfmoves since the last pawn advance or capture. This is used to determine if a draw can be claimed under the fifty-move rule.
6. Fullmove number: The number of the full move. It starts at 1, and is incremented after Black's move.
User avatar
smrf
Posts: 484
Joined: Mon Mar 13, 2006 11:08 am
Location: Klein-Gerau, Germany

Re: En passant square in FEN (in UCI)

Post by smrf »

In XFEN the e.p. koor is set if and only if a double pawn step has been placed beside an opposite pawn (but still regardless whether an e.p. move is possible or not).
UncombedCoconut
Posts: 319
Joined: Fri Dec 18, 2009 11:40 am
Location: Naperville, IL

Re: En passant square in FEN (in UCI)

Post by UncombedCoconut »

smrf wrote:In XFEN the e.p. koor is set if and only if a double pawn step has been placed beside an opposite pawn (but still regardless whether an e.p. move is possible or not).
Thanks for catching this; it also corrects my description of stockfish's behavior.

I guess this means that both FEN styles are valid, and virtually every GUI with chess960 support will do what stockfish expects?

FWIW this patch makes stockfish not care which decision the GUI author makes.

Code: Select all

--- src/position.cpp	2009-12-29 12:09:12.000000000 -0800
+++ src_new/position.cpp	2010-01-05 15:13:09.506169860 -0800
@@ -204,11 +204,14 @@
   while (fen[i] == ' ')
       i++;
 
-  // En passant square
+  // En passant square -- ignore if no capture is possible.
   if (    i <= fen.length() - 2
       && (fen[i] >= 'a' && fen[i] <= 'h')
-      && (fen[i+1] == '3' || fen[i+1] == '6'))
-      st->epSquare = square_from_string(fen.substr(i, 2));
+      && (fen[i+1] == '3' || fen[i+1] == '6')) {
+      Square fenEpSquare = square_from_string(fen.substr(i, 2));
+      if (this->pieces(PAWN, opposite_color(sideToMove)) & attacks_from<PAWN>(fenEpSquare))
+        st->epSquare = fenEpSquare;
+  }
 
   // Various initialisation
   for (Square sq = SQ_A1; sq <= SQ_H8; sq++)
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: En passant square in FEN (in UCI)

Post by bob »

UncombedCoconut wrote:Hi! My favorite chess GUI (pychess) and engine (stockfish) disagree on when the e.p. square should be blank. I'd appreciate help deciding which of them is wrong before I make any bug reports. (The effects on stockfish are fatal assert()s and false belief that it's out of book.)

pychess: e.p. square is provided if and only if the last move was a two-square pawn move.

stockfish: e.p. square is provided if and only if an e.p. capture is possible.

The "Portable Game Notation Specification and Implementation Guide" agrees with pychess. Is that a relevant standard, or some document that disagrees with the behavior of the more popular GUIs?

Thanks for your help. :)
It is a really lousy part of the PGN standard, but if a pawn advances two squares, it is an en passant "target" even if the opponent has no pawns...
User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

Re: En passant square in FEN (in UCI)

Post by michiguel »

UncombedCoconut wrote:Hi! My favorite chess GUI (pychess) and engine (stockfish) disagree on when the e.p. square should be blank. I'd appreciate help deciding which of them is wrong before I make any bug reports. (The effects on stockfish are fatal assert()s and false belief that it's out of book.)

pychess: e.p. square is provided if and only if the last move was a two-square pawn move.

stockfish: e.p. square is provided if and only if an e.p. capture is possible.

The "Portable Game Notation Specification and Implementation Guide" agrees with pychess. Is that a relevant standard, or some document that disagrees with the behavior of the more popular GUIs?

Thanks for your help. :)
pychess is then EPD compliant and stockfish is not. The main problem is that the standard focused on easy parsing rather than accuracy. This discussion comes back once in a while.

As GUI, I would send FENs without superflous eps, and accept them if they come with it. It would be nice if everybody does the same too.

Note that a position with a superflous ep is not the same as one w/o it. The 50 move counter will be different, but it is totally this extra info is useless because there is already a counter for that in FEN. Besides, this is not done for any other pawn move.

Miguel
Harald
Posts: 318
Joined: Thu Mar 09, 2006 1:07 am

Re: En passant square in FEN (in UCI)

Post by Harald »

michiguel wrote:As GUI, I would send FENs without superflous eps, and accept them if they come with it. It would be nice if everybody does the same too.
Yes.
Note that a position with a superflous ep is not the same as one w/o it. The 50 move counter will be different, but it is totally this extra info is useless because there is already a counter for that in FEN. Besides, this is not done for any other pawn move.
Sorry, I do not understand. I think the correct/superflous ep target square
in FEN does not have an influence on the 50 move rule. The pawn double
move itself has this influence and whether there is another pawn
(ep-)capture that follows has again influence on 50 moves.
And the true possible ep has an influence on repetition detection because
the position and the possible moves are different with or without ep.
Therefore each engine or GUI must check if the ep in FEN is real or nonsense
and it must always internally correct the situation and the ep flag.

Harald
User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

Re: En passant square in FEN (in UCI)

Post by michiguel »

Harald wrote:
michiguel wrote:As GUI, I would send FENs without superflous eps, and accept them if they come with it. It would be nice if everybody does the same too.
Yes.
Note that a position with a superflous ep is not the same as one w/o it. The 50 move counter will be different, but it is totally this extra info is useless because there is already a counter for that in FEN. Besides, this is not done for any other pawn move.
Sorry, I do not understand. I think the correct/superflous ep target square
in FEN does not have an influence on the 50 move rule. The pawn double
move itself has this influence and whether there is another pawn
(ep-)capture that follows has again influence on 50 moves.
And the true possible ep has an influence on repetition detection because
the position and the possible moves are different with or without ep.
Therefore each engine or GUI must check if the ep in FEN is real or nonsense
and it must always internally correct the situation and the ep flag.

Harald
Correct, let me rephrase it. If you see a superflous ep, last move was a pawn move. If you remove the superflous ep square, you do not know that. What I was trying to say is that not having this extra info is not a problem. If you are intereted in 50 move counters, you have already in FEN, if you are interested in 3-fold reps, you miss history information anyway to be accurate. So, I cannot see any engine using this info for anything.

Miguel
UncombedCoconut
Posts: 319
Joined: Fri Dec 18, 2009 11:40 am
Location: Naperville, IL

Re: En passant square in FEN (in UCI)

Post by UncombedCoconut »

UncombedCoconut wrote:

Code: Select all

--- src/position.cpp	2009-12-29 12:09:12.000000000 -0800
+++ src_new/position.cpp	2010-01-05 15:13:09.506169860 -0800
@@ -204,11 +204,14 @@
   while (fen[i] == ' ')
       i++;
 
-  // En passant square
+  // En passant square -- ignore if no capture is possible.
   if (    i <= fen.length() - 2
       && (fen[i] >= 'a' && fen[i] <= 'h')
-      && (fen[i+1] == '3' || fen[i+1] == '6'))
-      st->epSquare = square_from_string(fen.substr(i, 2));
+      && (fen[i+1] == '3' || fen[i+1] == '6')) {
+      Square fenEpSquare = square_from_string(fen.substr(i, 2));
+      if (this->pieces(PAWN, opposite_color(sideToMove)) & attacks_from<PAWN>(fenEpSquare))
+        st->epSquare = fenEpSquare;
+  }
 
   // Various initialisation
   for (Square sq = SQ_A1; sq <= SQ_H8; sq++)
Sorry, this is obviously wrong :oops: (uploaded a crazy test); it should be:

Code: Select all

--- src/position.cpp	2009-12-29 12:09:12.000000000 -0800
+++ src_new/position.cpp	2010-01-05 15:13:09.506169860 -0800
@@ -204,11 +204,14 @@
   while (fen[i] == ' ')
       i++;
 
-  // En passant square
+  // En passant square -- ignore if no capture is possible.
   if (    i <= fen.length() - 2
       && (fen[i] >= 'a' && fen[i] <= 'h')
-      && (fen[i+1] == '3' || fen[i+1] == '6'))
-      st->epSquare = square_from_string(fen.substr(i, 2));
+      && (fen[i+1] == '3' || fen[i+1] == '6')) {
+      Square fenEpSquare = square_from_string(fen.substr(i, 2));
+      if (this->pieces(PAWN,sideToMove) & attacks_from<PAWN>(fenEpSquare))
+        st->epSquare = fenEpSquare;
+  }
 
   // Various initialisation
   for (Square sq = SQ_A1; sq <= SQ_H8; sq++)
User avatar
hgm
Posts: 28394
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: En passant square in FEN (in UCI)

Post by hgm »

UncombedCoconut wrote:I guess this means that both FEN styles are valid, and virtually every GUI with chess960 support will do what stockfish expects?
WinBoard follows the PGN standard in this respect: the e.p. square is set whenever a Pawn makes a double move.

I hate smart-ass engines that feel the need to "correct" a GUI by making sure things do not work at all. Especially when they are wrong. But even if they would have been right this is inexcusible behavior. I also would not tolerate it in humans. If I would order my handyman to fix a leak in the bathroom, and replace the light bulb in case it was broken, and I would come back in the afternoon, and nothing would have been done to the leak, and his excuse was that there was no lightbulb at all, he would be fired for sure...

This falls under the header "abuse of asserts to sabotage software".

And on a sidenote: I know little of UCI, but I always thought it was a Shredder invention. So doesn't it use Shredder FEN, rather than XFEN?

XFEN is apparently not upward compatible with FENs for normal Chess as defined by the PGN standard... :lol: