Problem with bitboard knight attack generator

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

ZirconiumX
Posts: 1334
Joined: Sun Jul 17, 2011 11:14 am

Re: Problem with bitboard knight attack generator

Post by ZirconiumX »

ATM, with a not brilliant move generation scheme, should I calculate on the spot, which will be slow, or do I pre-initalize another set of tables for speed and laziness?

I think I pre-init another set of tables, just because I'm a lazy programmer.

Matthew:out

*Gets gloves out* - UK readers will know get the pun.
Some believe in the almighty dollar.

I believe in the almighty printf statement.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with bitboard knight attack generator

Post by Sven »

lucasart wrote:
Sven Schüle wrote:
lucasart wrote:
Sven Schüle wrote:
lucasart wrote:Ah OK, I understand what you mean with typedef extern. Have a look here, it's all explained:
http://www.allegro.cc/forums/print-thread/588235
How about C++, Lucas? ;-)

Code: Select all

struct A {
   ...
};

...

extern A my_a;
extern A * my_a_ptr;
No need for a "typedef" for structs any longer, "A" from the declaration "struct A" is already the name of the type (since "struct" is a special form of "class" where all members are public).

999:998 for C++ :-)

Sven
If I Coul;d have only the good stuff in C++ without all the crap, why not. But post C++98 exceptions are everywhere in the STL and even thrown by language operators...
You can use C++ without using any single line of STL. All my chess programs were written in C++ but there was never STL in it. Actually you don't need STL for chess programming.

In other areas of software development things are probably different. But I promised not to try converting you :-)

Sven

EDIT: Sorry to Matthew for hijacking your thread, I think I'll stop now.
But if you don't use STL in your chess program, why do you use C++ anyway ? Is it just because of this syntactic sugar (classes and the like can be written in plain C very well)
Just to clarify: with "STL" I mean that part of the C++ standard library which deals with containers, iterators, standard algorithms, numerics and the like. Sometimes "STL" is used as synonym for the whole C++ standard library which also contains the standard C library, the input/output stream library, and miscellaneous libraries like language support, strings or general utilities, but this does not match my understanding (see also http://www.cplusplus.com/reference). Very few parts of the latter, namely "new/delete", i/o streams and strings, are still possible candidates for using them in a chess program, although I only use "new" and "delete". This is not "STL" in my view, though.

As to your question why I use C++ instead of C, find below a brief summary of my reasons (not necessarily complete):

- stronger type system, which can also improve the ability of the compiler to optimize the code;
- encapsulation (which is sometimes a great help in isolating the source of a bug);
- the constructor/destructor concept to improve data integrity;
- several improvements in notation; two examples are:
a) the ability to put declarations where they are needed, not always at the top of a block,
b) initialization by using constructors;
- generic programming using templates (when using them with care - I am not a friend of horribly nested template declarations!!).

As you may have noticed, C99 has a lot of enhancements over C90, and you may guess where these originate ...

Sven
ZirconiumX
Posts: 1334
Joined: Sun Jul 17, 2011 11:14 am

Re: Problem with bitboard knight attack generator

Post by ZirconiumX »

Sven,

I though you were gong to
Sven Schüle wrote: stop now.
Gentlemen, if you are going to have flame wars about such matters, go and debate it with Steven Edwards, who will shoot you down in PASCAL flames.

I'm going to ask a mod about this.

Matthew:out
Some believe in the almighty dollar.

I believe in the almighty printf statement.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with bitboard knight attack generator

Post by Sven »

ZirconiumX wrote:Sven,

I though you were gong to
Sven Schüle wrote: stop now.
Gentlemen, if you are going to have flame wars about such matters, go and debate it with Steven Edwards, who will shoot you down in PASCAL flames.

I'm going to ask a mod about this.

Matthew:out
Please accept my apologies, as well as (I assume) those of Lucas. I will no longer post about C/C++ comparison issues in this thread, and hope noone else does.

Sven
ZirconiumX
Posts: 1334
Joined: Sun Jul 17, 2011 11:14 am

Re: Problem with bitboard knight attack generator

Post by ZirconiumX »

Matthew R. Brades wrote: ATM, with a not brilliant move generation scheme, should I calculate moves on the fly, which will be slow, or do I pre-initalize another set of tables for speed and laziness?

I think I pre-init another set of tables, just because I'm a lazy programmer.
Some believe in the almighty dollar.

