Page 1 of 7
Magic bitboards, Java
Posted: Sun Aug 19, 2007 9:17 pm
by Sargon
Hi
I'm thinking about rewriting my chess engine again. Some months ago, I remember reading something about magic bitboards as an alternative to rotated bitboards. I couldn't find any detailed information about it either in this forum nor via Google though. Is there any public info available somewhere? (if yes, where? :)
I'm also interested in hearing about first hand experience with bitboards and Java. Who is using bitboards in a Java engine? (as primary board representation - not just pawns or something like that) What classes/methods did you find most useful (with respect to speed) for bitboard representation and basic operations set/clear/test?
I've not yet decided whether my next rewrite will be in C++ (again) or Java. I really like Javas portability, but I fear I will miss things like templates. (not to speak of typedef and the const modifier) The current version makes heavy use of templates in the following way:
Code: Select all
class Board
{
[...]
bitboard_t whitePieces;
bitboard_t blackPieces;
[...]
template <colour_t> struct Trait;
};
template <> struct Board::Trait<White>
{
static inline pieces(const Board& b) { return b.whitePieces; };
[...]
};
[and analog for black]
This helps me in many ways to write code once, as opposed to:
Code: Select all
if(sideToMove == White) { do_this; }
else { do_that; }
Are there any features in Java that would help me here? (v1.6 is OK)
Thanks in advance. :)
Sargon
Re: Magic bitboards, Java
Posted: Sun Aug 19, 2007 10:23 pm
by Alessandro Damiani
About the Java part:
In Java Generics are like templates in C++. See
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf. I don't know C++'s templates, but I wonder why templates/Generics should be used in your case. If I guessed your intention right from looking at the C++ code I would write it this way in Java:
Code: Select all
class Board {
static interface Trait {
Bitboard pieces();
}
class TraitWhite implements Trait {
Bitboard pieces() {
return whitePieces;
}
}
class TraitBlack implements Trait {
Bitboard pieces() {
return blackPieces;
}
}
Bitboard whitePieces;
Bitboard blackPieces;
Trait traitWhite = new TraitWhite();
Trait traitBlack = new TraitBlack();
}
With this code just pass Board.Trait to other methods:
Code: Select all
void foo(Board.Trait trait) {
Bitboard pieces = trait.pieces();
while (!pieces.isEmpty()) {
...
}
}
Re: Magic bitboards, Java
Posted: Sun Aug 19, 2007 10:31 pm
by Pradu
Not complete and will probably not be until I can get around to proving all the optimal magics... but here are all the facts:
http://www.prism.gatech.edu/~gtg365v/Bu ... boards.pdf
If you are not interested in proving optimal magics, you can skip reading the "generating optimal magics" part and you can generate magic keys by trying out random numbers.
Also take a look at threads on the Winboard Forum for various enhancements like Grant Osbrone's 32-bit optimized versions and Gerd's separated-direction version.
Re: Magic bitboards, Java
Posted: Mon Aug 20, 2007 12:28 am
by Guetti
Hallo Daniel,
Es gibt viel Info auf dem Winboard forum ueber magic bitboards. Ich habe schnell ein paar links rausgesucht (sicher nicht vollstaendig):
http://wbforum.vpittlik.org/viewtopic.php?t=5452
http://wbforum.vpittlik.org/viewtopic.php?t=5997
Ich benutze im Moment nicht Pradus magic, sondern Gerd Isenbergs Methode auch "Kindergarten" Methode genannt. Der Vorteil sind die einfache Implementation, cache friendliness und wenig initialisationen.
Die Methode ist fast so effektiv wie Pradu's magic. Hier der 1.5 KB und der 9.5 KB approach:
http://wbforum.vpittlik.org/viewtopic.p ... 400&t=4523
http://wbforum.vpittlik.org/viewtopic.p ... 902&t=4523
http://wbforum.vpittlik.org/viewtopic.p ... 755&t=4523
Re: Magic bitboards, Java
Posted: Mon Aug 20, 2007 12:45 am
by Guetti
Here a explanation of Gerds Kindergarten Magics:
http://wbforum.vpittlik.org/viewtopic.php?t=5958
Re: Magic bitboards, Java
Posted: Mon Aug 20, 2007 9:51 am
by Sargon
Hi Pradu
Thanks for the link! Exactly what I was looking for. I'm not just interested in the algorithm but would also like to understand how it works. :)
Sargon
Re: Magic bitboards, Java
Posted: Mon Aug 20, 2007 9:53 am
by Sargon
Hi Guetti :)
Thanks for the links. I'll check the Winboard forum too. :) But... "kindergarten"? When it comes to Gerd, it usually involves Assembler code! Didn't know kids these days do that in kindergarten already. :)
Sargon
Re: Magic bitboards, Java
Posted: Mon Aug 20, 2007 10:14 am
by Sargon
Hi Allessandro
I'm aware that Java supports templates in version 5 and later. Unfortunately they're way less flexible than the C++ templates. For example, in Java the template parameter is always a class type. In C++ you can also make us of partial specialization, like I did.
While your version works for normal methods, it doesn't work for static methods, since you don't have polymorphism there. Anyway, thanks for the idea! :)
Sargon
Re: Magic bitboards, Java
Posted: Mon Aug 20, 2007 12:25 pm
by Guetti
Sargon wrote:Hi Guetti
Thanks for the links. I'll check the Winboard forum too.

