Coding a bitboard class

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

Coding a bitboard class

Postby Matthias Gemuh » 16 Sep 2007, 14:13

Given an 80-bit bitboard A, how do I code operators for "~A" and "&& A" ?
The commented lines fail.
I am not yet testing, but do you see any other errors ?



class BITBOARD {
protected:
UINT16 data16;
UINT64 data64;

public:
BITBOARD() { data16 = 0; data64 = 0ui64; }
BITBOARD(UINT16 dat16, UINT64 dat64) { data16 = dat16; data64 = dat64; }

UINT16 GetData16() const { return data16; }
UINT64 GetData64() const { return data64; }
void PutData16(UINT16 dat16) { data16 = dat16; }
void PutData64(UINT64 dat64) { data64 = dat64; }

BITBOARD operator & (BITBOARD BitA) const
{ return(BITBOARD((GetData16() & BitA.GetData16()), (GetData64() & BitA.GetData64()))); }
BITBOARD operator | (BITBOARD BitA) const
{ return(BITBOARD((GetData16() | BitA.GetData16()), (GetData64() | BitA.GetData64()))); }
BITBOARD operator ^ (BITBOARD BitA) const
{ return(BITBOARD((GetData16() ^ BitA.GetData16()), (GetData64() ^ BitA.GetData64()))); }

bool operator && (BITBOARD BitA) const
{ return((GetData16() || GetData64()) && (BitA.GetData16() || BitA.GetData64())); }
bool operator || (BITBOARD BitA) const
{ return(GetData16() || BitA.GetData16() || GetData64() || BitA.GetData64()); }
bool operator == (BITBOARD BitA) const
{ return((GetData16() == BitA.GetData16()) && (GetData64() == BitA.GetData64())); }
bool operator != (BITBOARD BitA) const
{ return((GetData16() != BitA.GetData16()) || (GetData64() != BitA.GetData64())); }

BITBOARD & operator = (BITBOARD BitA)
{ PutData16(BitA.GetData16()); PutData64(BitA.GetData64()); return(*this); }
BITBOARD & operator &= (BITBOARD BitA)
{ PutData16(GetData16() & BitA.GetData16()); PutData64(GetData64() & BitA.GetData64()); return(*this); }
BITBOARD & operator |= (BITBOARD BitA)
{ PutData16(GetData16() | BitA.GetData16()); PutData64(GetData64() | BitA.GetData64()); return(*this); }
BITBOARD & operator ^= (BITBOARD BitA)
{ PutData16(GetData16() ^ BitA.GetData16()); PutData64(GetData64() ^ BitA.GetData64()); return(*this); }

// BITBOARD operator ~ (*this) { return(BITBOARD((~GetData16()), (~GetData64()))); }
// bool operator && (*this) { return((GetData16()) || (GetData64())); }

};
http://www.chessgui.com
http://w2410tmq9.homepage.t-online.de
BigLion, Taktix, ArcBishop, FindDraw, ChessGUI
User avatar
Matthias Gemuh
 
Posts: 189
Joined: 10 Jun 2006, 15:08

Re: Coding a bitboard class

Postby Matthias Gemuh » 16 Sep 2007, 15:54

Not yet tested, but this may work:

BITBOARD operator ~ () { return(BITBOARD((~GetData16()), (~GetData64()))); }
friend bool operator && (bool bA, const BITBOARD A) { return((bA) && ((A.GetData16()) || (A.GetData64()))); }
http://www.chessgui.com
http://w2410tmq9.homepage.t-online.de
BigLion, Taktix, ArcBishop, FindDraw, ChessGUI
User avatar
Matthias Gemuh
 
Posts: 189
Joined: 10 Jun 2006, 15:08

Re: Coding a bitboard class

Postby Matthias Gemuh » 16 Sep 2007, 16:35

Given an 80-bit bitboard A, how do I code an operator for "(A)" to check for at least one set bit ?
The commented line seems to fail.
I am not yet testing, but do you see any other errors ?