I believe in the almighty printf statement.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with bitboard knight attack generator

Post by Sven »

ZirconiumX wrote:ATM, with a not brilliant move generation scheme, should I calculate on the spot, which will be slow, or do I pre-initalize another set of tables for speed and laziness?

I think I pre-init another set of tables, just because I'm a lazy programmer.
Are you now talking about sliding piece attacks resp. moves, or still about kings/knights/pawns?

In the former case, an answer to your question would require to know more about your current scheme of attack/move generation for sliding pieces. Would you mind giving a brief abstract of it?

In general I think that "laziness" does not necessarily correspond with speed. Sometimes the "lazy" approach that requires less coding effort can also be the slower one.

In case of sliding piece attacks/moves one of the most common approaches, "magic bitboards", usually works with a precalculated move database, either as a static table generated by a separate utility or dynamically calculated at program startup in a way as published by Marco Costalba this year.

Sven
ZirconiumX
Posts: 1334
Joined: Sun Jul 17, 2011 11:14 am

Re: Problem with bitboard knight attack generator

Post by ZirconiumX »

Sven Schüle wrote:
ZirconiumX wrote:ATM, with a not brilliant move generation scheme, should I calculate on the spot, which will be slow, or do I pre-initalize another set of tables for speed and laziness?

I think I pre-init another set of tables, just because I'm a lazy programmer.
1) Are you now talking about sliding piece attacks resp. moves, or still about kings/knights/pawns?

2) In the former case, an answer to your question would require to know more about your current scheme of attack/move generation for sliding pieces. Would you mind giving a brief abstract of it?

3) In general I think that "laziness" does not necessarily correspond with speed. Sometimes the "lazy" approach that requires less coding effort can also be the slower one.

4) In case of sliding piece attacks/moves one of the most common approaches, "magic bitboards", usually works with a precalculated move database, either as a static table generated by a separate utility or dynamically calculated at program startup in a way as published by Marco Costalba this year.

Sven
1) Yes, I am talking about sliders.

2) ATM, I use Dumb7Fill for sliders, calculating for each direction (CPW code), and ORing each direction together to produce a Bitboard for the piece on that square.

3) First I want to know how to do it, before I do it well, as I have never before coded a bitboard move generation scheme in my entire life.

4) I don't understand Magic Bitboards, and I would like to stick to stuff I can understand. In the future, I would like to upgrade to Kindergarten Bitboards, then to Rotated, then Magic.

Matthew:out
Some believe in the almighty dollar.

I believe in the almighty printf statement.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with bitboard knight attack generator

Post by Sven »

ZirconiumX wrote:2) ATM, I use Dumb7Fill for sliders, calculating for each direction (CPW code), and ORing each direction together to produce a Bitboard for the piece on that square.
In CPW, Dumb7Fill routines require to pass the "not occupied" bitboard taken (or derived) from the current board state as parameter "empty". I don't know if anyone has also tried to combine that idea with precalculated tables but to me it seems that the "Dumb7Fill" algorithm only works "on the fly".

Sven
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Problem with bitboard knight attack generator

Post by lucasart »

ZirconiumX wrote: 4) I don't understand Magic Bitboards, and I would like to stick to stuff I can understand. In the future, I would like to upgrade to Kindergarten Bitboards, then to Rotated, then Magic.
Rotated bitboards are quite simple to understand and to implement. I did that in the first versions of DoubleCheck, after reading this article http://www.frayn.net/beowulf/theory.html#bitboards. I implemented it all myself, looking at no one's code, and believe me it was painful. This page might be a little outdated by now, but IMO it's much easier to follow than the chess programming wiki. Probably to start reading this page before going into the wiki.

However, later on, when I wanted to further improve my mobility evaluation, I realized that I needed to remove certain set of squares from an occupancy structure (which is a collection of occupancy + symetric and rotated occupancies). and the only way was to do a loop, which seemed so stupid and was defeating the whole purpose of bitboards. Then I looked at StockFish for magic bitboards. I found the code somewhat complicated and difficult to "extract", so I took the one from Umko by Borko Boskovic, which is licensed under the GNU GPL. I "extracted" it from all the rest and put it in magic.c http://wbec-ridderkerk.nl/html/details1 ... Check.html
To be honest, I don't understand how it works either, and I can't be bothered. I decided I had done enough "reinventing the wheel" by coding a chess engine in C from scratch in the first place, so I could indulge in a bit of cpoy/paste, especially as this code is not related to chess playing stuff, which is the part i'm most interested in

