佳佳象棋 2007-6-23 13:42
Bitboards and pinned pieces
As I mentioned in another thread, I wrote a little magic number generator yesterday. Because it would be a waste to produce these numbers without using them for anything, I've now modified the bitboard version of my program (which used classical rotated bitboards) to use magic-based attack generation instead.
Most of the work was very easy, but I had a few small problems. A problem I still haven't been able to solve cleanly is to find a bitboard of all pinned pieces for a given side. My old rotated bitboard code looks like this:
Code:
Bitboard Position::pinned_pieces(Color c) const {
Bitboard pinned = EmptyBoardBB, b1, b2;
Square ksq = this->king_square(c), s;
Color them = opposite_color(c);
for(Direction d = DIR_E; d <= DIR_NW; d++) {
b1 = this->sliders_of_color(them, d);
b2 = this->sliding_attacks(ksq, d) & this->pieces_of_color(c);
while(b2) {
s = pop_1st_bit(&b2);
if(this->sliding_attacks(s, d) & b1) set_bit(&pinned, s);
}
}
return pinned;
}
My current magic bitboard version is a lot messier:
Code:
Bitboard Position::pinned_pieces(Color c) const {
Bitboard b1, b2, b3, pinned, sliders;
Square ksq = this->king_square(c);
Color them = opposite_color(c);
pinned = EmptyBoardBB;
b1 = this->occupied_squares();
sliders = this->rooks_and_queens_of_color(them);
if(sliders) {
b2 = this->rook_attacks(ksq) & this->pieces_of_color(c);
while(b2) {
b3 = b2 & -b2;
b2 ^= b3;
if(rook_attacks_bb(ksq, b1 ^ b3) & sliders) pinned |= b3;
}
}
sliders = this->bishops_and_queens_of_color(them);
if(sliders) {
b2 = this->bishop_attacks(ksq) & this->pieces_of_color(c);
while(b2) {
b3 = b2 & -b2;
b2 ^= b3;
if(bishop_attacks_bb(ksq, b1 ^ b3) & sliders) pinned |= b3;
}
}
return pinned;
}
This is fast enough and has the advantage of avoiding the dreaded bitscanning, but looks awfully ugly and complicated. There has to be a better way to do this. Because magic bitboards generate attacks in several directions at once, I would expect a good magic bitboard solution to be shorter and simpler than the rotated bitboard solution.
Any ideas about how to improve this code?
Tord
佳佳象棋 2007-7-10 13:27
位棋盘可用来做评估,但中象是9X10格的,怎样在中象中解决这个问题呢,奇兵很好的解决了这个问题,将棋盘分成上下二部分,这样就能很好的用MMX的64位指令来优化了.
PIN, 主要用来做解将算法,但中象多了一个炮,与马的别脚,就复杂多了.