Complicating code in C#

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

50 seconds

[pgn]
[Event "Computer Chess Game"]
[Site "LAPTOP-1FK7MTIP"]
[Date "2021.06.04"]
[Round "-"]
[White "Skipper_8_16"]
[Black "Stockfish 13"]
[Result "1-0"]
[TimeControl "50"]
[Annotator "1. +0.21 1... -0.26"]

1. e4 {+0.21/7} e5 {-0.26/22 3} 2. Nc3 {+0.06/7 0.8} Nc6 {-0.07/21 0.9} 3.
Bc4 {-0.08/6 0.8} Nf6 {+0.14/16 0.5} 4. Nf3 {-0.02/7 0.8} Nxe4
{+0.18/20 0.8} 5. Nxe4 {-0.14/7 0.8} d5 {+0.11/21 0.2} 6. Bd3 {-0.31/7 0.8}
dxe4 {+0.00/21 0.1} 7. Bxe4 {-0.40/7 0.8} Bd6 {+0.00/22 0.5} 8. d3
{-0.03/6 0.8} Ne7 {+0.47/18 0.6} 9. d4 {-0.09/6 0.8} f5 {+3.22/19 0.6} 10.
dxe5 {-1.85/6 0.7} Bb4+ {+4.90/17 0.6} 11. Bd2 {-1.96/8 0.7} fxe4
{+5.34/20 0.9} 12. Bxb4 {-1.62/9 0.7} Qxd1+ {+5.36/20 0.2} 13. Rxd1
{-1.08/9 0.7} exf3 {+5.38/20 0.2} 14. gxf3 {-1.06/8 0.7} Nc6 {+5.63/22 2.0}
15. Bc3 {-0.99/7 0.7} Be6 {+6.07/22 3} 16. a4 {-1.02/7 0.7} Rf8
{+6.25/19 0.6} 17. Rd3 {-0.89/7 0.7} Rf4 {+6.21/23 4} 18. a5 {-0.91/6 0.7}
Rh4 {+6.36/21 3} 19. b3 {-0.64/6 0.6} Rd8 {+6.18/19 0.6} 20. O-O
{-0.40/7 0.6} Rxd3 {+6.49/22 2.4} 21. cxd3 {-0.97/6 0.6} Rh6 {+6.48/20 0.1}
22. Rb1 {-1.08/7 0.6} Bh3 {+6.17/25 6} 23. Kh1 {-0.35/7 0.6} Rg6
{+5.78/22 2.2} 24. Rg1 {-0.57/8 0.6} Ne7 {+5.87/20 0.7} 25. Rxg6
{-0.41/8 0.6} Nxg6 {+5.79/19 0.2} 26. d4 {-0.87/8 0.6} Be6 {+6.38/18 0.5}
27. b4 {-0.92/9 0.6} Nh4 {+6.52/19 0.6} 28. f4 {-1.32/8 0.6} Nf5
{+5.03/22 4} 29. Kg2 {-0.44/8 0.5} c6 {+5.30/18 0.6} 30. Kg1 {-0.41/7 0.5}
Ne7 {+5.61/17 0.2} 31. Kg2 {-0.31/7 0.5} Ng6 {+5.12/21 1.7} 32. Kg3
{-0.18/7 0.5} Ne7 {+5.24/18 0.4} 33. Kg2 {+0.00/10 0.5} Bf5 {+5.30/20 0.4}
34. Bd2 {-0.26/7 0.5} Kf7 {+5.47/21 0.1} 35. Kf3 {-0.41/7 0.5} Nd5
{+5.30/19 0.2} 36. Kg3 {-0.40/7 0.5} Ke6 {+5.71/20 0.6} 37. h4
{-0.49/7 0.5} Nc7 {+5.55/21 0.8} 38. Bc1 {-1.00/7 0.5} Kd5 {+5.71/16 0.2}
39. Be3 {-1.12/8 0.5} h5 {+5.82/19 0.6} 40. Kg2 {-1.32/8 0.5} Kc4
{+6.01/18 0.3} 41. f3 {-1.43/7 0.5} Nd5 {+6.07/18 0.2} 42. Bd2
{-2.37/8 0.5} Kd3 {+6.22/16 0.2} 43. Bc1 {-2.32/8 0.5} Kc2 {+6.14/21 0.1}
44. Ba3 {-2.62/8 0.4} Kb3 {+6.40/21 0.2} 45. Bc1 {-2.56/8 0.4} Kc2
{+6.53/22 0.2} 46. Ba3 {+0.00/10 0.5} Kb3 {+6.52/22 0.2} 47. Bc1
{+0.00/11 0.5} Kxb4 {+6.44/21 0.2} 48. Bd2+ {-3.87/8 0.4} Kc4
{+6.71/20 0.1} 49. Kg3 {-3.94/7 0.4} b5 {+8.32/18 0.4} 50. axb6
{-3.73/8 0.4} axb6 {+9.48/22 0.1} 51. Kf2 {-3.93/7 0.4} b5 {+10.02/24 0.1}
52. Kg3 {-4.65/7 0.4} Kd3 {+11.13/19 0.2} 53. Bc1 {-5.18/8 0.4} b4
{+12.32/17 0.2} 54. e6 {-7.31/8 0.4} Kc2 {+14.75/21 0.1} 55. e7
{-9.19/9 0.4} Nxe7 {+57.44/19 0.2} 56. Be3 {-10.67/8 0.4} Nd5
{+99.83/34 0.2} 57. Bf2 {-13.44/7 0.4} b3 {+99.85/36 0.3} 58. Kg2
{-15.20/8 0.3} b2 {+99.89/51 0.1} 59. Bg3 {-15.18/7 0.3} b1=Q
{+99.91/31 0.2} 60. Bf2 {-15.69/8 0.3} Kd3 {+99.93/72 0.1} 61. Bg1
{-20.04/8 0.4} Bh3+ {+99.95/16 0.3} 62. Kh2 {-327.62/8 0.5}
{White wins on time} 1-0
[/pgn]
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Problems with zobrist key. I try to implement it but zobrist key after doing some moves not equal to computing zobrist key from scratch for result position.