Code: Select all

/*
 * DoubleCheck, a UCI chess playing engine. Copyright (C) 2011 Lucas Braesch.
 *
 * DoubleCheck is free software: you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * DoubleCheck is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program. If not,
 * see <http&#58;//www.gnu.org/licenses/>.
 *
 * Credits&#58; All magic bitboard code is a &#40;almost&#41; verbatim copy of Umko, by Borko Boskovic. Many
 * thanks to Borko for providing a good implementation of magics to the free software community.
*/
#include "defs.h"

const int magic_bb_r_shift&#91;64&#93; = &#123;
	52, 53, 53, 53, 53, 53, 53, 52,
	53, 54, 54, 54, 54, 54, 54, 53,
	53, 54, 54, 54, 54, 54, 54, 53,
	53, 54, 54, 54, 54, 54, 54, 53,
	53, 54, 54, 54, 54, 54, 54, 53,
	53, 54, 54, 54, 54, 54, 54, 53,
	53, 54, 54, 54, 54, 54, 54, 53,
	53, 54, 54, 53, 53, 53, 53, 53
&#125;;

const uint64_t magic_bb_r_magics&#91;64&#93; = &#123;
	0x0080001020400080ull, 0x0040001000200040ull, 0x0080081000200080ull, 0x0080040800100080ull,
	0x0080020400080080ull, 0x0080010200040080ull, 0x0080008001000200ull, 0x0080002040800100ull,
	0x0000800020400080ull, 0x0000400020005000ull, 0x0000801000200080ull, 0x0000800800100080ull,
	0x0000800400080080ull, 0x0000800200040080ull, 0x0000800100020080ull, 0x0000800040800100ull,
	0x0000208000400080ull, 0x0000404000201000ull, 0x0000808010002000ull, 0x0000808008001000ull,
	0x0000808004000800ull, 0x0000808002000400ull, 0x0000010100020004ull, 0x0000020000408104ull,
	0x0000208080004000ull, 0x0000200040005000ull, 0x0000100080200080ull, 0x0000080080100080ull,
	0x0000040080080080ull, 0x0000020080040080ull, 0x0000010080800200ull, 0x0000800080004100ull,
	0x0000204000800080ull, 0x0000200040401000ull, 0x0000100080802000ull, 0x0000080080801000ull,
	0x0000040080800800ull, 0x0000020080800400ull, 0x0000020001010004ull, 0x0000800040800100ull,
	0x0000204000808000ull, 0x0000200040008080ull, 0x0000100020008080ull, 0x0000080010008080ull,
	0x0000040008008080ull, 0x0000020004008080ull, 0x0000010002008080ull, 0x0000004081020004ull,
	0x0000204000800080ull, 0x0000200040008080ull, 0x0000100020008080ull, 0x0000080010008080ull,
	0x0000040008008080ull, 0x0000020004008080ull, 0x0000800100020080ull, 0x0000800041000080ull,
	0x00FFFCDDFCED714Aull, 0x007FFCDDFCED714Aull, 0x003FFFCDFFD88096ull, 0x0000040810002101ull,
	0x0001000204080011ull, 0x0001000204000801ull, 0x0001000082000401ull, 0x0001FFFAABFAD1A2ull
&#125;;

