Re: Help with Debugging My Chess Engine
Posted: Thu Sep 29, 2016 8:08 pm
Ok.
A set and an unordered set are very different.universecoder wrote:As you people suggest, I too don't think it's a problem with unordered_set, rather the problem might be that using it in a wrong way(the same way as a set?). For now, I'll use a set only.
As I wrote the OP simply uses an unordered set of integers representing square numbers in a piece list (one list per color and piece type). Integers are "hashable".matthewlai wrote:A set and an unordered set are very different.universecoder wrote:As you people suggest, I too don't think it's a problem with unordered_set, rather the problem might be that using it in a wrong way(the same way as a set?). For now, I'll use a set only.
A set requires objects it contains to be comparable. That's how it maintains ordering (usually using a tree).
An unordered_set requires objects to be hashable. It's usually implemented using a hash table.
If your type doesn't satisfy the strict weak ordering constraint (eg. you cannot have objects A, B, C, where A > B, B > C and C > A), a set won't work.
If your type doesn't satisfy the hash constraint (eg. you have the same object with different hashes), an unordered_set won't work.
Code: Select all
enPassantSquare[!side] = EM;
int pawn = ( !side == white ) ? wp : bp;
int increment = ( !side == white ) ? ( 2*UP ) : ( 2*DOWN );
if ( move.currPiece == pawn && ( move.to == move.from + increment ) ) {
enPassantSquare[side] = move.from + increment/2;
//...
}
Now that I read it, you are absolutely correct! I'll store the enPassant Square too.
@Pranav:
I still believe that the undo code for the en passant square is wrong, it might even play a role in the crash scenario. What you do in undoMove() is (if the code from GitHub is still valid):where at this point "side" is the opponent of the side for which you are undoing a move. Let's assume we are undoing a white move, so side == black.Code: Select all
enPassantSquare[!side] = EM; int pawn = ( !side == white ) ? wp : bp; int increment = ( !side == white ) ? ( 2*UP ) : ( 2*DOWN ); if ( move.currPiece == pawn && ( move.to == move.from + increment ) ) { enPassantSquare[side] = move.from + increment/2; //... }
First thing is, you reset enPassantSquare[white] to EM (undefined), but how can you guess that? The previous black move might have been a pawn double step so prior to making this move enPassantSquare[white] may have been set, and this information gets lost that way.
Second, if you detect that the move to be taken back was a pawn double step then you set enPassantSquare[black] to the square that the pawn had crossed, which is correct *after* making a double step but not when taking it back. Here again, the en passant square that may have been set before making the move that led to the current position can't be derived from position+move only.
So it should be obvious that you need to store the (one!) ep square prior to making a move, same as castling rights.