Maybe because these random generated bit patterns overlap? I don't understand. I first try to make the tests work by ensuring bit patterns never overlap and making it easy to observe. Resulting key will be far to long. But if that works I try overlapping bit patterns.

By the way I even doubt if zobrist hashing is such a performance gain for you have to update zobrist key for each (undo)move.

(un)Doing move is slow so adding extra zobrist key update probably will make it twice as slow. But 8% is less than 16% as it is now so i continue.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Complicating code in C#

Post by Sven »

Overlapping bits are not an issue here. If incremental hash key != hash key from scratch then you do not perform the same set of XOR operations, so you have a bug for sure.
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Yes already two bugs encountered in move generation. First one when short castling it only disabled short castling rights.
Perft did not catch it because it only castles long when king on e1 and rook on a1 etc.

Second bug was not setting en passant square when pawn moving two squares is isolated.
Of course perft does not catch that. Only matter of definition. But if zobrist hashing does it differently you get diversions.

By the the way there were more bugs because of not implementing zobrist hashing correctly.
For instance forgetting to set en passant square after clearing it etc.

xor is commutative and associative.Maybe it goes wrong if generated bit patterns for two elements are exactly the same.
But chance that that happens is negligible. Now I have key of 64 bits. Being stupid to compress it without first testing all kinds of perfts.
So if I find a bug later I will have more trouble to debug it. Only tested it now on a few perfts.
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Henk wrote: Fri Jun 11, 2021 11:37 pm Maybe it goes wrong if generated bit patterns for two elements are exactly the same.
O wait probably it works too if two bit patterns are exactly the same. Haven't tried it. Only getting more collisions I guess.
Key after n moves and key build from result position will always be the same when there are no bugs even if if all generated bit patterns in zobrist table are identical.
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Time control: 55 seconds