const uint64_t magic_bb_r_mask&#91;64&#93; = &#123;
	0x000101010101017Eull, 0x000202020202027Cull, 0x000404040404047Aull, 0x0008080808080876ull,
	0x001010101010106Eull, 0x002020202020205Eull, 0x004040404040403Eull, 0x008080808080807Eull,
	0x0001010101017E00ull, 0x0002020202027C00ull, 0x0004040404047A00ull, 0x0008080808087600ull,
	0x0010101010106E00ull, 0x0020202020205E00ull, 0x0040404040403E00ull, 0x0080808080807E00ull,
	0x00010101017E0100ull, 0x00020202027C0200ull, 0x00040404047A0400ull, 0x0008080808760800ull,
	0x00101010106E1000ull, 0x00202020205E2000ull, 0x00404040403E4000ull, 0x00808080807E8000ull,
	0x000101017E010100ull, 0x000202027C020200ull, 0x000404047A040400ull, 0x0008080876080800ull,
	0x001010106E101000ull, 0x002020205E202000ull, 0x004040403E404000ull, 0x008080807E808000ull,
	0x0001017E01010100ull, 0x0002027C02020200ull, 0x0004047A04040400ull, 0x0008087608080800ull,
	0x0010106E10101000ull, 0x0020205E20202000ull, 0x0040403E40404000ull, 0x0080807E80808000ull,
	0x00017E0101010100ull, 0x00027C0202020200ull, 0x00047A0404040400ull, 0x0008760808080800ull,
	0x00106E1010101000ull, 0x00205E2020202000ull, 0x00403E4040404000ull, 0x00807E8080808000ull,
	0x007E010101010100ull, 0x007C020202020200ull, 0x007A040404040400ull, 0x0076080808080800ull,
	0x006E101010101000ull, 0x005E202020202000ull, 0x003E404040404000ull, 0x007E808080808000ull,
	0x7E01010101010100ull, 0x7C02020202020200ull, 0x7A04040404040400ull, 0x7608080808080800ull,
	0x6E10101010101000ull, 0x5E20202020202000ull, 0x3E40404040404000ull, 0x7E80808080808000ull
&#125;;

const int magic_bb_b_shift&#91;64&#93; = &#123;
	58, 59, 59, 59, 59, 59, 59, 58,
	59, 59, 59, 59, 59, 59, 59, 59,
	59, 59, 57, 57, 57, 57, 59, 59,
	59, 59, 57, 55, 55, 57, 59, 59,
	59, 59, 57, 55, 55, 57, 59, 59,
	59, 59, 57, 57, 57, 57, 59, 59,
	59, 59, 59, 59, 59, 59, 59, 59,
	58, 59, 59, 59, 59, 59, 59, 58
&#125;;

const uint64_t magic_bb_b_magics&#91;64&#93; = &#123;
	0x0002020202020200ull, 0x0002020202020000ull, 0x0004010202000000ull, 0x0004040080000000ull,
	0x0001104000000000ull, 0x0000821040000000ull, 0x0000410410400000ull, 0x0000104104104000ull,
	0x0000040404040400ull, 0x0000020202020200ull, 0x0000040102020000ull, 0x0000040400800000ull,
	0x0000011040000000ull, 0x0000008210400000ull, 0x0000004104104000ull, 0x0000002082082000ull,
	0x0004000808080800ull, 0x0002000404040400ull, 0x0001000202020200ull, 0x0000800802004000ull,
	0x0000800400A00000ull, 0x0000200100884000ull, 0x0000400082082000ull, 0x0000200041041000ull,
	0x0002080010101000ull, 0x0001040008080800ull, 0x0000208004010400ull, 0x0000404004010200ull,
	0x0000840000802000ull, 0x0000404002011000ull, 0x0000808001041000ull, 0x0000404000820800ull,
	0x0001041000202000ull, 0x0000820800101000ull, 0x0000104400080800ull, 0x0000020080080080ull,
	0x0000404040040100ull, 0x0000808100020100ull, 0x0001010100020800ull, 0x0000808080010400ull,
	0x0000820820004000ull, 0x0000410410002000ull, 0x0000082088001000ull, 0x0000002011000800ull,
	0x0000080100400400ull, 0x0001010101000200ull, 0x0002020202000400ull, 0x0001010101000200ull,
	0x0000410410400000ull, 0x0000208208200000ull, 0x0000002084100000ull, 0x0000000020880000ull,
	0x0000001002020000ull, 0x0000040408020000ull, 0x0004040404040000ull, 0x0002020202020000ull,
	0x0000104104104000ull, 0x0000002082082000ull, 0x0000000020841000ull, 0x0000000000208800ull,
	0x0000000010020200ull, 0x0000000404080200ull, 0x0000040404040400ull, 0x0002020202020200ull
&#125;;

