/*
- Glaurung, a UCI chess playing engine.
- Copyright (C) 2004-2008 Tord Romstad
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2009 Marco Costalba
- Glaurung is free software: you can redistribute it and/or modify
+ Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
- Glaurung is distributed in the hope that it will be useful,
+ Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
#include <iostream>
#include "bitboard.h"
+#include "bitcount.h"
#include "direction.h"
-////
-//// Constants and variables
-////
-
-const Bitboard SquaresByColorBB[2] = {BlackSquaresBB, WhiteSquaresBB};
-
-const Bitboard FileBB[8] = {
- FileABB, FileBBB, FileCBB, FileDBB, FileEBB, FileFBB, FileGBB, FileHBB
-};
-
-const Bitboard NeighboringFilesBB[8] = {
- FileBBB, FileABB|FileCBB, FileBBB|FileDBB, FileCBB|FileEBB,
- FileDBB|FileFBB, FileEBB|FileGBB, FileFBB|FileHBB, FileGBB
-};
-
-const Bitboard ThisAndNeighboringFilesBB[8] = {
- FileABB|FileBBB, FileABB|FileBBB|FileCBB,
- FileBBB|FileCBB|FileDBB, FileCBB|FileDBB|FileEBB,
- FileDBB|FileEBB|FileFBB, FileEBB|FileFBB|FileGBB,
- FileFBB|FileGBB|FileHBB, FileGBB|FileHBB
-};
-
-const Bitboard RankBB[8] = {
- Rank1BB, Rank2BB, Rank3BB, Rank4BB, Rank5BB, Rank6BB, Rank7BB, Rank8BB
-};
-
-const Bitboard RelativeRankBB[2][8] = {
- {
- Rank1BB, Rank2BB, Rank3BB, Rank4BB, Rank5BB, Rank6BB, Rank7BB, Rank8BB
- },
- {
- Rank8BB, Rank7BB, Rank6BB, Rank5BB, Rank4BB, Rank3BB, Rank2BB, Rank1BB
- }
-};
-
-const Bitboard InFrontBB[2][8] = {
- {
- Rank2BB | Rank3BB | Rank4BB | Rank5BB | Rank6BB | Rank7BB | Rank8BB,
- Rank3BB | Rank4BB | Rank5BB | Rank6BB | Rank7BB | Rank8BB,
- Rank4BB | Rank5BB | Rank6BB | Rank7BB | Rank8BB,
- Rank5BB | Rank6BB | Rank7BB | Rank8BB,
- Rank6BB | Rank7BB | Rank8BB,
- Rank7BB | Rank8BB,
- Rank8BB,
- EmptyBoardBB
- },
- {
- EmptyBoardBB,
- Rank1BB,
- Rank2BB | Rank1BB,
- Rank3BB | Rank2BB | Rank1BB,
- Rank4BB | Rank3BB | Rank2BB | Rank1BB,
- Rank5BB | Rank4BB | Rank3BB | Rank2BB | Rank1BB,
- Rank6BB | Rank5BB | Rank4BB | Rank3BB | Rank2BB | Rank1BB,
- Rank7BB | Rank6BB | Rank5BB | Rank4BB | Rank3BB | Rank2BB | Rank1BB
- }
-};
-
#if defined(USE_COMPACT_ROOK_ATTACKS)
Bitboard RankAttacks[8][64], FileAttacks[8][64];
int BAttackIndex[64];
Bitboard BAttacks[0x1480];
-Bitboard SetMaskBB[64];
-Bitboard ClearMaskBB[64];
+Bitboard SetMaskBB[65];
+Bitboard ClearMaskBB[65];
Bitboard StepAttackBB[16][64];
Bitboard RayBB[64][8];
////
namespace {
+
void init_masks();
void init_ray_bitboards();
void init_attacks();
/// pop_1st_bit() finds and clears the least significant nonzero bit in a
/// nonzero bitboard.
-#if defined(USE_32BIT_ATTACKS) && defined(_MSC_VER)
+#if defined(USE_32BIT_ATTACKS)
-// On 32bit system compiled with MSVC this verion seems
-// slightly faster then the standard one.
+// Use type-punning
+union b_union {
-Square pop_1st_bit(Bitboard *b) {
+ Bitboard b;
+ struct {
+ uint32_t l;
+ uint32_t h;
+ } dw;
+};
- unsigned long index;
- uint32_t *l, *h;
+// WARNING: Needs -fno-strict-aliasing compiler option
+Square pop_1st_bit(Bitboard *bb) {
- if (*(l = (uint32_t*)b) != 0)
- {
- _BitScanForward(&index, *l);
- *l &= ~(1 << index);
- }
- else if (*(h = (uint32_t*)b + 1) != 0)
- {
- _BitScanForward(&index, *h);
- *h &= ~(1 << index);
- index += 32;
- } else
- return SQ_NONE;
-
- return Square(index);
+ b_union u;
+ uint32_t b;
+
+ u.b = *bb;
+
+ if (u.dw.l)
+ {
+ b = u.dw.l;
+ *((uint32_t*)bb) = b & (b - 1);
+ b ^= (b - 1);
+ }
+ else
+ {
+ b = u.dw.h;
+ *((uint32_t*)bb+1) = b & (b - 1); // Little endian only?
+ b = ~(b ^ (b - 1));
+ }
+ return Square(BitTable[(b * 0x783a9b23) >> 26]);
}
#else
#endif
-#else
+#else // defined(USE_FOLDED_BITSCAN)
static const int BitTable[64] = {
0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 34, 20, 40, 5, 17, 26, 38, 15,
// be necessary to touch any of them.
void init_masks() {
+ SetMaskBB[SQ_NONE] = 0ULL;
+ ClearMaskBB[SQ_NONE] = ~SetMaskBB[SQ_NONE];
for(Square s = SQ_A1; s <= SQ_H8; s++) {
SetMaskBB[s] = (1ULL << s);
ClearMaskBB[s] = ~SetMaskBB[s];
void init_ray_bitboards() {
int d[8] = {1, -1, 16, -16, 17, -17, 15, -15};
- for(int i = 0; i < 128; i = i + 9 & ~8) {
+ for(int i = 0; i < 128; i = (i + 9) & ~8) {
for(int j = 0; j < 8; j++) {
RayBB[(i&7)|((i>>4)<<3)][j] = EmptyBoardBB;
for(int k = i + d[j]; (k & 0x88) == 0; k += d[j])
for(i = 0; i < 64; i++) {
attackIndex[i] = index;
mask[i] = sliding_attacks(i, 0ULL, 4, deltas, 1, 6, 1, 6);
+
+#if defined(USE_32BIT_ATTACKS)
+ j = (1 << (32 - shift[i]));
+#else
j = (1 << (64 - shift[i]));
+#endif
+
for(k = 0; k < j; k++) {
+
#if defined(USE_32BIT_ATTACKS)
b = index_to_bitboard(k, mask[i]);
attacks[index +