But... "kindergarten"? When it comes to Gerd, it usually involves Assembler code! Didn't know kids these days do that in kindergarten already.
Sargon
"Kindergarten" in the sense of easyness to implement. It takes some time to understand, but Pradu's magic, well
If you already have a normal bitboard move generator (not rotated), you probably only have to add and correctly initialize these four arrays for the "Kindergarten" method:
Code: Select all
extern unsigned char first_rank_attacks[64][8]; // bitsets on first rank for square x and file y
extern Bitboard a_file_attacks[64][8]; // bitsets on a-file for square x and rank y
extern Bitboard fillup_attacks[64][8]; // 0x0101010101010101ULL * first_rank_attacks
extern Bitboard diaga1h8_mask[64]; // bits on diagonal of square x
extern Bitboard diagh1a8_mask[64]; // bits on antidiagonal of square x
and the attack functions described in the winboard threads:
Code: Select all
/*
// Gerd's 1.5 kb approach
inline Bitboard rankAttacks(Bitboard occ, int sq)
{
int f = sq & 7;
int r = sq & ~7; // rank * 8
int o = (int) (occ >> (r + 1)) & 63;
Bitboard g = first_rank_attacks[o][f];
return (g << r);
}
inline Bitboard fileAttacks(Bitboard occ, int sq)
{
int f = sq & 7;
occ = 0x0101010101010101ULL & (occ >> f); // a-file
occ = (0x0080402010080400ULL * occ) >> 58;
occ = (0x8040201008040201ULL * first_rank_attacks[occ][(sq^56)>>3]);
return ((0x8080808080808080ULL & occ) >> (f^7));
}
inline Bitboard diagonalAttacks(Bitboard occ, int sq)
{
int f = sq & 7;
occ = (diaga1h8_mask[sq] & occ);
occ = (0x0202020202020202ULL * occ) >> 58;
occ = (0x0101010101010101ULL * first_rank_attacks[occ][f]);
return (diaga1h8_mask[sq] & occ);
}
inline Bitboard antidiagonalAttacks(Bitboard occ, int sq)
{
int f = sq & 7;
occ = (diagh1a8_mask[sq] & occ);
occ = (0x0202020202020202ULL * occ) >> 58;
occ = (0x0101010101010101ULL * first_rank_attacks[occ][f]);
return (diagh1a8_mask[sq] & occ);
}
*/
// Gerds 9.5kb approach
inline Bitboard rankAttacks(Bitboard occ, int sq)
{
int f = sq & 7; // file
int r = sq & ~7; // rank*8
int o = (int) (occ >> (r+1)) & 63;
return (Bitboard) first_rank_attacks[o][f] << r;
}
inline Bitboard fileAttacks(Bitboard occ, int sq)
{
int f = sq & 7; // file
occ = 0x0101010101010101ULL & (occ >> f); // a-file
int o = (0x0080402010080400ULL * occ) >> 58;
return (a_file_attacks[o][sq>>3]) << f;
}
inline Bitboard diagonalAttacks(Bitboard occ, int sq)
{
int f = sq & 7; // file
occ = (diaga1h8_mask[sq] & occ);
int o = (0x0202020202020202ULL * occ) >> 58;
return (diaga1h8_mask[sq] & fillup_attacks[o][f]);
}
inline Bitboard antidiagonalAttacks(Bitboard occ, int sq)
{
int f = sq & 7; // file
occ = (diagh1a8_mask[sq] & occ);
int o = (0x0202020202020202ULL * occ) >> 58;
return (diagh1a8_mask[sq] & fillup_attacks[o][f]);
}
and you're set.
This method uses one (or 2) 64-bit multiplication(s) per attack getter, which is fine on 64-bit systems but takes a speed hit on 32-bit. (I think Gerd posted a more 32-bit friendly method in the same thread).
Re: Magic bitboards, Java
Posted: Mon Aug 20, 2007 12:45 pm
by fluxroot
Sargon wrote:Hi Allessandro
I'm aware that Java supports templates in version 5 and later. Unfortunately they're way less flexible than the C++ templates. For example, in Java the template parameter is always a class type. In C++ you can also make us of partial specialization, like I did.
While your version works for normal methods, it doesn't work for static methods, since you don't have polymorphism there. Anyway, thanks for the idea!
Sargon
I'm just porting my engine the other way around, from Java to C++. Though both languages are OO, there's
a lot of difference in designing your classes. Don't try to map them one-to-one. This was my big mistake...
