Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Are there new ideas to make movegeneration faster ?

Author: Dan Newman

Date: 14:14:49 09/02/99

Go up one level in this thread


On September 02, 1999 at 09:51:07, Bas Hamstra wrote:

>On September 01, 1999 at 14:20:59, Steve Maughan wrote:
>
>>Bas
>>
>>Facinating stuff!!  A couple of quick questions
>>
>>>>>
>>>>>All these methods can see if a piece is attacked by another piece very fast,
>>>>>without scanning the board.
>>>
>>>You can download the source of KnightCap. I have no idea how complicated that
>>>source is. KnightCap keeps a "real" attackmap, which is harder (and I think
>>>slower) than keeping a "pseudo" attackmap. Here is how I do it:
>>>
>>>Suppose your want to "know" at any moment by which pieces a square is
>>>pseudo-attacked. Pseudo attacks are simply blocked AND non blocked attacks by
>>>sliding pieces and attacks by non sliding pieces.
>>
>>How would you do Check detection with only pseudo attacks?  I assume you would
>>test for a pseudo attacker of a king.  If one does not exist then InCheck=false.
>> Otherwise, if one does exist then if it is NOT a sliding piece then
>>InCheck=true.  If it is a sliding piece then do the hard work of checking to see
>>if there is a block.
>>
>>Is this sort of correct?
>
>Yes, that's it.
>
>>>If you want to do SEE you have all attackers neatly sorted already at any time
>>>and can just pop em out with lastone(). You HAVE to have a fast lastone of
>>>course, preferably one that relies on a single CPU instruction (intel has that).
>>>
>>>Critical: a fast lastone and a fast way to update (sliding) attacks.
>>>
>>
>>I understand what SEE is but what do you mean by lastone()?  Do you mean the
>>last bit set?
>
>Yes. The last 1. The gcc compiler has a c function for it: ffs(). If your
>compiler has no such function, but you have a intel cpu, you can make that
>function easily in assembler: there is an assembler instruction BSF that returns
>the last bit set (another for the first bit).
>
>>>I hope this all made sense. Disclaimer: I have not seen many other programs do
>>>this. So draw your own conclusions.
>>>
>>
>>Doesn't Commet do something similar?
>
>I have really no idea, got the idea from what Don Daily once said to me. I don't
>think I have found the ultra fastest way to update sliding attacks yet.
>Currently I have the squares to update in code like this:
>
>OrQueen(int Square, unsigned long Mask)
>
>{ switch(Square)
>  case 0:
>    Attacks[1] |= Mask;
>    Attacks[2] |= Mask;
>    .
>    .
>    .
>    break;
>  case 1:
>    .
>    .
>}
>
>that way the minimum number of assembly instructions is used and you have no
>loop overhead.
>
>However maybe in some cases it is faster to delete attacks from the captured
>piece and the PieceFromSquare (so the 2 pieces you want to delete from the
>attacks in case of a capture) in one run by combining masks:
>
>Attacks[0] &= ~Mask;
>.
>.
>Attacks[63] &= ~Mask;
>
>Especially so when the moving piece and the capture are both sliders.
>
>>Interesting discussion!
>>
>>>
>>>Regards,
>>>Bas Hamstra.

Very interesting.  This discussion has got me started on yet another
chess program...  I once tried this sort of attack table (after reading
about it here I think) but got stymied on figuring out how to update
the table.  The thing was, I was trying to make a legal attack table, which
required updating not only the attacks of the moved/captured piece(s)
but also the newly block/unblocked pieces.  What a nightmare.  A pseudo-
legal attack table is easy though.  I guess the OrQueen() function above
is the sort of thing you write a program to write it for you...

One improvement might be to make this an XOR function like this:

XorQueen(int Square, unsigned long Mask)

{ switch(Square)
  case 0:
    Attacks[1] ^= Mask;
    Attacks[2] ^= Mask;
    .
    .
    .
    break;
  case 1:
    .
    .
}

With this function you can toggle the bits on or off and you don't
need a separate bit clearing function.

Updating the attack table seems like an awful lot of work to do in
make() and undo(), but if it significantly speeds up the SEE, it might
be a win.  And it also should speed up (and make easier to program)
castling generation, in-check detection, etc.  (Currently in my 0x88
program, the SEE takes about 25% of the cycles...)

-Dan.



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.