const uint64_t magic_bb_b_mask&#91;64&#93; = &#123;
	0x0040201008040200ull, 0x0000402010080400ull, 0x0000004020100A00ull, 0x0000000040221400ull,
	0x0000000002442800ull, 0x0000000204085000ull, 0x0000020408102000ull, 0x0002040810204000ull,
	0x0020100804020000ull, 0x0040201008040000ull, 0x00004020100A0000ull, 0x0000004022140000ull,
	0x0000000244280000ull, 0x0000020408500000ull, 0x0002040810200000ull, 0x0004081020400000ull,
	0x0010080402000200ull, 0x0020100804000400ull, 0x004020100A000A00ull, 0x0000402214001400ull,
	0x0000024428002800ull, 0x0002040850005000ull, 0x0004081020002000ull, 0x0008102040004000ull,
	0x0008040200020400ull, 0x0010080400040800ull, 0x0020100A000A1000ull, 0x0040221400142200ull,
	0x0002442800284400ull, 0x0004085000500800ull, 0x0008102000201000ull, 0x0010204000402000ull,
	0x0004020002040800ull, 0x0008040004081000ull, 0x00100A000A102000ull, 0x0022140014224000ull,
	0x0044280028440200ull, 0x0008500050080400ull, 0x0010200020100800ull, 0x0020400040201000ull,
	0x0002000204081000ull, 0x0004000408102000ull, 0x000A000A10204000ull, 0x0014001422400000ull,
	0x0028002844020000ull, 0x0050005008040200ull, 0x0020002010080400ull, 0x0040004020100800ull,
	0x0000020408102000ull, 0x0000040810204000ull, 0x00000A1020400000ull, 0x0000142240000000ull,
	0x0000284402000000ull, 0x0000500804020000ull, 0x0000201008040200ull, 0x0000402010080400ull,
	0x0002040810204000ull, 0x0004081020400000ull, 0x000A102040000000ull, 0x0014224000000000ull,
	0x0028440200000000ull, 0x0050080402000000ull, 0x0020100804020000ull, 0x0040201008040200ull
&#125;;

uint64_t magic_bb_r_db&#91;0x19000&#93;;
uint64_t magic_bb_b_db&#91;0x1480&#93;;

const uint64_t* magic_bb_b_indices&#91;64&#93; = &#123;
	magic_bb_b_db+4992, magic_bb_b_db+2624, magic_bb_b_db+256,	magic_bb_b_db+896,
	magic_bb_b_db+1280, magic_bb_b_db+1664, magic_bb_b_db+4800, magic_bb_b_db+5120,
	magic_bb_b_db+2560, magic_bb_b_db+2656, magic_bb_b_db+288,  magic_bb_b_db+928,
	magic_bb_b_db+1312, magic_bb_b_db+1696, magic_bb_b_db+4832, magic_bb_b_db+4928,
	magic_bb_b_db+0,    magic_bb_b_db+128, magic_bb_b_db+320,	magic_bb_b_db+960,
	magic_bb_b_db+1344, magic_bb_b_db+1728, magic_bb_b_db+2304, magic_bb_b_db+2432,
	magic_bb_b_db+32,   magic_bb_b_db+160,  magic_bb_b_db+448,	magic_bb_b_db+2752,
	magic_bb_b_db+3776, magic_bb_b_db+1856, magic_bb_b_db+2336, magic_bb_b_db+2464,
	magic_bb_b_db+64,	magic_bb_b_db+192,  magic_bb_b_db+576,  magic_bb_b_db+3264,
	magic_bb_b_db+4288, magic_bb_b_db+1984, magic_bb_b_db+2368, magic_bb_b_db+2496,
	magic_bb_b_db+96,   magic_bb_b_db+224, magic_bb_b_db+704,	magic_bb_b_db+1088,
	magic_bb_b_db+1472, magic_bb_b_db+2112, magic_bb_b_db+2400, magic_bb_b_db+2528,
	magic_bb_b_db+2592, magic_bb_b_db+2688, magic_bb_b_db+832,	magic_bb_b_db+1216,
	magic_bb_b_db+1600, magic_bb_b_db+2240, magic_bb_b_db+4864, magic_bb_b_db+4960,
	magic_bb_b_db+5056, magic_bb_b_db+2720, magic_bb_b_db+864,  magic_bb_b_db+1248,
	magic_bb_b_db+1632, magic_bb_b_db+2272, magic_bb_b_db+4896, magic_bb_b_db+5184
&#125;;

