Author: Gerd Isenberg
Date: 14:37:21 02/23/06
Go up one level in this thread
On February 23, 2006 at 17:06:07, Dann Corbit wrote:
>On February 23, 2006 at 16:58:07, Gerd Isenberg wrote:
>
>>On February 23, 2006 at 16:28:20, Dann Corbit wrote:
>>
>>>On February 23, 2006 at 16:08:12, Gerd Isenberg wrote:
>>>
>>>>On February 23, 2006 at 15:49:46, Dann Corbit wrote:
>>>>
>>>>>On February 23, 2006 at 15:29:17, Gerd Isenberg wrote:
>>>>>
>>>>>>Sounds very interesting, Dann. Can you elaborate a bit more about the idea?
>>>>>>Do you mean a kind of rotated lookup with 7-bit distinct white/black occupied
>>>>>>states?
>>>>>
>>>>>For any given ray there are at most 128 possible states (7 bits, as you say)
>>>>>because we do not need to count the square on which we are standing.
>>>>>
>>>>>So, obvoiusly, a switch() with 128 labels can account for every possibility.
>>>>>Suppose you have a diagonal slider at e5.
>>>>>The labels will look like:
>>>>>
>>>>>switch case(masked_diagonal)
>>>>>case a1:
>>>>>/* do stuff */
>>>>>break;
>>>>>case a1b2:
>>>>>/* do stuff */
>>>>>break;
>>>>>
>>>>>...
>>>>>
>>>>>case h8:
>>>>>/* do stuff */
>>>>>break;
>>>>>
>>>>>default:
>>>>>assert(false);
>>>>>}
>>>>>
>>>>>Since you have at your disposal bitboards for every piece and for all white and
>>>>>for all black and for all chessmen of any color, you can precompute
>>>>>*everything*.
>>>>>
>>>>>The best thing about it (I think) is that the need for rotating the bitboards
>>>>>goes away completely (though your generator that computes the sliders is much
>>>>>easier if you use rotated bitboards for that). But the generator is not part of
>>>>>your chess program. It just writes four functions for each square on the
>>>>>chessboard.
>>>>>
>>>>>So (for instance) you might have a file called e5.cpp.
>>>>>
>>>>>Inside of e5.cpp, we will find methods e5p() {diagonal, e5 with + slope},
>>>>>e5m(){diagonal, e5 with - slope}, e5v() {e5 vertical} and e5h() {e5 horizontal}
>>>>>[Well, may as well toss in e5n() {e5 knights} etc.]
>>>>>
>>>>>There are (of course) other ways to organize it, and 64 files is a lot of files,
>>>>>but it's not like you have to do a lot of writing, since you write a single
>>>>>program to generate them.
>>>>>
>>>>>Is it clear?
>>>>
>>>>No sorry, not exactly - or better not at all.
>>>>
>>>>How are those generated functions called during movegeneration inside the chess
>>>>program? Do you have arrays of functions pointers indexed by squares and what
>>>>else?
>>>>
>>>>May be i am to biased with the De Bruijn stuff ;-)
>>>
>>>Calling the function returns a structure.
>>>The structure will contain:
>>>1. A list of captures + pawn promotions
>>>2. A list of non-captures
>>>Calling the function updates an array of structures that increments counts of
>>>sqare attacks by piece types, and square shadow attacks by piece type (a shadow
>>>attack is a pin or a battery due to a ray attack with one object in the way).
>>>It also computes half shadow attacks (which are pins or batterys with two
>>>chessmen in the way {of either color}).
>>>
>>>The operations are all precomputed, and so are branchless.
>>>For instance, if we have this board:
>>>[D]K7/6p1/8/4B3/8/2P5/8/7k w - -
>>>we will have (among other things) ...
>>>
>>>Game.c3.WhiteBishopAttacks++; /* Useful to know this chessman is not hung */
>>>Game.d4.WhiteBishopAttacks++; /* also a non-capture move will generate */
>>>Game.f6.WhiteBishopAttacks++; /* also a non-capture move will generate */
>>>Game.g7.WhiteBishopAttacks++; /* also a capture move will generate */
>>>
>>>Game.a1.WhiteBishopShadows++; /* Useful for board control, pins and battery */
>>>Game.b2.WhiteBishopShadows++; /* Useful for board control, pins and battery */
>>>Game.h8.WhiteBishopShadows++; /* Useful for board control, pins and battery */
>>>
>>>So the precomputed stuff will show us not only which captures we can make, but
>>>also if the piece we want to capture is defended, how many defenders there are,
>>>and what type of defenders they are. For empty squares, we can know if it is
>>>pawn safe, ... king safe
>>
>>I still don't get it. Do you have precalculated [128*128] arrays?
>
>No. I write switch statements. There are no array lookups.
>For instance:
>>>>>case a1b2:
>a1b2 is a 64 bit unsigned integer with bits a1 and b2 set.
Huch! That is possible!?
Hopefully no indirect jump table with 2**64 entries ;-)
Is that inside the generator or inside the chess programs.
>
>>How does the white/black occupied information interact with the functions.
>
>The functions have access to all the bitboards both individual and grouped.
>The other stuff is more complicated, which is why I showed the square attack and
>shadow information (which is totally generic and does not even need to know
>piece type).
>
>Obviously, you can take your piece attack mask generated (always has 0, 1, or 2
>bits set on a ray for a slider) and AND it with the enemy chessmen (either
>together or by type) to know which attacks are potential capures (the others are
>piece defends, by elimination).
>
>>Why functions and mot an array of structs?
>
>I have both. The objects are classes which are really nothing more than structs
>with a few function pointers thrown in.
I also generate cpp-source, but only const data.
>
>>Thanks for your patience.
>
>Is it becoming more clear or less clear?
Not sure. Never thought on switch 64-bit ints - still confused about that.
>I have discussed my ideas with other
>people lots of times by email, and maybe I can pull up some of those detailed
>discussions to clarify further.
Thanks, that would be nice.
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.