I store the old hashcode in my "undo" information. That makes undoing a move quick and makes sure the hashcode is correctly restored no matter what complications arise during the making of a move: en passant posibilities, castling rights, piece captures etc.
I had a scheme for hashing that I really liked, but ditched it in favour of the hashcodes used by polyglot in order to use standard opening books. In hindsight I don't think I needed to do that, but that's what I have at the moment. The hashcodes are evaluated using exclusive-or and that basically means that the order things are done doesn't matter at all. You just need to make sure that you evaulate things correctly.
I modified my perft software to check hashcodes and I know someone else who did the same so I guess it is standard practice.
In the perft software I check that the incrementally evaluated hashcode is the same as the hashcode generated from scratch.
If it throws up an error, you need to look at the position and move that caused the problem.
For example, if a pawn takes a piece and queens, then you might
1. reset some en-passant rights
2. change some castling rights
3. remove a captured black rook on a8 from the board completely
4. remove a white pawn from b7
5. place the white pawn on a8
6. remove the white pawn from a8
7. create a white queen on a8.
8. Change the side to move.
Some of the steps are unnecessary in the sense that 5 and 6 cancel each other out.
But it is worth noting that it isn't as simple as having the board correct.
That's because for example putting a queen on a8 makes the data for the square a8 correct, even if you don't consiously remove the rook
and whether or not the pawn is put on a8 and removed from a8, or simply removed from b7.
If you get an incorrect hashcode, you can compare it with the correct hashcode (eg by exclusive or-ing in the case of Polyglot's Zobrist hashcodes).
In the example above, if the difference corresponded to a value for en passant, then one could look to see if one had forgotten to cancel enpassant rights
the move after a pawn pushes forwards two squares.
Initially, you can verify that your static evaluation of the hash key is correct.
Here are a few values (with no guarantees) calculated by my program.
- Code: Select all
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - Zob 463B96181691FC9C;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 w - - Zob 5DCCC1E5133B8729;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 b - a3 Zob D5D69496B7DE6C04;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 w - b6 Zob BFD6AAD0CC37BDFE;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 b - c3 Zob A52074970E9C6B42;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 w - d6 Zob 41551F362F831788;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 b - e3 Zob 6A2BA291B6C140A9;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 w - f6 Zob 8D28839F462F7C5B;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 b - g3 Zob D2DCC68323AFA6A3;
4k3/8/8/PpPpPpPp/PpPpPpPp/8/8/4K3 w - h6 Zob 3A6F8C49506DD222;
r3k2r/8/8/8/8/8/8/R3K2R w - - Zob 86981467BEABCFBA;
r3k2r/8/8/8/8/8/8/R3K2R w K - Zob B74F09A9DA190CAA;
r3k2r/8/8/8/8/8/8/R3K2R w Q - Zob 77FDA1E061224E2A;
r3k2r/8/8/8/8/8/8/R3K2R w k - Zob 23E6775E63873C1A;
r3k2r/8/8/8/8/8/8/R3K2R w q - Zob 986EF2BC0F3DD173;
r3k2r/8/8/8/8/8/8/R3K2R w KQkq - Zob FDA239CC692A6053;
7k/8/8/8/8/8/8/K7 w - - Zob 523760C49712209D;
7K/8/8/8/8/8/8/k7 w - - Zob 9D59E1F9C78EE65;
K7/8/8/8/8/8/8/7k w - - Zob DFDAA843ACD9BD6D;
k7/8/8/8/8/8/8/7K w - - Zob 16D152196D11E3F1;
4k3/8/8/8/8/8/P7/4K3 w - - Zob 4A29F78EE09643B0;
4k3/8/8/8/8/8/N7/4K3 w - - Zob 8C32E094493AE3F9;
4k3/8/8/8/8/8/B7/4K3 w - - Zob 4FB436D2EEEEF356;
4k3/8/8/8/8/8/R7/4K3 w - - Zob 1055B3040A2207F3;
4k3/8/8/8/8/8/p7/4K3 w - - Zob 53FB3B27CF9E48D6;
4k3/8/8/8/8/8/n7/4K3 w - - Zob 20685F77C324391F;
4k3/8/8/8/8/8/b7/4K3 w - - Zob 69E7079F3364B22F;
4k3/8/8/8/8/8/r7/4K3 w - - Zob 854737CFD3933679;
4k3/8/8/8/8/8/q7/4K3 w - - Zob 7F65F02AB12D0D79;