[pgn]
[Event "Computer Chess Game"]
[Site "LAPTOP-1FK7MTIP"]
[Date "2021.06.12"]
[Round "-"]
[White "Skipper_8_16"]
[Black "Stockfish 13"]
[Result "1-0"]
[TimeControl "55"]
[Annotator "1. -0.11 1... +0.27"]

1. d3 {-0.11/8} d5 {+0.27/21 2.1} 2. Nf3 {-0.21/8 0.9} Nf6 {+0.18/21 0.7}
3. Bf4 {-0.23/7 0.9} c5 {+0.30/23 3} 4. Nc3 {-0.06/7 0.9} Nc6
{+0.71/17 0.6} 5. Nb5 {+0.00/7 0.9} Qa5+ {+5.17/21 0.7} 6. Nc3
{-3.11/8 0.9} d4 {+5.12/22 0.7} 7. Bd2 {-3.27/7 0.9} dxc3 {+5.22/23 0.4} 8.
Bxc3 {-3.32/8 0.8} Qc7 {+5.10/21 0.1} 9. e4 {-3.25/7 0.8} e5 {+5.71/21 1.0}
10. b3 {-3.24/6 0.8} Be7 {+6.25/22 1.8} 11. Be2 {-3.21/6 0.8} O-O
{+6.21/21 0.1} 12. O-O {-3.50/6 0.8} Kh8 {+6.20/21 0.1} 13. Rb1
{-2.59/6 0.8} Ng8 {+6.25/24 5} 14. a3 {-2.66/7 0.8} Nd4 {+6.23/24 4} 15.
Nxd4 {-2.81/8 0.7} cxd4 {+6.36/18 0.6} 16. Bb4 {-2.88/9 0.7} Bxb4
{+6.80/20 1.4} 17. axb4 {-2.87/10 0.7} Be6 {+7.01/19 0.3} 18. Bf3
{-2.90/8 0.7} a5 {+6.95/19 2.0} 19. bxa5 {-2.84/9 0.7} Rxa5 {+7.21/20 0.3}
20. b4 {-3.12/8 0.7} Ra2 {+6.78/22 5} 21. Rc1 {-3.10/9 0.7} Nf6
{+7.17/21 1.3} 22. Kh1 {-3.04/7 0.7} Rc8 {+7.28/21 1.3} 23. Kg1
{-3.63/8 0.7} h6 {+7.31/23 6} 24. b5 {-3.43/8 0.7} Qd7 {+7.59/20 1.8} 25.
b6 {-3.46/8 0.6} Qd6 {+7.59/20 1.1} 26. Re1 {-3.33/8 0.6} Qxb6 {+7.83/22 3}
27. Re2 {-3.39/7 0.6} Ra6 {+8.23/19 2.6} 28. Rb1 {-3.45/8 0.6} Qc6
{+7.93/20 1.0} 29. Rb2 {-3.42/7 0.6} b5 {+8.32/18 0.7} 30. Rb1
{-3.41/6 0.6} Qc5 {+8.34/18 0.5} 31. Rb2 {-3.29/6 0.6} b4 {+8.94/17 0.7}
32. Re1 {-3.20/6 0.6} Qc3 {+8.94/19 0.2} 33. Qb1 {-3.39/7 0.6} Ba2
{+9.44/21 0.3} 34. Qc1 {-3.38/7 0.6} b3 {+8.00/20 0.4} 35. Re2
{-3.68/7 0.6} Qxd3 {+8.82/19 0.1} 36. Rd2 {-3.65/7 0.6} Qc3 {+9.19/15 0.2}
37. Be2 {-3.72/5 0.5} Raa8 {+9.71/18 0.1} 38. Bd3 {-3.65/7 0.5} Nd7
{+9.86/16 0.2} 39. Be2 {-3.88/6 0.5} Nc5 {+10.94/15 0.2} 40. Bg4
{-5.28/6 0.5} Na4 {+11.18/16 0.2} 41. Bxc8 {-6.15/7 0.5} Nxb2
{+12.94/16 0.2} 42. Bb7 {-6.29/7 0.5} Rb8 {+13.37/19 0.2} 43. Bd5
{-8.58/7 0.5} Nc4 {+14.76/19 0.2} 44. Rd3 {-9.17/8 0.5} b2 {+16.42/16 0.2}
45. Qf1 {-12.13/8 0.5} Qxc2 {+17.88/17 0.2} 46. Rd1 {-14.22/7 0.5} Qxd1
{+99.85/39 0.1} 47. Qxd1 {-21.99/10 0.5} b1=Q {+99.87/51 0.1} 48. Qf1
{-21.98/9 0.5} Nd2 {+99.89/28 0.2} 49. h3 {-22.59/9 0.5} Qxf1+
{+99.93/27 0.2} 50. Kh2 {-327.60/8 0.5} Qxf2 {+99.95/245 0.5} 51. Bxa2
{-327.62/8 0.6}
{White wins on time} 1-0
[/pgn]
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Don't like this. I made implementation more efficient but now state changes of objects.
So often I must not forget to restore state. For instance after a recursive call.
O wait I have to use a memento and make it more inefficient. Grrr
https://en.wikipedia.org/wiki/Memento_pattern
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

