It seems a bit slowish indeed. I tried on the 2.0GHz Core2Duo.
My method is mailbox structure. Single-threaded, bulk counting, but including SEE for every generated move:
Well this is about the third rewrite... Focusing on GenMoves, MakeMove and UnMakeMove now.
I'm using Delphi XE and worrying a bit about the speed in general.
Int64 operations, array access.
And maybe access of my boardstructure, which has it's fields not aligned on 32 or 64 bit .
ericlangedijk wrote:Thanks for the response.
There is still a lot of optimization to do.
I make pseudolegal moves and check after having made the move if we runned into a check. I work with Bitboards and incrementally update 4 occupationmasks (normal, rotated90, rotated45 and rotated315).
Is this the best way to handle that? Or is there a smarter way?
To my astonishment GenerateMoves() took much less time than I thought.
GenerateMoves - 7,94% of the time used
MakeMove - 19,94% of the time used
UnmakeMove - 16,68% of the time used
RunnedIntoCheck - 14,31% of the time used
Where the rest of the time is going I still have to figure out.
I use Perft (after it runs correct in a lot of testpositions) now to check the basic speed.
It was numbers like these that made me give up on rotated bitmaps.
ericlangedijk wrote:Thanks for the response.
There is still a lot of optimization to do.
I make pseudolegal moves and check after having made the move if we runned into a check. I work with Bitboards and incrementally update 4 occupationmasks (normal, rotated90, rotated45 and rotated315).
Is this the best way to handle that? Or is there a smarter way?
To my astonishment GenerateMoves() took much less time than I thought.
GenerateMoves - 7,94% of the time used
MakeMove - 19,94% of the time used
UnmakeMove - 16,68% of the time used
RunnedIntoCheck - 14,31% of the time used
Where the rest of the time is going I still have to figure out.
I use Perft (after it runs correct in a lot of testpositions) now to check the basic speed.
It was numbers like these that made me give up on rotated bitmaps.
What else is any better? I use magic because of the single occupied_squares bitboard that makes it more flexible, but I saw no speed gain by getting rid of the rotated stuff at all. It is just now more efficient to ask "If I remove this pawn here, will a rook now attack square X?" Before I would have to update all 4 occupied_squares bitboards before I could answer that and it made the code messier. Move generation didn't change a bit, and is, in fact, slower with magic because of the operations being done. But then Make/Unmake gain some speed by doing less updates, which turned into a "break-even" thing with regard to speed...
Rotated BB are much harder to implement (at least for me) than the magic ones but not slower in execution.
Magic BB helped me, because I have a legal move generator and the validation code that verifies the king is not in check after the move creates a new occupied board bitboard where the move was done and checks whether the own king is now attacked. This is simpler with magic bb but very specific to my implementation.
ericlangedijk wrote:As far as I could see Bob (Crafty) generates captures first. Then if a king is taken there the result is discarded.
dont understand this. do you mean you generate all opponent captures when is your turn? that sounds strange to me. what it is usual is you generate the moves of who is in turn and the check if there is any ilegal with a is_attaked(k_sq) function, or allow the search to capture the king and return mate as score.....
also I am curious if crafty makemove (for perf) also compute the new hash.....