Moderator: Andres Valverde
Gerd's Routine:Onno Garms wrote:I offten need a bitboard of squares between two squares. Ideally, this is
- the connecting segment (diagonal, row, or column), if one exists
- empty when the squares differ by a knight's move
- all 64 bit in all other cases
Currently I have a lookup table for this. But as the table is quite large (32k) compared to the complexity of its content, I think it might be better to calculate online.
However, I have not yet found a fast way to do that. Any ideas?
My actual board is similar to this:
struct
{
u64 bb;//bit of sq
u64 bMap;//bishop map w/o center
u64 rMap;
//....
} board[64];
//test if sq x, y along a bishop path and free of blocking bits
__inline int xyBishopAttack(board_t * board, int x, int y, u64 blocks){
//may pass a depleted blocks
assert(x != y);
i64 u;
//(u - ((u & - u) << 1) gets in-between bits of a bitboard with 2 bits
return board->brd[x].bMap & board->brd[y].bb &&
!(u - ((u & -(u = board->brd[x].bb | board->brd[y].bb)) << 1)
& board->brd[x].bMap & board->brd[y].bMap & blocks);
}
(board->brd[x].bb - 1) ^ (board->brd[y].bb -1)
u = board->brd[x].bb | board->brd[y].bb
u
Why do you OR the two single bits? Isn't
Code:
(board->brd[x].bb - 1) ^ (board->brd[y].bb -1)
faster?
BTW, AFAIK the C standard does not guarantee that
Code:
u = board->brd[x].bb | board->brd[y].bb
gets evaluated before
Code:
u
My C syntax is vague. Does not the parenthesis force the order of evaluation?
> cat order.cpp
#include <iostream>
int main ()
{
int u;
std::cout << u - ((u & -(u = 1)) << 1);
}
> g++ -Wall order.cpp
order.cpp: In function 'int main()':
order.cpp:5: warning: operation on 'u' may be undefined
order.cpp:5: warning: operation on 'u' may be undefined
The codes pass the relevant asserts.
Quote:
My C syntax is vague. Does not the parenthesis force the order of evaluation?
It only groups what is inside the parenthesis. It does not determine which side of & gets evaluated first. The compiler may make its own decision.
When parentheses are used to group the subexpressions, they alter the precedence and also the order in which the expression is evaluated, as shown in Figure 4.2.
#include <stdio.h>
#include <conio.h>
int main ()
{
int u, v;
v = u - ( (u & -(u = 1)) << 1);
printf("%d", v);
//v = -1
getch();
return 1;
}
Chan Rasjid wrote:The above builds in Visual C++ 4.0 without error or warning and prints
Not every compiler prints warnings on every potential problem. For example, Visual Studio also prints no warnings
- when order in initialization list of constructor differs from the order of the member variables
- when a class has virtual functions but no virtual constructor.
The absence of a warning in a particular compiler does not mean that the code is OK.
Onno Garms wrote:Chan Rasjid wrote:The above builds in Visual C++ 4.0 without error or warning and prints
Not every compiler prints warnings on every potential problem. For example, Visual Studio also prints no warnings
- when order in initialization list of constructor differs from the order of the member variables
- when a class has virtual functions but no virtual constructor.
The absence of a warning in a particular compiler does not mean that the code is OK.
BTW, consider a free upgrade to Visual Studio 2005 express edition.
int main ()
{
int u, v;
v = u - ( (u & -(u = 1)) << 1);//A
printf("%d", v);
//v = -1
getch();
return 1;
}
Hi,Chan Rasjid wrote:
- Code: Select all
v = u - ( (u & -(u = 1)) << 1);//A
Onno Garms wrote:I offten need a bitboard of squares between two squares. Ideally, this is
- the connecting segment (diagonal, row, or column), if one exists
- empty when the squares differ by a knight's move
- all 64 bit in all other cases
Currently I have a lookup table for this. But as the table is quite large (32k) compared to the complexity of its content, I think it might be better to calculate online.
However, I have not yet found a fast way to do that. Any ideas?
u64 inbetweenBy0x88Diff[240];
u64 inBetween(u32 sq1, u32 sq2)
{
return _rotl64(inbetweenBySigned0x88Diff[sq2+(sq2&56)-sq1-(sq1&56)+120], sq1);
}
u64 inBetweenWithoutLookup(u32 sq1, u32 sq2)
{
const u64 o = 1, m1 = -o;
const u64 a2a7 = 0x0001010101010100;
const u64 b7h1 = 0x0002040810204080;
const u64 b2h8 = 0x8040201008040200;
u64 btwnbits, raybits;
u32 rankDiff, fileDiff, antiDiff, diaxDiff;
btwnbits = (o<<sq1) - o;
btwnbits ^= (o<<sq2) - o;
rankDiff =((sq2 |7) - sq1)>>3;
fileDiff = (sq2 &7) - (sq1 &7);
antiDiff = rankDiff + fileDiff;
rankDiff = rankDiff & 15;
fileDiff = fileDiff & 15;
antiDiff = antiDiff & 15;
diaxDiff = rankDiff ^ fileDiff;
raybits =((rankDiff-1)>>26)*2;
raybits |= (m1+fileDiff)& a2a7;
raybits |= (m1+antiDiff)& b7h1;
raybits |= (m1+diaxDiff)& b2h8;
raybits *= btwnbits &-btwnbits;
return raybits & btwnbits;
}
Gerd Isenberg wrote:What do you intend with all bits set (-1) for none slidings and knight distances btw?
Onno Garms wrote:Gerd Isenberg wrote:What do you intend with all bits set (-1) for none slidings and knight distances btw?
I'm not sure if I really need this. This is only the current content of my lookup table.
The idea was that there exists a piece that can move from sq1 to sq2, if and only if between(sq1,sq2) & occupied_bb != 0.
Gerd Isenberg wrote:to check whether a move is (pseudo) legal, one has to consider piece types anyway.
bob wrote:This is simply a bad programming practice.
Return to Programming and Technical Discussions
Users browsing this forum: No registered users and 24 guests