The wrong way

Discussion of chess software programming and technical issues.

Moderator: Ras

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

Re: The wrong way

Post by Henk »

It's the same code as before. Assume attackers != 0.

Code: Select all

 
        void AddCaptures(List<MoveBase> moves, ulong attackers, ulong target)
        {
            BitBoardIndex bbIndex = BitBoardIndex.Instance;
            do
            {
                var attackerBit = attackers & (~attackers + 1);
                var Location = ChessBoard.GetField(bbIndex, attackerBit);

                ChessPiece.Sort PieceSort = Location.Occupier.PieceSort;
                var moveDict = Location.AllMovesDict(PieceSort);
                var captures = Location.Moves(PieceSort, Board.Occupiers) & target;
                while (captures != 0)
                {
                    var moveBit = captures & (~captures + 1);
                    var move = moveDict[moveBit];

                    moves.Add(move);
                    captures &= captures - 1;
                }
                attackers &= attackers - 1;
            }
            while (attackers != 0);
        }
Henk
Posts: 7251
Joined: Mon May 27, 2013 10:31 am

Re: The wrong way

Post by Henk »

I don't know if it is best to generate captures in (small) stages instead of generating them all. For how big is the chance that a capture causes a cut off after hash move has been played. If that chance would be low then it would be better to generate all captures in one method call.
User avatar
hgm
Posts: 28383
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: The wrong way

Post by hgm »

Typical numbers people report for cut moves in cut nodes are 80-90% cutoff by the first move (presumably hash), and 5-10% by the second move (presumably the MVV/LVA-wise best capture). So it does seem to happen reasonably often. I use 'staged' move generation in Spartacus, where it generates all captures on a particular victim-value group, and then searches those before generating for the next value group. Even with a stupid method for generating the captures of a given target I was surprised how competitive this was, nps-wise.
Henk
Posts: 7251
Joined: Mon May 27, 2013 10:31 am

Re: The wrong way

Post by Henk »

Henk wrote:It's the same code as before. Assume attackers != 0.

Code: Select all

 
        void AddCaptures(List<MoveBase> moves, ulong attackers, ulong target)
        {
            BitBoardIndex bbIndex = BitBoardIndex.Instance;
            do
            {
                var attackerBit = attackers & (~attackers + 1);
                var Location = ChessBoard.GetField(bbIndex, attackerBit);

                ChessPiece.Sort PieceSort = Location.Occupier.PieceSort;
                var moveDict = Location.AllMovesDict(PieceSort);
                var captures = Location.Moves(PieceSort, Board.Occupiers) & target;
                while (captures != 0)
                {
                    var moveBit = captures & (~captures + 1);
                    var move = moveDict[moveBit];

                    moves.Add(move);
                    captures &= captures - 1;
                }
                attackers &= attackers - 1;
            }
            while (attackers != 0);
        }
Perhaps better:

Code: Select all

        void AddCaptures(List<MoveBase> moves, ulong attackers, ulong target,  ulong occupiers)
        {           
            do
            {
                ChessBoard[attackers & (~attackers + 1)].AddCaptures(moves, target, occupiers);              
            }
            while ((attackers &= attackers - 1) != 0);
        }
flok

Re: The wrong way

Post by flok »

Today I made the moves-list-generator of my program 3.48% slower.
The code shrunk on the other hand shrunk:
  • 2,28% lines
    7,2% bytes
A good day for a software developer is a day where he removes code.
Henk
Posts: 7251
Joined: Mon May 27, 2013 10:31 am

Re: The wrong way

Post by Henk »

flok wrote:Today I made the moves-list-generator of my program 3.48% slower.
The code shrunk on the other hand shrunk:
  • 2,28% lines
    7,2% bytes
A good day for a software developer is a day where he removes code.
Then I might as well implement minimax and have stopped few years ago.
It is the speed requirement. Software that does not meet the requirements is not good.
flok

Re: The wrong way

Post by flok »

Henk wrote:
flok wrote:Today I made the moves-list-generator of my program 3.48% slower.
The code shrunk on the other hand shrunk:
  • 2,28% lines
    7,2% bytes
A good day for a software developer is a day where he removes code.
Then I might as well implement minimax and have stopped few years ago.
It is the speed requirement. Software that does not meet the requirements is not good.
Speed must come in the first place from the algorithm, implementation at earliest on the second place.
Henk
Posts: 7251
Joined: Mon May 27, 2013 10:31 am

Re: The wrong way

Post by Henk »

Skipper only has to be about million times faster (or doesn't ELO increase with 70 points for each factor two).
flok

Re: The wrong way

Post by flok »

Henk wrote:Skipper only has to be about million times faster (or doesn't ELO increase with 70 points for each factor two).
By fixing a bug a couple of bugs (e.g. not sorting en-passant moves correctly) I gained +/- 130 elo poins today. That is including that 3.4% slow down...
Henk
Posts: 7251
Joined: Mon May 27, 2013 10:31 am

Re: The wrong way

Post by Henk »

flok wrote:Today I made the moves-list-generator of my program 3.48% slower.
The code shrunk on the other hand shrunk:
  • 2,28% lines
    7,2% bytes
A good day for a software developer is a day where he removes code.

Strangely bad or ugly code always performs best in Skipper so I have to set it back. Main rule: the more generic your code the slower it gets.