I have to restore ChessBoard [ HistoryFromRoot ] [ZobristKey] when searching a move.
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

I even don't have a [unit] test for null move pruning. Looks like I have lost my mind. Blind faith or something.
Sopel
Posts: 389
Joined: Tue Oct 08, 2019 11:39 pm
Full name: Tomasz Sobczyk

Re: Complicating code in C#

Post by Sopel »

JohnWoe wrote: Tue Dec 08, 2020 11:26 am
Henk wrote: Mon Dec 07, 2020 12:58 pm Before this:

Code: Select all

   public interface IPieceSort
    {
        int Value { get; }
    }
I used

Code: Select all

       public enum Sort { whitePawn, whiteKnight, whiteBishop, whiteRook,  whiteQueen, whiteKing, blackPawn, blackKnight, blackBishop, blackRook, blackQueen, blackKing, none }
But Sort is a concrete type which should be avoided. At least in an interface. Maybe better use int but that is too generic and giving no information.

Now I need an extra class to make it work.

Code: Select all

 class PredefinedPieceSortValues
    {
        public IPieceSort[] pieceSortValues;

        private static object syncRoot = new Object();
        private static PredefinedPieceSortValues instance;

        public static PredefinedPieceSortValues PieceSortInstance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new PredefinedPieceSortValues();
                    }
                }

                return instance;
            }
        }


        private PredefinedPieceSortValues()
        {
            const int NUMBER_OF_SORT_VALUES = (int)none;
            pieceSortValues = new ChessPieceSort[NUMBER_OF_SORT_VALUES];

            for (var i = whitePawn; i <= blackKing; i++)
            {
                pieceSortValues[(int)i] = new ChessPieceSort(i);
            }

        }

        public IPieceSort PieceSort(ChessPiece.Sort pieceSort)
        {
            return pieceSortValues[(int)pieceSort];

        }
 }

Get the impression making it overcomplicated. But don't see a better solution yet.
Without looking any further. I count 6 indentation levels. After 3 you are generally kinda fucked. :D

It's code smell.
Indentation level is a terrible metric. Cyclomatic complexity is a somewhat better one and here it's very low.
dangi12012 wrote:No one wants to touch anything you have posted. That proves you now have negative reputations since everyone knows already you are a forum troll.

Maybe you copied your stockfish commits from someone else too?
I will look into that.