class BITBOARD {
protected:
UINT16 data16;
UINT64 data64;

public:
BITBOARD() { data16 = 0; data64 = 0ui64; }
BITBOARD(UINT16 dat16, UINT64 dat64) { data16 = dat16; data64 = dat64; }

UINT16 GetData16() const { return data16; }
UINT64 GetData64() const { return data64; }
void PutData16(UINT16 dat16) { data16 = dat16; }
void PutData64(UINT64 dat64) { data64 = dat64; }

BITBOARD operator & (BITBOARD BitA) const
{ return(BITBOARD((GetData16() & BitA.GetData16()), (GetData64() & BitA.GetData64()))); }
BITBOARD operator | (BITBOARD BitA) const
{ return(BITBOARD((GetData16() | BitA.GetData16()), (GetData64() | BitA.GetData64()))); }
BITBOARD operator ^ (BITBOARD BitA) const
{ return(BITBOARD((GetData16() ^ BitA.GetData16()), (GetData64() ^ BitA.GetData64()))); }

friend bool operator && (const BITBOARD A, const BITBOARD B)
{ return((A.GetData16() || A.GetData64()) && (B.GetData16() || B.GetData64())); }
friend bool operator || (const BITBOARD A, const BITBOARD B)
{ return(A.GetData16() || B.GetData16() || A.GetData64() || B.GetData64()); }
friend bool operator == (const BITBOARD A, const BITBOARD B)
{ return((A.GetData16() == B.GetData16()) && (A.GetData64() == B.GetData64())); }
friend bool operator != (const BITBOARD A, const BITBOARD B)
{ return((A.GetData16() != B.GetData16()) || (A.GetData64() != B.GetData64())); }

BITBOARD & operator = (BITBOARD BitA)
{ PutData16(BitA.GetData16()); PutData64(BitA.GetData64()); return(*this); }
BITBOARD & operator &= (BITBOARD BitA)
{ PutData16(GetData16() & BitA.GetData16()); PutData64(GetData64() & BitA.GetData64()); return(*this); }
BITBOARD & operator |= (BITBOARD BitA)
{ PutData16(GetData16() | BitA.GetData16()); PutData64(GetData64() | BitA.GetData64()); return(*this); }
BITBOARD & operator ^= (BITBOARD BitA)
{ PutData16(GetData16() ^ BitA.GetData16()); PutData64(GetData64() ^ BitA.GetData64()); return(*this); }

// bool operator () () { return((GetData16()) || (GetData64())); }
BITBOARD operator ~ () { return(BITBOARD((~GetData16()), (~GetData64()))); }
friend bool operator && (bool bA, const BITBOARD A) { return((bA) && ((A.GetData16()) || (A.GetData64()))); }

};
http://www.chessgui.com
http://w2410tmq9.homepage.t-online.de
BigLion, Taktix, ArcBishop, FindDraw, ChessGUI
User avatar
Matthias Gemuh
 
Posts: 189
Joined: 10 Jun 2006, 15:08

Re: Coding a bitboard class

Postby Aleks Peshkov » 16 Sep 2007, 18:10

1) Good interface should hide implementation details, so GetData16() and PutData64() is no-no!
2) C++ style does not recommend to overload (&&), (||) and (,) operators.
Given an 80-bit bitboard A, how do I code an operator for "(A)" to check for at least one set bit ?

You need to have (operator bool).
Code: Select all
operator bool () const { return (data64 | data16) != 0; }

3) I personally prefer to implement 80-bit set as structure of 3 x 32 bits. How you share 80 bit inside 96 bits is not important. You only need to be careful with (~) operator that is equivalent to XOR with your 80 significant bit constant.
4) It is much better to pass const references, not copies.
Code: Select all
BITBOARD& ^= (const BITBOARD& b) {
    data64 ^= b.data64;
    data16 ^= b.data16;
    return *this;
}


I suggest you to look how std::complex numbers and std::bitset template are declared in Standard C++ Library.
Aleks Peshkov
 
Posts: 27
Joined: 13 Jul 2007, 13:14

Re: Coding a bitboard class

Postby Matthias Gemuh » 16 Sep 2007, 19:57

Thanks a lot, Alex.

If I pass values by reference, can I still use the bitboard operators on referenced variables ? I mean:

BITBOARD& ^= (const BITBOARD& b)

void FunctionX(const BITBOARD& b)
{
BITBOARD a;
...
a ^= b; <--- referencing referenced "b" is ok ?
...
}


BTW, I thought using UINT64 may speed up the class on 64-Bit architecture.


Regards,
Matthias.
http://www.chessgui.com
http://w2410tmq9.homepage.t-online.de
BigLion, Taktix, ArcBishop, FindDraw, ChessGUI
User avatar
Matthias Gemuh
 
Posts: 189
Joined: 10 Jun 2006, 15:08

Re: Coding a bitboard class

Postby Aleks Peshkov » 16 Sep 2007, 20:47

Code: Select all
void FunctionX(const BITBOARD& b)
{
  a ^= b;   <--- referencing referenced "b" is ok ?
}

Ok.