const uint64_t* magic_bb_r_indices&#91;64&#93; = &#123;
	magic_bb_r_db+86016, magic_bb_r_db+73728, magic_bb_r_db+36864, magic_bb_r_db+43008,
	magic_bb_r_db+47104, magic_bb_r_db+51200, magic_bb_r_db+77824, magic_bb_r_db+94208,
	magic_bb_r_db+69632, magic_bb_r_db+32768, magic_bb_r_db+38912, magic_bb_r_db+10240,
	magic_bb_r_db+14336, magic_bb_r_db+53248, magic_bb_r_db+57344, magic_bb_r_db+81920,
	magic_bb_r_db+24576, magic_bb_r_db+33792, magic_bb_r_db+6144,  magic_bb_r_db+11264,
	magic_bb_r_db+15360, magic_bb_r_db+18432, magic_bb_r_db+58368, magic_bb_r_db+61440,
	magic_bb_r_db+26624, magic_bb_r_db+4096,  magic_bb_r_db+7168,  magic_bb_r_db+0,
	magic_bb_r_db+2048,  magic_bb_r_db+19456, magic_bb_r_db+22528, magic_bb_r_db+63488,
	magic_bb_r_db+28672, magic_bb_r_db+5120,  magic_bb_r_db+8192,  magic_bb_r_db+1024,
	magic_bb_r_db+3072,  magic_bb_r_db+20480, magic_bb_r_db+23552, magic_bb_r_db+65536,
	magic_bb_r_db+30720, magic_bb_r_db+34816, magic_bb_r_db+9216,  magic_bb_r_db+12288,
	magic_bb_r_db+16384, magic_bb_r_db+21504, magic_bb_r_db+59392, magic_bb_r_db+67584,
	magic_bb_r_db+71680, magic_bb_r_db+35840, magic_bb_r_db+39936, magic_bb_r_db+13312,
	magic_bb_r_db+17408, magic_bb_r_db+54272, magic_bb_r_db+60416, magic_bb_r_db+83968,
	magic_bb_r_db+90112, magic_bb_r_db+75776, magic_bb_r_db+40960, magic_bb_r_db+45056,
	magic_bb_r_db+49152, magic_bb_r_db+55296, magic_bb_r_db+79872, magic_bb_r_db+98304
&#125;;

static uint64_t init_magic_bb_r&#40;int sq, uint64_t occ&#41;;
static uint64_t init_magic_bb_occ&#40;const int *sq, int numSq, uint64_t linocc&#41;;
static uint64_t init_magic_bb_b&#40;int sq, uint64_t occ&#41;;

