Suppose that bitboards are mapped so that H1 = 0. There is a loop initializing 64 bitboards denoting single square and a function printing a bitboard. One of them is wrong, since when I print any bitboard, only the upper part of the diagram is filled - the rest is all zeroes. Where's the bug?
--------
U64 bbSQ[64]
for (int i=0;i<32;i++) {
bbSQ = 0x0000000000000001<<i & 0x00000000FFFFFFFF;
bbSQ[i+32] = 0x0000000100000000<<i;
}
--------
void util_printBB(U64 bb) {
for (int i=0; i < 64; i++) {
int number = ( bb & bbSQ );
if ( number != 0) number = 1; // we need just yes or no
printf(" %d", number);
if ( (i + 1) % 8 == 0 ) printf("\n"); // take care of board edges
}
}
beginner bitboard bug question
Moderators: hgm, Rebel, chrisw
-
- Posts: 895
- Joined: Mon Jan 15, 2007 11:23 am
- Location: Warsza
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Re: beginner bitboard bug question
It might be helpful to express all 64 bit hexadecimal constants with a "ull" suffix. Or "ULL" if you prefer.
Example: bb = 0x0123456789abcdefull;
Example: bb = 0x0123456789abcdefull;
Re: beginner bitboard bug question
int number = ( bb & bbSQ );
U64 number = ( bb & bbSQ );
Note that the compiler told you that if ints are not 64 bits.
HJ.
U64 number = ( bb & bbSQ );
Note that the compiler told you that if ints are not 64 bits.
HJ.
-
- Posts: 2251
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: beginner bitboard bug question
PK wrote:Suppose that bitboards are mapped so that H1 = 0. There is a loop initializing 64 bitboards denoting single square and a function printing a bitboard. One of them is wrong, since when I print any bitboard, only the upper part of the diagram is filled - the rest is all zeroes. Where's the bug?
--------
U64 bbSQ[64]
for (int i=0;i<32;i++) {
bbSQ = 0x0000000000000001<<i & 0x00000000FFFFFFFF;
bbSQ[i+32] = 0x0000000100000000<<i;
}
--------
void util_printBB(U64 bb) {
for (int i=0; i < 64; i++) {
int number = ( bb & bbSQ );
if ( number != 0) number = 1; // we need just yes or no
printf(" %d", number);
if ( (i + 1) % 8 == 0 ) printf("\n"); // take care of board edges
}
}
As Harald already mentioned your number type was not sufficient.
I wouldwrite it that way, also to avoid problems with 64-bit constants ...
Otherwise, as Steven mentioned 64-bit constants may require a suffix, see the C64 macro in cpw.
Code: Select all
U64 bbSQ[64];
void initbbSQ()
{
bbSQ[0] = 1;
for (int i=1; i<64; i++)
bbSQ[i] = 2*bbSQ[i-1];
}
// INLINE
int /*bool*/ isBitSet(U64 bb, int idx)
{
return (bb & bbSQ[i]) != 0;
}
void util_printBB(U64 bb)
{
static char digit[] = "01"; // ".1";
for (int i=0; i < 64; i++)
{
printf(" %c", digit[isBitSet(bb, i )]); //printf(" %d", isBitSet(bb, i ));
if ( (i % 8) == 7 )
printf("\n"); // take care of board edges
}
}
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: beginner bitboard bug question
PK wrote:Suppose that bitboards are mapped so that H1 = 0. There is a loop initializing 64 bitboards denoting single square and a function printing a bitboard. One of them is wrong, since when I print any bitboard, only the upper part of the diagram is filled - the rest is all zeroes. Where's the bug?
--------
U64 bbSQ[64]
for (int i=0;i<32;i++) {
bbSQ = 0x0000000000000001<<i & 0x00000000FFFFFFFF;
bbSQ[i+32] = 0x0000000100000000<<i;
}
--------
void util_printBB(U64 bb) {
for (int i=0; i < 64; i++) {
int number = ( bb & bbSQ );
if ( number != 0) number = 1; // we need just yes or no
printf(" %d", number);
if ( (i + 1) % 8 == 0 ) printf("\n"); // take care of board edges
}
}
Your constants above are 32 bit values. use constants of the form:
nnnnnnnnnnnnnnnnnnULL, as otherwise the compiler will truncate to 32 bits before it does anything at all...
-
- Posts: 318
- Joined: Thu Mar 09, 2006 1:07 am
Re: beginner bitboard bug question
Hi
There are a few usefull defines and functions for you. I use them with MSVC++. It begins with macros for constants and for printf formats.
With GCC this may be
I also use this typedef
and a bitboard class
May be you have to change it a bit for other compilers.
You may even wrap it in some #ifdef ... #endif blocks.
Here ist the fun stuff:
Perhaps you find something useful in it.
Harald
There are a few usefull defines and functions for you. I use them with MSVC++. It begins with macros for constants and for printf formats.
Code: Select all
#define C64(c) c##ui64
#define U64_F "I64u"
#define X64_F "016I64x"
#define X64_S "I64x"
Code: Select all
#define C64(c) c##ULL
Code: Select all
typedef unsigned __int64 uint64;
typedef uint64 Bits64;
Code: Select all
class Bitboard
{
private:
Bits64 bb_; // This is the real 64 bit Bitboard. The rest ist just class stuff.
public:
// ...
};
You may even wrap it in some #ifdef ... #endif blocks.
Here ist the fun stuff:
Code: Select all
#include "..."
using namespace std;
/**
Construct a bitboard from a 2 byte coordinate string. Only one bit is set.
Construct a bitboard from a 16 byte hex-string.
Construct a bitboard from a 64 byte 01-string.
Construct a bitboard from a 8 lines 8 rows 01-string.
*/
Bitboard::Bitboard( const string &s )
{
bb_ = 0;
if ( s.size() == 2 )
coordinate( s );
else if ( s.size() == 16 )
hex( s );
else if ( s.size() == 64 )
txt01( s );
else
txt8lines( s );
}
/**
Assign a bitboard from a 2 byte coordinate string. Only one bit is set.
Assign a bitboard from a 16 byte hex-string.
Assign a bitboard from a 64 byte 01-string.
Assign a bitboard from a 8 lines 8 rows 01-string.
*/
Bitboard &Bitboard::operator=( const string &s )
{
bb_ = 0;
if ( s.size() == 2 )
coordinate( s );
else if ( s.size() == 16 )
hex( s );
else if ( s.size() == 64 )
txt01( s );
else
txt8lines( s );
return *this;
}
/**
Get a 16 byte hex-string from a bitboard.
*/
string Bitboard::hex() const
{
char buf[17];
sprintf( buf, "%"X64_F"", bb_ );
return string(buf);
}
/**
Get a bitboard from a 16 byte hex-string.
*/
void Bitboard::hex( const string &txt )
{
bb_ = 0;
if ( txt.size() != 16 )
{
logf << "error: txt01 " << txt << endl;
return;
}
if ( txt.find_first_not_of( "0123456789abcdefABCDEF" ) != string::npos )
{
logf << "error: txt01 " << txt << endl;
return;
}
sscanf( txt.c_str(), "%"X64_S"", &bb_ );
}
/**
Get a 64 byte 01-string from a bitboard.
*/
string Bitboard::txt01() const
{
string txt;
Bits64 s = C64(1) << 63;
while ( s > 0 )
{
txt += ( bb_ & s ? '1' : '0' );
s >>= 1;
}
return txt;
}
/**
Get a bitboard from a 64 byte 01-string.
*/
void Bitboard::txt01( const string &txt )
{
bb_ = 0;
if ( txt.size() != 64 )
{
logf << "error: txt01 " << txt << endl;
return;
}
if ( txt.find_first_not_of( "01" ) != string::npos )
{
logf << "error: txt01 " << txt << endl;
return;
}
Bits64 s = C64(1) << 63;
for ( int i = 0; i < 64; ++i, s >>= 1 )
{
if ( txt[i] == '1' )
bb_ |= s;
}
}
/**
Get a 8 lines 8 rows 01-string from a bitboard.
*/
string Bitboard::txt8lines() const
{
string txt;
int z = 0;
Bits64 s = C64(1) << 63;
while ( s > 0 )
{
txt += ( bb_ & s ? '1' : '0' );
s >>= 1;
if ( (++z % 8) == 0 && s > 0 )
txt += '\n';
}
return txt;
}
/**
Get a bitboard from a 8 lines 8 rows 01-string.
*/
void Bitboard::txt8lines( const string &txt )
{
bb_ = 0;
if ( txt.size() < 8 * 8 + 7 )
{
logf << "error: txt8lines " << txt << endl;
return;
}
if ( txt.find_first_not_of( "01 \t\n" ) != string::npos )
{
logf << "error: txt8lines " << txt << endl;
return;
}
Bits64 s = C64(1) << 63;
int i = 0;
while ( i < txt.size() && s > 0 )
{
char c = txt[i++];
if ( c < '0' )
continue;
if ( c == '1' )
bb_ |= s;
s >>= 1;
}
if ( s != 0 )
{
logf << "error: txt8lines " << txt << endl;
return;
}
}
/**
Get a 2 byte coordinate string from a bitboard with only one bit set.
If more or less bits are set the result is "??".
The normal results are "a1", ..., "h8".
*/
string Bitboard::coordinate() const
{
if ( !only_1_bit() )
{
logf << "coordinate ?? " << hex() << endl;
return "??";
}
byte ep = msb_nr();
string s;
s += "hgfedcba"[ep % 8];
s += "12345678"[ep / 8];
return s;
}
/**
Get bitboard from a 2 byte coordinate string. Only one bit is set.
If the coordinates are invalid the bitboard is empty (0).
Valid coordinate strings are "a1", ..., "h8".
*/
void Bitboard::coordinate( const string &s )
{
bb_ = 0;
if ( s.size() != 2 )
{
logf << "error: coordinate " << s << endl;
return;
}
int line = s[0];
if ( line >= 'a' && line <= 'h' )
line = 'h' - line;
else if ( line >= 'A' && line <= 'H' )
line = 'H' - line;
else
{
logf << "error: coordinate " << s << endl;
return;
}
int row = s[1];
if ( row >= '1' && row <= '8' )
row = row - '1';
else
{
logf << "error: coordinate " << s << endl;
return;
}
bb_ = set_one_bit( row * 8 + line );
}
Harald
-
- Posts: 895
- Joined: Mon Jan 15, 2007 11:23 am
- Location: Warsza
Re: beginner bitboard bug question
Thank You very much for Your help and code samples.
I have another Microsoft-specific question: how to disable all those silly gets/scanf warnings? As You can see from the above example, I have a problem with finding real ones, which would be easier without all that garbage.
Pawel Koziol
I have another Microsoft-specific question: how to disable all those silly gets/scanf warnings? As You can see from the above example, I have a problem with finding real ones, which would be easier without all that garbage.
Pawel Koziol
Pawel Koziol
http://www.pkoziol.cal24.pl/rodent/rodent.htm
http://www.pkoziol.cal24.pl/rodent/rodent.htm
-
- Posts: 147
- Joined: Wed Jun 06, 2007 10:01 am
- Location: United States
- Full name: Mike Leany
Re: beginner bitboard bug question
I'm afraid your gets() warnings are real ones, and your scanf() warnings may be as well (although I can't be certain without knowing what they are). You can disable these warnings, but in this case, I think it may be just a band-aid that hides the real problem. Usually fixing the issue that causes the warning is better than disabling the warning.PK wrote:Thank You very much for Your help and code samples.
I have another Microsoft-specific question: how to disable all those silly gets/scanf warnings? As You can see from the above example, I have a problem with finding real ones, which would be easier without all that garbage.
Pawel Koziol
In your specific case, you should use fgets() instead of gets(), since it allows you to specify the maximum number of characters to read, while gets() does not. Overflowing your buffer would be bad. See here for information on why gets is bad (particularly under "BUGS"): http://www.rt.com/man/gets.3.html
If you're using scanf() to input strings of arbitrary length, you might consider specifying a maximum field width. Again, overflowing your buffer would be bad.
If you absolutely MUST disable a warning, here's one way to do it in MSVC: http://msdn.microsoft.com/en-us/library ... 80%29.aspx
When reasonable, I would recommend suppressing the warning for one line over disabling it completely.
Re: beginner bitboard bug question
define that for example :PK wrote:Thank You very much for Your help and code samples.
I have another Microsoft-specific question: how to disable all those silly gets/scanf warnings? As You can see from the above example, I have a problem with finding real ones, which would be easier without all that garbage.
Pawel Koziol
/D _CRT_SECURE_NO_DEPRECATE
HJ.