BTW, I thought using UINT64 may speed up the class on 64-Bit architecture.
May be, you are right. If your specially target to 64-bit, then 2x64bit become much better. 2x64 is probably better then 3x32 even in 32-bit architecture. Your should not worry too early about actual implementation of the BITBOARD before you be able to test speed of real games.
Aleks Peshkov
 
Posts: 27
Joined: 13 Jul 2007, 13:14

Re: Coding a bitboard class

Postby Matthias Gemuh » 16 Sep 2007, 21:54

Thanks !

Through some reflex, I misspelled your name as "Alex" :o .

Matthias.
http://www.chessgui.com
http://w2410tmq9.homepage.t-online.de
BigLion, Taktix, ArcBishop, FindDraw, ChessGUI
User avatar
Matthias Gemuh
 
Posts: 189
Joined: 10 Jun 2006, 15:08

Re: Coding a bitboard class

Postby BrettVsop » 18 Nov 2007, 18:22

Why is it 80bit? What is the purpose of the extra 16bit variable?
BrettVsop
 
Posts: 50
Joined: 04 Nov 2007, 18:32

Re: Coding a bitboard class

Postby Tord Romstad » 18 Nov 2007, 19:02

BrettVsop wrote:Why is it 80bit? What is the purpose of the extra 16bit variable?

Simple: The board has 80 squares (10x8).

Tord
User avatar
Tord Romstad
 
Posts: 639
Joined: 09 Oct 2004, 12:49
Location: Oslo, Norway

Re: Coding a bitboard class

Postby BrettVsop » 18 Nov 2007, 21:50

Oh. This is for a chess variant? Does c++ not support a 80 bit integer?
BrettVsop
 
Posts: 50
Joined: 04 Nov 2007, 18:32

Re: Coding a bitboard class

Postby GothicChessInventor » 10 Dec 2007, 06:50

Matthias Gemuh wrote:Given an 80-bit bitboard A, how do I code operators for "~A" and "&& A" ?
The commented lines fail.
I am not yet testing, but do you see any other errors ?


I used operator overloading and just redefined the meaning of:

&, ^, |, >>, <<, >>=, <<= etc.

You define your 80-bit item as a struct composed of a 16-bit and 64-bit portion.

Let me know if you would like to see some of the code in Gothic Vortex.

Image
GothicChessInventor
 
Posts: 8
Joined: 26 Oct 2007, 20:07
Location: Philadelphia, PA

Re: Coding a bitboard class

Postby Matthias Gemuh » 10 Dec 2007, 15:53

GothicChessInventor wrote:
Matthias Gemuh wrote:Given an 80-bit bitboard A, how do I code operators for "~A" and "&& A" ?
The commented lines fail.
I am not yet testing, but do you see any other errors ?


I used operator overloading and just redefined the meaning of:

&, ^, |, >>, <<, >>=, <<= etc.

You define your 80-bit item as a struct composed of a 16-bit and 64-bit portion.

Let me know if you would like to see some of the code in Gothic Vortex.





Hi Ed,
yes you can send me code snippet as private mail.
Please include ROW() and COL(), for I now use:

#define ROW(x) (((x)-((x)%10)) / 10)
#define COL(x) (x % 10)

In ArcBishop, I use this very slow, unoptimized class:


class BITBOARD {
protected:
UINT16 data16;
UINT64 data64;

public:
BITBOARD() { data16 = (UINT16)0; data64 = 0ui64; }
BITBOARD(UINT16 dat16, UINT64 dat64) { data16 = (UINT16)dat16; data64 = (UINT64)dat64; }

UINT16 GetData16() const { return((UINT16) data16); }
UINT64 GetData64() const { return((UINT64) data64); }
void PutData16(UINT16 dat16) { data16 = (UINT16)dat16; }
void PutData64(UINT64 dat64) { data64 = (UINT64)dat64; }

BITBOARD operator & (BITBOARD const BitA) const
{ return(BITBOARD(((UINT16)data16 & BitA.GetData16()), ((UINT64)data64 & BitA.GetData64()))); }
BITBOARD operator | (BITBOARD const BitA) const
{ return(BITBOARD(((UINT16)data16 | BitA.GetData16()), ((UINT64)data64 | BitA.GetData64()))); }
BITBOARD operator ^ (BITBOARD const BitA) const
{ return(BITBOARD(((UINT16)data16 ^ BitA.GetData16()), ((UINT64)data64 ^ BitA.GetData64()))); }
BITBOARD operator << (UINT16 k) const {
if (k == 0) return(*this);
else if (k <= 16) return(BITBOARD((UINT16)(((UINT64)data16 << k) | ((UINT64)data64 >> (64-k))), ((UINT64)data64 << k)));
else if (k <= 64) return(BITBOARD((UINT16)((UINT64)data64 >> (64-k)), ((UINT64)data64 << k)));
else return(BITBOARD((UINT16)((UINT64)data64 << (k-64)), ((UINT64)data64 << k)));
}
BITBOARD operator >> (UINT16 k) const {
if (k == 0) return(*this);
else if (k <= 15) return(BITBOARD(((UINT16)data16 >> k), (((UINT64)data16 << (64-k)) | ((UINT64)data64 >> k))));
else if (k <= 63) return(BITBOARD((UINT16)0, (((UINT64)data16 << (64-k)) | ((UINT64)data64 >> k))));
else return(BITBOARD((UINT16)0, ((UINT64)data16 >> (k-64))));
}

friend bool operator && (const BITBOARD& const A, const BITBOARD& const B)
{ return((A.GetData16() || A.GetData64()) && (B.GetData16() || B.GetData64())); }
friend bool operator || (const BITBOARD& const A, const BITBOARD& const B)
{ return(A.GetData16() || B.GetData16() || A.GetData64() || B.GetData64()); }
friend bool operator == (const BITBOARD& const A, const BITBOARD& const B)
{ return((A.GetData16() == B.GetData16()) && (A.GetData64() == B.GetData64())); }
friend bool operator != (const BITBOARD& const A, const BITBOARD& const B)
{ return((A.GetData16() != B.GetData16()) || (A.GetData64() != B.GetData64())); }

friend BITBOARD operator & (const UINT64 A, const BITBOARD& const B) { return(BITBOARD(0, (A & B.GetData64()))); }
friend BITBOARD operator | (const UINT64 A, const BITBOARD& const B) { return(BITBOARD(0, (A | B.GetData64()))); }
friend BITBOARD operator & (const BITBOARD& const A, const UINT64 B) { return(BITBOARD(0, (B & A.GetData64()))); }
friend BITBOARD operator | (const BITBOARD& const A, const UINT64 B) { return(BITBOARD(0, (B | A.GetData64()))); }

BITBOARD & operator = (BITBOARD const BitA)
{ data16 = (UINT16)BitA.GetData16(); data64 = (UINT64)BitA.GetData64(); return(*this); }
BITBOARD & operator = (UINT64 A) { data16 = (UINT16)0; data64 = (UINT64)A; return(*this); }
BITBOARD & operator &= (BITBOARD const BitA)
{ data16 = (UINT16)(data16 & BitA.GetData16()); data64 = (UINT64)(data64 & BitA.GetData64()); return(*this); }
BITBOARD & operator |= (BITBOARD const BitA)
{ data16 = (UINT16)(data16 | BitA.GetData16()); data64 = (UINT64)(data64 | BitA.GetData64()); return(*this); }
BITBOARD & operator ^= (BITBOARD const BitA)
{ data16 = (UINT16)(data16 ^ BitA.GetData16()); data64 = (UINT64)(data64 ^ BitA.GetData64()); return(*this); }

bool operator == (UINT64 A) { return((data16 == 0) && (data64 == A)); }
friend bool IsEmpty(BITBOARD BitA) { return((BitA.GetData16() == 0) && (BitA.GetData64() == 0ui64)); }
friend bool IsNotEmpty(BITBOARD BitA) { return((BitA.GetData16()) || (BitA.GetData64())); }
// operator bool () const { return((data64 | data16) != 0ui64); }
BITBOARD operator ~ () { return(BITBOARD((~data16), (~data64))); }

bool GetBit(int nBit) const
{
if( nBit < 64 ) return (data64 & (1ui64 << nBit)) != 0ui64;
return (data16 & (1 << (nBit - 64))) != 0;
}
void SetBit(int nBit)
{
if( nBit < 64 ) data64 = data64 | (1ui64 << nBit);
else data16 = data16 | (1 << (nBit - 64));
}
void ClearBit(int nBit)
{
if( nBit < 64 ) data64 = data64 & (0xFFFFFFFFFFFFFFFFui64 ^ (1ui64 << nBit));
else data16 = data16 & (0xFFFF ^ (1 << (nBit - 64)));
}
void ToggleBit(int nBit)
{
if( nBit < 64 ) data64 = data64 ^ (1ui64 << nBit);
else data16 = data16 ^ (1 << (nBit - 64));
}

};





Best,
Matthias.
http://www.chessgui.com
http://w2410tmq9.homepage.t-online.de
BigLion, Taktix, ArcBishop, FindDraw, ChessGUI
User avatar
Matthias Gemuh
 
Posts: 189
Joined: 10 Jun 2006, 15:08


Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 35 guests