void init_magics&#40;)
&#123;
	const int init_magic_bitpos64_db&#91;64&#93; = &#123;
		63,  0, 58,  1, 59, 47, 53,  2,
		60, 39, 48, 27, 54, 33, 42,  3,
		61, 51, 37, 40, 49, 18, 28, 20,
		55, 30, 34, 11, 43, 14, 22,  4,
		62, 57, 46, 52, 38, 26, 32, 41,
		50, 36, 17, 19, 29, 10, 13, 21,
		56, 45, 25, 31, 35, 16,  9, 12,
		44, 24, 15,  8, 23,  7,  6,  5
	&#125;;

	uint64_t* const magic_bb_b_indices2&#91;64&#93; = &#123;
		magic_bb_b_db+4992, magic_bb_b_db+2624, magic_bb_b_db+256,
		magic_bb_b_db+896,  magic_bb_b_db+1280, magic_bb_b_db+1664,
		magic_bb_b_db+4800, magic_bb_b_db+5120, magic_bb_b_db+2560,
		magic_bb_b_db+2656, magic_bb_b_db+288,  magic_bb_b_db+928,
		magic_bb_b_db+1312, magic_bb_b_db+1696, magic_bb_b_db+4832,
		magic_bb_b_db+4928, magic_bb_b_db+0,    magic_bb_b_db+128,
		magic_bb_b_db+320,  magic_bb_b_db+960,  magic_bb_b_db+1344,
		magic_bb_b_db+1728, magic_bb_b_db+2304, magic_bb_b_db+2432,
		magic_bb_b_db+32,   magic_bb_b_db+160,  magic_bb_b_db+448,
		magic_bb_b_db+2752, magic_bb_b_db+3776, magic_bb_b_db+1856,
		magic_bb_b_db+2336, magic_bb_b_db+2464, magic_bb_b_db+64,
		magic_bb_b_db+192,  magic_bb_b_db+576,  magic_bb_b_db+3264,
		magic_bb_b_db+4288, magic_bb_b_db+1984, magic_bb_b_db+2368,
		magic_bb_b_db+2496, magic_bb_b_db+96,   magic_bb_b_db+224,
		magic_bb_b_db+704,  magic_bb_b_db+1088, magic_bb_b_db+1472,
		magic_bb_b_db+2112, magic_bb_b_db+2400, magic_bb_b_db+2528,
		magic_bb_b_db+2592, magic_bb_b_db+2688, magic_bb_b_db+832,
		magic_bb_b_db+1216, magic_bb_b_db+1600, magic_bb_b_db+2240,
		magic_bb_b_db+4864, magic_bb_b_db+4960, magic_bb_b_db+5056,
		magic_bb_b_db+2720, magic_bb_b_db+864,  magic_bb_b_db+1248,
		magic_bb_b_db+1632, magic_bb_b_db+2272, magic_bb_b_db+4896,
		magic_bb_b_db+5184
	&#125;;

	uint64_t* const magic_bb_r_indices2&#91;64&#93; = &#123;
		magic_bb_r_db+86016, magic_bb_r_db+73728, magic_bb_r_db+36864,
		magic_bb_r_db+43008, magic_bb_r_db+47104, magic_bb_r_db+51200,
		magic_bb_r_db+77824, magic_bb_r_db+94208, magic_bb_r_db+69632,
		magic_bb_r_db+32768, magic_bb_r_db+38912, magic_bb_r_db+10240,
		magic_bb_r_db+14336, magic_bb_r_db+53248, magic_bb_r_db+57344,
		magic_bb_r_db+81920, magic_bb_r_db+24576, magic_bb_r_db+33792,
		magic_bb_r_db+6144,  magic_bb_r_db+11264, magic_bb_r_db+15360,
		magic_bb_r_db+18432, magic_bb_r_db+58368, magic_bb_r_db+61440,
		magic_bb_r_db+26624, magic_bb_r_db+4096,  magic_bb_r_db+7168,
		magic_bb_r_db+0,     magic_bb_r_db+2048,  magic_bb_r_db+19456,
		magic_bb_r_db+22528, magic_bb_r_db+63488, magic_bb_r_db+28672,
		magic_bb_r_db+5120,  magic_bb_r_db+8192,  magic_bb_r_db+1024,
		magic_bb_r_db+3072,  magic_bb_r_db+20480, magic_bb_r_db+23552,
		magic_bb_r_db+65536, magic_bb_r_db+30720, magic_bb_r_db+34816,
		magic_bb_r_db+9216,  magic_bb_r_db+12288, magic_bb_r_db+16384,
		magic_bb_r_db+21504, magic_bb_r_db+59392, magic_bb_r_db+67584,
		magic_bb_r_db+71680, magic_bb_r_db+35840, magic_bb_r_db+39936,
		magic_bb_r_db+13312, magic_bb_r_db+17408, magic_bb_r_db+54272,
		magic_bb_r_db+60416, magic_bb_r_db+83968, magic_bb_r_db+90112,
		magic_bb_r_db+75776, magic_bb_r_db+40960, magic_bb_r_db+45056,
		magic_bb_r_db+49152, magic_bb_r_db+55296, magic_bb_r_db+79872,
		magic_bb_r_db+98304
	&#125;;

	for&#40;int i = A1; i <= H8; i++) &#123;
		int sq&#91;64&#93;;
		int numSq = 0;
		uint64_t temp = magic_bb_b_mask&#91;i&#93;;
		while&#40;temp&#41; &#123;
			uint64_t bit = temp & -temp;
			sq&#91;numSq++&#93; = init_magic_bitpos64_db&#91;&#40;bit * 0x07EDD5E59A4E28C2ull&#41; >> 58&#93;;
			temp ^= bit;
		&#125;
		for&#40;temp = 0; temp < &#40;1ULL << numSq&#41;; temp++) &#123;
			uint64_t tempocc = init_magic_bb_occ&#40;sq, numSq, temp&#41;;
			*&#40;magic_bb_b_indices2&#91;i&#93; + (&#40;tempocc * magic_bb_b_magics&#91;i&#93;) >> magic_bb_b_shift&#91;i&#93;)) =
				init_magic_bb_b&#40;i,tempocc&#41;;
		&#125;
	&#125;

	for&#40;int i = A1; i <= H8; i++) &#123;
		int sq&#91;64&#93;;
		int numSq = 0;
		uint64_t temp = magic_bb_r_mask&#91;i&#93;;
		while&#40;temp&#41; &#123;
			uint64_t bit = temp & -temp;
			sq&#91;numSq++&#93; = init_magic_bitpos64_db&#91;&#40;bit * 0x07EDD5E59A4E28C2ull&#41; >> 58&#93;;
			temp ^= bit;
		&#125;
		for&#40;temp = 0; temp < &#40;1ULL << numSq&#41;; temp++) &#123;
			uint64_t tempocc = init_magic_bb_occ&#40;sq, numSq, temp&#41;;
			*&#40;magic_bb_r_indices2&#91;i&#93; + (&#40;tempocc * magic_bb_r_magics&#91;i&#93;) >> magic_bb_r_shift&#91;i&#93;)) =
				init_magic_bb_r&#40;i, tempocc&#41;;
		&#125;
	&#125;
