Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Bitboards: must I rotate ?

Author: Matthias Gemuh

Date: 04:29:12 05/12/02

Go up one level in this thread


On May 12, 2002 at 05:34:48, Tim Foden wrote:

>On May 12, 2002 at 02:53:12, Matthias Gemuh wrote:
>
>>On May 12, 2002 at 00:23:07, Robert Hyatt wrote:
>>
>>>On May 11, 2002 at 05:48:17, Matthias Gemuh wrote:
>>>
>>>>
>>>>Hi Experts,
>>>>how much faster can I compute attacks when I rotate ? 5%? 20%? 50%?
>>>>I don't understand rotation and hope the gain is 1% speed boost :-).
>>>>Regards,
>>>>Matthias.
>>>
>>>It is more than that.  The main thing is that it eliminates the loop needed
>>>to find where a particular diagonal, file or rank is blocked.  Generating
>>>the attacks on a particular "ray" becomes a simple table lookup...
>>
>>
>>I don't loop. I use an idea from Crafty (blocking squares)
>>
>>if (((MovesAndAttacks->obstructed[k][j] & BitBoth) == 0) &&
>>           (MovesAndAttacks->SlidingMoves[bishop][k]&ChsPos->Mask[j]))
>>
>>tells me bishop on square k can move unhindered to square j.
>>Is this too expensive ?
>
>Let's see if I understand this.  You have a bishop on square k, and you are
>testing whether the bishop can be moved to square j?
>
>How do you get the value for j?
>
>Maybe an example of generating ALL the moves for the bishop would be more
>beneficial.
>
>A rotated bitboard implementation will do something like this (this is adapted
>from the code in Green Light):
>
>
>	// first we generate the bitmap of all moves
>
>	int	rank = Rank(from);
>	int	file = File(from);
>
>	UINT8	diag1 = m_bitBoard.m_rows[bbDiag1 + 7 + rank - file];
>	UINT8	diag2 = m_bitBoard.m_rows[bbDiag2 + rank + file];
>	UINT64	diag1Moves = m_diag1Moves[from][diag1];
>	UINT64	diag2Moves = m_diag2Moves[from][diag2];
>
>	// we remove moves that take the bishops own pieces
>	UINT64	bitmap = (diag1Moves | diag2Moves) & ~m_colourBoard[m_wtm];
>
>	// now we generate the moves
>        while( bitmap )
>        {
>		Square	to = BitScanForwardRemove(bitmap);
>                moves.Add( CMove(cBishop, from, to) );
>        }
>
>What would your code to generate all the bishop's moves look like?
>
>Cheers, Tim.




Your solution looks smarter. I will study it carefully.
Yes, I need a loop to get that "j" when generating moves. In eval(), j be some
interesting target (got without loop).
I do this for white:

        BitS = WhiteBishops;
        while (BitS) {
            nFrom = FirstOne(BitS); Move = PutFrom(Move,nFrom);
            if (ChsPos->piece[white][bishop] & MovesAndAttacks->set_mask[nFrom])
Move = PutPieceNr(Move,bishop);
            Move = PutEp(Move,0); Move = PutPromo(Move,0); Move =
PutCapturedNr(Move,0);
            moves = MovesAndAttacks->SlidingMoves[bishop][nFrom] & BitEmpty;
            while (moves) {
                nTo = FirstOne(moves); Move = PutTo(Move,nTo);
                if ((MovesAndAttacks->obstructed[nFrom][nTo] & BitBoth) == 0) {
                    MoveList[nIndex] = Move; nIndex++;
                }
                Klear(nTo, moves);
            }
            Move = PutEp(Move,0); Move = PutPromo(Move,0); Move =
PutCapturedNr(Move,0);
            moves = MovesAndAttacks->SlidingMoves[bishop][nFrom] &
ChsPos->occupied[black];
            while (moves) {
                nTo = FirstOne(moves); Move = PutTo(Move,nTo);
                if ((MovesAndAttacks->obstructed[nFrom][nTo] & BitBoth) == 0) {
                    Move = PutCapturedNr(Move, ChsPos->PieceOnSq[nTo]);
                    MoveList[nIndex] = Move; nIndex++;
                }
                Klear(nTo, moves);
            }
            Klear(nFrom, BitS);
        }


This generates noncaptures, then caps.
I generate 10 million pseudolegal per sec on Athlon 1.4GHz.
Too slow approach maybe.


Regards,
Matthias.









This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.