Note that "other items include" part. "Include" means "necessary" but not always "sufficient".mcostalba wrote:This was your previous (few hours ago) definition of flip:sje wrote:That code doesn't flip any position history. Move retraction will not work, and neither will repetition detection.mcostalba wrote:Anyhow it is easier to flip with string manipulation (at least in C++) starting from the FEN representation of a position:
And this is also the definition most engines follow (if this makes any sense for you).Code: Select all
A position flip is the action by which a position is replaced with a copy of itself modified such that each man is replaced with the corresponding man of the opposite color and then moved to the opposite side (front/back) of the board (file is same, but rank is flipped). Other items must also be flipped: these include the color on the move, the castling status, and the en passant target square.
What I have written flips according to this definition.
Position flipping
Moderators: hgm, Rebel, chrisw
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Re: Position flipping
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Re: Position flipping
Code: Select all
void Position::Flip(void)
{
Position position(GetIfen()); // Initial FEN
Board tmpboard = position.RefBoard();
Color tmpgood = position.GetGood();
Cabs tmpcabs = position.GetCabs();
Sq tmpepsq = position.GetEpSq();
ui tmphmvc = position.GetHmvc();
ui tmpfmvn = position.GetFmvn();
tmpboard.Flip();
FlipColor(tmpgood);
FlipCabs(tmpcabs);
FlipMetaSq(tmpepsq);
MoveNodePtr mnptr = RefHistory().GetHead();
position.Load(tmpboard, tmpgood, tmpcabs, tmpepsq, tmphmvc, tmpfmvn);
while (mnptr)
{
position.PlayMove(mnptr->Other());
mnptr = mnptr->GetNext();
};
*this = position;
}
-
- Posts: 5106
- Joined: Tue Apr 29, 2008 4:27 pm
Re: Position flipping
This is a good debugging feature.mcostalba wrote:This is another thing I am about to drop from Stockfish. The only reason while is still there is because it is from original Tord's code....but I found no use for it even once in the last years...sje wrote:A position flip
Capital punishment would be more effective as a preventive measure if it were administered prior to the crime.
-
- Posts: 589
- Joined: Tue Jun 04, 2013 10:15 pm
Re: Position flipping
I use this:
It doesn't re-normalise the castling field, but my program eats the output anyway.
Code: Select all
#!/usr/bin/python
#
# Small program that flips a board position (exchanges White and Black)
#
import sys
import string
if len(sys.argv) != 2:
print >> sys.stderr, "%s: arguments" % sys.argv[0]
exit(10)
fen = sys.argv[1].split()
if len(fen) != 4:
print >> sys.stderr, "%s: not a FEN string (%s)" %\
(sys.argv[0], repr(sys.argv[1]))
exit(10)
fen[0] = fen[0].translate(string.maketrans("kqrbnpKQRBNP", "KQRBNPkqrbnp"))
fen[1] = fen[1].translate(string.maketrans("wb", "bw"))
fen[2] = fen[2].translate(string.maketrans("kqKQ", "KQkq"))
fen[3] = fen[3].translate(string.maketrans("36", "63"))
rows = fen[0].split("/")
if len(rows) != 8:
print >> sys.stderr, "%s: not a FEN string (%s)" %\
(sys.argv[0], repr(sys.argv[1]))
exit(10)
rows.reverse()
fen[0] = "/".join(rows)
print " ".join(fen)
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: Position flipping
This is just a skeleton used as a dispatcher, the actual code is missing:sje wrote:Code: Select all
void Position::Flip(void)
Code: Select all
tmpboard.Flip();
FlipColor(tmpgood);
FlipCabs(tmpcabs);
FlipMetaSq(tmpepsq);
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: Position flipping
This does not work for Chess960mvk wrote:Code: Select all
fen[2] = fen[2].translate(string.maketrans("kqKQ", "KQkq"))
-
- Posts: 589
- Joined: Tue Jun 04, 2013 10:15 pm
Re: Position flipping
It also does not work for checkers and pac man.
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Re: Position flipping
Board::Flip() is a two line loop over the squares which calls OtherMan() and OtherSq(). FlipCabs() is a two line loop over the castling availability bits which calls FlipCastling(). The other two (and several other scalar flippers) are all one liners.mcostalba wrote:This is just a skeleton used as a dispatcher, the actual code is missing:sje wrote:Code: Select all
void Position::Flip(void)
Code: Select all
tmpboard.Flip(); FlipColor(tmpgood); FlipCabs(tmpcabs); FlipMetaSq(tmpepsq);
A little more work is done by Move::Other(). It has six statements, each flipping or copying a move component.
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: Position flipping
An oversight. I have a procedure "tested" that uses a flip and flop command (flop mirrors left to right at the d/e file point, flip mirrors using the 4/5 rank point. tested computes the static eval, then flips and computes, then flops and computes, then flips again to give the 4th option and computes again. All 4 scores must match. This detects the occasional black/white asymmetry, or the left/right asymmetry. I don't use them to search positions at all, so I never added the ep target.sje wrote:A position flip is the action by which a position is replaced with a copy of itself modified such that each man is replaced with the corresponding man of the opposite color and then moved to the opposite side (front/back) of the board (file is same, but rank is flipped).
Other items must also be flipped: these include the color on the move, the castling status, and the en passant target square.
I notice that in Crafty, which has a flip command, there doesn't seem to be a flip of the en passant target. Am I missing something here?
Symbolic goes a bit further with its position flip. Not only are the board and the FEN scalars flipped, but also the entire move history and the saved state history. This means that it's possible to retract played moves in the flipped position all the way back to its flipped start. Also: flip(flip(P)) ≡ P
A position flip is a handy user command. It can also be used during opening book generation when (position, move) pair data are all stored using a White-to-move convention; this allows retrieval of "reversed" opening data.
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Re: Position flipping
Interesting. I had never thought of a flop() like Crafty's, but I can see where it would be useful. Alas, a flop() must destroy castling availability data, so it has no inverse.bob wrote:I have a procedure "tested" that uses a flip and flop command (flop mirrors left to right at the d/e file point, flip mirrors using the 4/5 rank point. tested computes the static eval, then flips and computes, then flops and computes, then flips again to give the 4th option and computes again. All 4 scores must match. This detects the occasional black/white asymmetry, or the left/right asymmetry.
Symbolic does have ReflectX0(), ReflectY0(), and ReflectXY(). But they are used only for tablebase index generation and are not user commands.
A Position class instance in Symbolic contains a Board class instance as a member To flip the board, the following is used:
Code: Select all
void Board::Flip(void)
{
Board otherboard;
for (Sq sq = (Sq) 0; sq < SqLen; IncrSq(sq))
otherboard.PutMan(sq, OtherMan(GetMan(OtherSq(sq))));
*this = otherboard;
}