&#125;

uint64_t init_magic_bb_r&#40;int sq, uint64_t occ&#41;
&#123;
	uint64_t ret = 0;
	uint64_t bit;
	uint64_t rowbits = 0xFFULL << &#40;sq & ~7&#41;;

	bit = 1ULL << sq;
	do &#123;
		bit <<= 8;
		ret |= bit;
	&#125; while &#40;bit && !&#40;bit & occ&#41;);
	
	bit = 1ULL << sq;
	do &#123;
		bit >>= 8;
		ret |= bit;
	&#125; while&#40;bit && !&#40;bit & occ&#41;);
	
	bit = 1ULL << sq;
	do &#123;
		bit<<=1;
		if&#40;bit&rowbits&#41;
			ret |= bit;
		else
			break;
	&#125; while (!&#40;bit & occ&#41;);
	
	bit = 1ULL << sq;
	do &#123;
		bit >>= 1;
		if &#40;bit & rowbits&#41;
			ret |= bit;
		else
			break;
	&#125; while (!&#40;bit & occ&#41;);
	return ret;
&#125;

uint64_t init_magic_bb_b&#40;int sq, uint64_t occ&#41;
&#123;
	uint64_t ret = 0;
	uint64_t bit, bit2;
	uint64_t rowbits = 0xFFULL << &#40;sq & ~7&#41;;

	bit = 1ULL << sq;
	bit2=bit;
	do &#123;
		bit <<= 8-1;
		bit2 >>= 1;
		if &#40;bit2 & rowbits&#41;
			ret |= bit;
		else
			break;
	&#125; while&#40;bit && !&#40;bit & occ&#41;);
	
	bit = 1ULL << sq;
	bit2 = bit;
	do &#123;
		bit <<= 8+1;
		bit2 <<= 1;
		if &#40;bit2 & rowbits&#41;
			ret |= bit;
		else
			break;
	&#125; while &#40;bit && !&#40;bit & occ&#41;);
	
	bit = 1ULL << sq;
	bit2 = bit;
	do &#123;
		bit >>= 8-1;
		bit2 <<= 1;
		if &#40;bit2 & rowbits&#41;
			ret |= bit;
		else
			break;
	&#125; while&#40;bit && !&#40;bit & occ&#41;);
	
	bit = 1ULL << sq;
	bit2 = bit;
	do &#123;
		bit >>= 8+1;
		bit2 >>= 1;
		if &#40;bit2 & rowbits&#41;
			ret |= bit;
		else
			break;
	&#125; while &#40;bit && !&#40;bit & occ&#41;);
	
	return ret;
&#125;

uint64_t init_magic_bb_occ&#40;const int* sq, int numSq, uint64_t linocc&#41;
&#123;
	uint64_t ret = 0;
	for&#40;int i = 0; i < numSq; i++)
		if &#40;linocc & &#40;1ULL << i&#41;)
			ret |= 1ULL << sq&#91;i&#93;;
	return ret;
&#125;
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Problem with bitboard knight attack generator

Post by lucasart »

Oh I forgot, here's how you use it:

Code: Select all

static inline uint64_t bishop_attack&#40;int sq, uint64_t occ&#41;
&#123; return *&#40;magic_bb_b_indices&#91;sq&#93; + ((&#40;occ & magic_bb_b_mask&#91;sq&#93;) * magic_bb_b_magics&#91;sq&#93;) >> magic_bb_b_shift&#91;sq&#93;)); &#125;

static inline uint64_t rook_attack&#40;int sq, uint64_t occ&#41;
&#123; return *&#40;magic_bb_r_indices&#91;sq&#93; + ((&#40;occ & magic_bb_r_mask&#91;sq&#93;) * magic_bb_r_magics&#91;sq&#93;) >> magic_bb_r_shift&#91;sq&#93;)); &#125;