Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 99 | pmbaty | 1 | /* |
| 2 | Texel - A UCI chess engine. |
||
| 3 | Copyright (C) 2012-2014 Peter Ă–sterlund, peterosterlund2@gmail.com |
||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify |
||
| 6 | it under the terms of the GNU General Public License as published by |
||
| 7 | the Free Software Foundation, either version 3 of the License, or |
||
| 8 | (at your option) any later version. |
||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, |
||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 13 | GNU General Public License for more details. |
||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License |
||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
| 17 | */ |
||
| 18 | |||
| 19 | /* |
||
| 20 | * bitBoard.cpp |
||
| 21 | * |
||
| 22 | * Created on: Feb 25, 2012 |
||
| 23 | * Author: petero |
||
| 24 | */ |
||
| 25 | |||
| 26 | #include "bitBoard.hpp" |
||
| 27 | #include "position.hpp" |
||
| 28 | #include <cassert> |
||
| 29 | #include <iostream> |
||
| 30 | |||
| 31 | U64 BitBoard::kingAttacks[64]; |
||
| 32 | U64 BitBoard::knightAttacks[64]; |
||
| 33 | U64 BitBoard::wPawnAttacks[64]; |
||
| 34 | U64 BitBoard::bPawnAttacks[64]; |
||
| 35 | U64 BitBoard::wPawnBlockerMask[64]; |
||
| 36 | U64 BitBoard::bPawnBlockerMask[64]; |
||
| 37 | |||
| 38 | const U64 BitBoard::maskFile[8] = { |
||
| 39 | 0x0101010101010101ULL, |
||
| 40 | 0x0202020202020202ULL, |
||
| 41 | 0x0404040404040404ULL, |
||
| 42 | 0x0808080808080808ULL, |
||
| 43 | 0x1010101010101010ULL, |
||
| 44 | 0x2020202020202020ULL, |
||
| 45 | 0x4040404040404040ULL, |
||
| 46 | 0x8080808080808080ULL |
||
| 47 | }; |
||
| 48 | |||
| 49 | U64 BitBoard::epMaskW[8]; |
||
| 50 | U64 BitBoard::epMaskB[8]; |
||
| 51 | |||
| 52 | const U64 BitBoard::maskRow1; |
||
| 53 | const U64 BitBoard::maskRow2; |
||
| 54 | const U64 BitBoard::maskRow3; |
||
| 55 | const U64 BitBoard::maskRow4; |
||
| 56 | const U64 BitBoard::maskRow5; |
||
| 57 | const U64 BitBoard::maskRow6; |
||
| 58 | const U64 BitBoard::maskRow7; |
||
| 59 | const U64 BitBoard::maskRow8; |
||
| 60 | const U64 BitBoard::maskRow1Row8; |
||
| 61 | const U64 BitBoard::maskDarkSq; |
||
| 62 | const U64 BitBoard::maskLightSq; |
||
| 63 | const U64 BitBoard::maskCorners; |
||
| 64 | |||
| 65 | U64* BitBoard::rTables[64]; |
||
| 66 | U64 BitBoard::rMasks[64]; |
||
| 67 | int BitBoard::rBits[64] = { 12, 11, 11, 11, 11, 11, 11, 12, |
||
| 68 | 11, 10, 10, 11, 10, 10, 10, 11, |
||
| 69 | 11, 10, 10, 10, 10, 10, 10, 11, |
||
| 70 | 11, 10, 10, 10, 10, 10, 10, 11, |
||
| 71 | 11, 10, 10, 10, 10, 10, 10, 11, |
||
| 72 | 11, 10, 10, 11, 10, 10, 10, 11, |
||
| 73 | 10, 9, 9, 9, 9, 9, 10, 10, |
||
| 74 | 11, 10, 10, 10, 10, 11, 10, 11 }; |
||
| 75 | const U64 BitBoard::rMagics[64] = { |
||
| 76 | 0x19a80065ff2bffffULL, 0x3fd80075ffebffffULL, 0x4010000df6f6fffeULL, 0x0050001faffaffffULL, |
||
| 77 | 0x0050028004ffffb0ULL, 0x7f600280089ffff1ULL, 0x7f5000b0029ffffcULL, 0x5b58004848a7fffaULL, |
||
| 78 | 0x002a90005547ffffULL, 0x000050007f13ffffULL, 0x007fa0006013ffffULL, 0x006a9005656fffffULL, |
||
| 79 | 0x007f600f600affffULL, 0x007ec007e6bfffe2ULL, 0x007ec003eebffffbULL, 0x0071d002382fffdaULL, |
||
| 80 | 0x009f803000e7fffaULL, 0x00680030008bffffULL, 0x00606060004f3ffcULL, 0x001a00600bff9ffdULL, |
||
| 81 | 0x000d006005ff9fffULL, 0x0001806003005fffULL, 0x00000300040bfffaULL, 0x000192500065ffeaULL, |
||
| 82 | 0x00fff112d0006800ULL, 0x007ff037d000c004ULL, 0x003fd062001a3ff8ULL, 0x00087000600e1ffcULL, |
||
| 83 | 0x000fff0100100804ULL, 0x0007ff0100080402ULL, 0x0003ffe0c0060003ULL, 0x0001ffd53000d300ULL, |
||
| 84 | 0x00fffd3000600061ULL, 0x007fff7f95900040ULL, 0x003fff8c00600060ULL, 0x001ffe2587a01860ULL, |
||
| 85 | 0x000fff3fbf40180cULL, 0x0007ffc73f400c06ULL, 0x0003ff86d2c01405ULL, 0x0001fffeaa700100ULL, |
||
| 86 | 0x00fffdfdd8005000ULL, 0x007fff80ebffb000ULL, 0x003fffdf603f6000ULL, 0x001fffe050405000ULL, |
||
| 87 | 0x000fff400700c00cULL, 0x0007ff6007bf600aULL, 0x0003ffeebffec005ULL, 0x0001fffdf3feb001ULL, |
||
| 88 | 0x00ffff39ff484a00ULL, 0x007fff3fff486300ULL, 0x003fff99ffac2e00ULL, 0x001fff31ff2a6a00ULL, |
||
| 89 | 0x000fff19ff15b600ULL, 0x0007fff5fff28600ULL, 0x0003fffddffbfee0ULL, 0x0001fff5f63c96a0ULL, |
||
| 90 | 0x00ffff5dff65cfb6ULL, 0x007fffbaffd1c5aeULL, 0x003fff71ff6cbceaULL, 0x001fffd9ffd4756eULL, |
||
| 91 | 0x000ffff5fff338e6ULL, 0x0007fffdfffe24f6ULL, 0x0003ffef27eebe74ULL, 0x0001ffff23ff605eULL |
||
| 92 | }; |
||
| 93 | |||
| 94 | U64* BitBoard::bTables[64]; |
||
| 95 | U64 BitBoard::bMasks[64]; |
||
| 96 | const int BitBoard::bBits[64] = { 5, 4, 5, 5, 5, 5, 4, 5, |
||
| 97 | 4, 4, 5, 5, 5, 5, 4, 4, |
||
| 98 | 4, 4, 7, 7, 7, 7, 4, 4, |
||
| 99 | 5, 5, 7, 9, 9, 7, 5, 5, |
||
| 100 | 5, 5, 7, 9, 9, 7, 5, 5, |
||
| 101 | 4, 4, 7, 7, 7, 7, 4, 4, |
||
| 102 | 4, 4, 5, 5, 5, 5, 4, 4, |
||
| 103 | 5, 4, 5, 5, 5, 5, 4, 5 }; |
||
| 104 | const U64 BitBoard::bMagics[64] = { |
||
| 105 | 0x0006eff5367ff600ULL, 0x00345835ba77ff2bULL, 0x00145f68a3f5dab6ULL, 0x003a1863fb56f21dULL, |
||
| 106 | 0x0012eb6bfe9d93cdULL, 0x000d82827f3420d6ULL, 0x00074bcd9c7fec97ULL, 0x000034fe99f9ffffULL, |
||
| 107 | 0x0000746f8d6717f6ULL, 0x00003acb32e1a3f7ULL, 0x0000185daf1ffb8aULL, 0x00003a1867f17067ULL, |
||
| 108 | 0x0000038ee0ccf92eULL, 0x000002a2b7ff926eULL, 0x000006c9aa93ff14ULL, 0x00000399b5e5bf87ULL, |
||
| 109 | 0x00400f342c951ffcULL, 0x0020230579ed8ff0ULL, 0x007b008a0077dbfdULL, 0x001d00010c13fd46ULL, |
||
| 110 | 0x00040022031c1ffbULL, 0x000fa00fd1cbff79ULL, 0x000400a4bc9affdfULL, 0x000200085e9cffdaULL, |
||
| 111 | 0x002a14560a3dbfbdULL, 0x000a0a157b9eafd1ULL, 0x00060600fd002ffaULL, 0x004006000c009010ULL, |
||
| 112 | 0x001a002042008040ULL, 0x001a00600fd1ffc0ULL, 0x000d0ace50bf3f8dULL, 0x000183a48434efd1ULL, |
||
| 113 | 0x001fbd7670982a0dULL, 0x000fe24301d81a0fULL, 0x0007fbf82f040041ULL, 0x000040c800008200ULL, |
||
| 114 | 0x007fe17018086006ULL, 0x003b7ddf0ffe1effULL, 0x001f92f861df4a0aULL, 0x000fd713ad98a289ULL, |
||
| 115 | 0x000fd6aa751e400cULL, 0x0007f2a63ae9600cULL, 0x0003ff7dfe0e3f00ULL, 0x000003fd2704ce04ULL, |
||
| 116 | 0x00007fc421601d40ULL, 0x007fff5f70900120ULL, 0x003fa66283556403ULL, 0x001fe31969aec201ULL, |
||
| 117 | 0x0007fdfc18ac14bbULL, 0x0003fb96fb568a47ULL, 0x000003f72ea4954dULL, 0x00000003f8dc0383ULL, |
||
| 118 | 0x0000007f3a814490ULL, 0x00007dc5c9cf62a6ULL, 0x007f23d3342897acULL, 0x003fee36eee1565cULL, |
||
| 119 | 0x0003ff3e99fcccc7ULL, 0x000003ecfcfac5feULL, 0x00000003f97f7453ULL, 0x0000000003f8dc03ULL, |
||
| 120 | 0x000000007efa8146ULL, 0x0000007ed3e2ef60ULL, 0x00007f47243adcd6ULL, 0x007fb65afabfb3b5ULL |
||
| 121 | }; |
||
| 122 | |||
| 123 | vector_aligned<U64> BitBoard::tableData; |
||
| 124 | |||
| 125 | const S8 BitBoard::dirTable[] = { |
||
| 126 | -9, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, -7, |
||
| 127 | 0, 0, -9, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, -7, 0, |
||
| 128 | 0, 0, 0, -9, 0, 0, 0, 0, -8, 0, 0, 0, 0, -7, 0, 0, |
||
| 129 | 0, 0, 0, 0, -9, 0, 0, 0, -8, 0, 0, 0, -7, 0, 0, 0, |
||
| 130 | 0, 0, 0, 0, 0, -9, 0, 0, -8, 0, 0, -7, 0, 0, 0, 0, |
||
| 131 | 0, 0, 0, 0, 0, 0, -9,-17, -8,-15, -7, 0, 0, 0, 0, 0, |
||
| 132 | 0, 0, 0, 0, 0, 0,-10, -9, -8, -7, -6, 0, 0, 0, 0, 0, |
||
| 133 | 0, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, |
||
| 134 | 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, |
||
| 135 | 0, 0, 0, 0, 0, 0, 7, 15, 8, 17, 9, 0, 0, 0, 0, 0, |
||
| 136 | 0, 0, 0, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 0, 0, |
||
| 137 | 0, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, |
||
| 138 | 0, 0, 0, 7, 0, 0, 0, 0, 8, 0, 0, 0, 0, 9, 0, 0, |
||
| 139 | 0, 0, 7, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 9, 0, |
||
| 140 | 0, 7, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9 |
||
| 141 | }; |
||
| 142 | |||
| 143 | const S8 BitBoard::kingDistTable[] = { |
||
| 144 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, |
||
| 145 | 0, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, |
||
| 146 | 0, 7, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, |
||
| 147 | 0, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7, |
||
| 148 | 0, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, |
||
| 149 | 0, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, |
||
| 150 | 0, 7, 6, 5, 4, 3, 2, 1, 1, 1, 2, 3, 4, 5, 6, 7, |
||
| 151 | 0, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, |
||
| 152 | 0, 7, 6, 5, 4, 3, 2, 1, 1, 1, 2, 3, 4, 5, 6, 7, |
||
| 153 | 0, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, |
||
| 154 | 0, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, |
||
| 155 | 0, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7, |
||
| 156 | 0, 7, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, |
||
| 157 | 0, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, |
||
| 158 | 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 |
||
| 159 | }; |
||
| 160 | |||
| 161 | const S8 BitBoard::taxiDistTable[] = { |
||
| 162 | 14,13,12,11,10, 9, 8, 7, 8, 9,10,11,12,13,14, |
||
| 163 | 0,13,12,11,10, 9, 8, 7, 6, 7, 8, 9,10,11,12,13, |
||
| 164 | 0,12,11,10, 9, 8, 7, 6, 5, 6, 7, 8, 9,10,11,12, |
||
| 165 | 0,11,10, 9, 8, 7, 6, 5, 4, 5, 6, 7, 8, 9,10,11, |
||
| 166 | 0,10, 9, 8, 7, 6, 5, 4, 3, 4, 5, 6, 7, 8, 9,10, |
||
| 167 | 0, 9, 8, 7, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7, 8, 9, |
||
| 168 | 0, 8, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 8, |
||
| 169 | 0, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, |
||
| 170 | 0, 8, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 8, |
||
| 171 | 0, 9, 8, 7, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7, 8, 9, |
||
| 172 | 0,10, 9, 8, 7, 6, 5, 4, 3, 4, 5, 6, 7, 8, 9,10, |
||
| 173 | 0,11,10, 9, 8, 7, 6, 5, 4, 5, 6, 7, 8, 9,10,11, |
||
| 174 | 0,12,11,10, 9, 8, 7, 6, 5, 6, 7, 8, 9,10,11,12, |
||
| 175 | 0,13,12,11,10, 9, 8, 7, 6, 7, 8, 9,10,11,12,13, |
||
| 176 | 0,14,13,12,11,10, 9, 8, 7, 8, 9,10,11,12,13,14 |
||
| 177 | }; |
||
| 178 | |||
| 179 | const int BitBoard::trailingZ[64] = { |
||
| 180 | 63, 0, 58, 1, 59, 47, 53, 2, |
||
| 181 | 60, 39, 48, 27, 54, 33, 42, 3, |
||
| 182 | 61, 51, 37, 40, 49, 18, 28, 20, |
||
| 183 | 55, 30, 34, 11, 43, 14, 22, 4, |
||
| 184 | 62, 57, 46, 52, 38, 26, 32, 41, |
||
| 185 | 50, 36, 17, 19, 29, 10, 13, 21, |
||
| 186 | 56, 45, 25, 31, 35, 16, 9, 12, |
||
| 187 | 44, 24, 15, 8, 23, 7, 6, 5 |
||
| 188 | }; |
||
| 189 | |||
| 190 | U64 BitBoard::squaresBetween[64][64]; |
||
| 191 | |||
| 192 | static U64 createPattern(int i, U64 mask) { |
||
| 193 | U64 ret = 0ULL; |
||
| 194 | for (int j = 0; ; j++) { |
||
| 195 | U64 nextMask = mask & (mask - 1); |
||
| 196 | U64 bit = mask ^ nextMask; |
||
| 197 | if ((i & (1ULL << j)) != 0) |
||
| 198 | ret |= bit; |
||
| 199 | mask = nextMask; |
||
| 200 | if (mask == 0) |
||
| 201 | break; |
||
| 202 | } |
||
| 203 | return ret; |
||
| 204 | } |
||
| 205 | |||
| 206 | static U64 addRay(U64 mask, int x, int y, int dx, int dy, |
||
| 207 | U64 occupied, bool inner) { |
||
| 208 | int lo = inner ? 1 : 0; |
||
| 209 | int hi = inner ? 6 : 7; |
||
| 210 | while (true) { |
||
| 211 | if (dx != 0) { |
||
| 212 | x += dx; if ((x < lo) || (x > hi)) break; |
||
| 213 | } |
||
| 214 | if (dy != 0) { |
||
| 215 | y += dy; if ((y < lo) || (y > hi)) break; |
||
| 216 | } |
||
| 217 | int sq = Position::getSquare(x, y); |
||
| 218 | mask |= 1ULL << sq; |
||
| 219 | if ((occupied & (1ULL << sq)) != 0) |
||
| 220 | break; |
||
| 221 | } |
||
| 222 | return mask; |
||
| 223 | } |
||
| 224 | |||
| 225 | static U64 addRookRays(int x, int y, U64 occupied, bool inner) { |
||
| 226 | U64 mask = 0; |
||
| 227 | mask = addRay(mask, x, y, 1, 0, occupied, inner); |
||
| 228 | mask = addRay(mask, x, y, -1, 0, occupied, inner); |
||
| 229 | mask = addRay(mask, x, y, 0, 1, occupied, inner); |
||
| 230 | mask = addRay(mask, x, y, 0, -1, occupied, inner); |
||
| 231 | return mask; |
||
| 232 | } |
||
| 233 | |||
| 234 | static U64 addBishopRays(int x, int y, U64 occupied, bool inner) { |
||
| 235 | U64 mask = 0; |
||
| 236 | mask = addRay(mask, x, y, 1, 1, occupied, inner); |
||
| 237 | mask = addRay(mask, x, y, -1, -1, occupied, inner); |
||
| 238 | mask = addRay(mask, x, y, 1, -1, occupied, inner); |
||
| 239 | mask = addRay(mask, x, y, -1, 1, occupied, inner); |
||
| 240 | return mask; |
||
| 241 | } |
||
| 242 | |||
| 243 | static StaticInitializer<BitBoard> bbInit; |
||
| 244 | |||
| 245 | void |
||
| 246 | BitBoard::staticInitialize() { |
||
| 247 | |||
| 248 | for (int f = 0; f < 8; f++) { |
||
| 249 | U64 m = 0; |
||
| 250 | if (f > 0) m |= 1ULL << Position::getSquare(f-1, 3); |
||
| 251 | if (f < 7) m |= 1ULL << Position::getSquare(f+1, 3); |
||
| 252 | epMaskW[f] = m; |
||
| 253 | |||
| 254 | m = 0; |
||
| 255 | if (f > 0) m |= 1ULL << Position::getSquare(f-1, 4); |
||
| 256 | if (f < 7) m |= 1ULL << Position::getSquare(f+1, 4); |
||
| 257 | epMaskB[f] = m; |
||
| 258 | } |
||
| 259 | |||
| 260 | // Compute king attacks |
||
| 261 | for (int sq = 0; sq < 64; sq++) { |
||
| 262 | U64 m = 1ULL << sq; |
||
| 263 | U64 mask = (((m >> 1) | (m << 7) | (m >> 9)) & maskAToGFiles) | |
||
| 264 | (((m << 1) | (m << 9) | (m >> 7)) & maskBToHFiles) | |
||
| 265 | (m << 8) | (m >> 8); |
||
| 266 | kingAttacks[sq] = mask; |
||
| 267 | } |
||
| 268 | |||
| 269 | // Compute knight attacks |
||
| 270 | for (int sq = 0; sq < 64; sq++) { |
||
| 271 | U64 m = 1ULL << sq; |
||
| 272 | U64 mask = (((m << 6) | (m >> 10)) & maskAToFFiles) | |
||
| 273 | (((m << 15) | (m >> 17)) & maskAToGFiles) | |
||
| 274 | (((m << 17) | (m >> 15)) & maskBToHFiles) | |
||
| 275 | (((m << 10) | (m >> 6)) & maskCToHFiles); |
||
| 276 | knightAttacks[sq] = mask; |
||
| 277 | } |
||
| 278 | |||
| 279 | // Compute pawn attacks |
||
| 280 | for (int sq = 0; sq < 64; sq++) { |
||
| 281 | U64 m = 1ULL << sq; |
||
| 282 | U64 mask = ((m << 7) & maskAToGFiles) | ((m << 9) & maskBToHFiles); |
||
| 283 | wPawnAttacks[sq] = mask; |
||
| 284 | mask = ((m >> 9) & maskAToGFiles) | ((m >> 7) & maskBToHFiles); |
||
| 285 | bPawnAttacks[sq] = mask; |
||
| 286 | |||
| 287 | int x = Position::getX(sq); |
||
| 288 | int y = Position::getY(sq); |
||
| 289 | m = 0; |
||
| 290 | for (int y2 = y+1; y2 < 8; y2++) { |
||
| 291 | if (x > 0) m |= 1ULL << Position::getSquare(x-1, y2); |
||
| 292 | m |= 1ULL << Position::getSquare(x , y2); |
||
| 293 | if (x < 7) m |= 1ULL << Position::getSquare(x+1, y2); |
||
| 294 | } |
||
| 295 | wPawnBlockerMask[sq] = m; |
||
| 296 | m = 0; |
||
| 297 | for (int y2 = y-1; y2 >= 0; y2--) { |
||
| 298 | if (x > 0) m |= 1ULL << Position::getSquare(x-1, y2); |
||
| 299 | m |= 1ULL << Position::getSquare(x , y2); |
||
| 300 | if (x < 7) m |= 1ULL << Position::getSquare(x+1, y2); |
||
| 301 | } |
||
| 302 | bPawnBlockerMask[sq] = m; |
||
| 303 | } |
||
| 304 | |||
| 305 | // Rook magics |
||
| 306 | int rTableSize = 0; |
||
| 307 | for (int sq = 0; sq < 64; sq++) |
||
| 308 | rTableSize += 1 << rBits[sq]; |
||
| 309 | int bTableSize = 0; |
||
| 310 | for (int sq = 0; sq < 64; sq++) |
||
| 311 | bTableSize += 1 << bBits[sq]; |
||
| 312 | tableData.resize(rTableSize + bTableSize); |
||
| 313 | |||
| 314 | int tableUsed = 0; |
||
| 315 | for (int sq = 0; sq < 64; sq++) { |
||
| 316 | int x = Position::getX(sq); |
||
| 317 | int y = Position::getY(sq); |
||
| 318 | rMasks[sq] = addRookRays(x, y, 0ULL, true); |
||
| 319 | int tableSize = 1 << rBits[sq]; |
||
| 320 | U64* table = &tableData[tableUsed]; |
||
| 321 | tableUsed += tableSize; |
||
| 322 | const U64 unInit = 0xffffffffffffffffULL; |
||
| 323 | for (int i = 0; i < tableSize; i++) table[i] = unInit; |
||
| 324 | int nPatterns = 1 << BitBoard::bitCount(rMasks[sq]); |
||
| 325 | for (int i = 0; i < nPatterns; i++) { |
||
| 326 | U64 p = createPattern(i, rMasks[sq]); |
||
| 327 | int entry = (int)((p * rMagics[sq]) >> (64 - rBits[sq])); |
||
| 328 | U64 atks = addRookRays(x, y, p, false); |
||
| 329 | if (table[entry] == unInit) { |
||
| 330 | table[entry] = atks; |
||
| 331 | } else { |
||
| 332 | assert(table[entry] == atks); |
||
| 333 | } |
||
| 334 | } |
||
| 335 | rTables[sq] = table; |
||
| 336 | } |
||
| 337 | |||
| 338 | // Bishop magics |
||
| 339 | for (int sq = 0; sq < 64; sq++) { |
||
| 340 | int x = Position::getX(sq); |
||
| 341 | int y = Position::getY(sq); |
||
| 342 | bMasks[sq] = addBishopRays(x, y, 0ULL, true); |
||
| 343 | int tableSize = 1 << bBits[sq]; |
||
| 344 | U64* table = &tableData[tableUsed]; |
||
| 345 | tableUsed += tableSize; |
||
| 346 | const U64 unInit = 0xffffffffffffffffULL; |
||
| 347 | for (int i = 0; i < tableSize; i++) table[i] = unInit; |
||
| 348 | int nPatterns = 1 << BitBoard::bitCount(bMasks[sq]); |
||
| 349 | for (int i = 0; i < nPatterns; i++) { |
||
| 350 | U64 p = createPattern(i, bMasks[sq]); |
||
| 351 | int entry = (int)((p * bMagics[sq]) >> (64 - bBits[sq])); |
||
| 352 | U64 atks = addBishopRays(x, y, p, false); |
||
| 353 | if (table[entry] == unInit) { |
||
| 354 | table[entry] = atks; |
||
| 355 | } else { |
||
| 356 | assert(table[entry] == atks); |
||
| 357 | } |
||
| 358 | } |
||
| 359 | bTables[sq] = table; |
||
| 360 | } |
||
| 361 | |||
| 362 | // squaresBetween |
||
| 363 | for (int sq1 = 0; sq1 < 64; sq1++) { |
||
| 364 | for (int j = 0; j < 64; j++) |
||
| 365 | squaresBetween[sq1][j] = 0; |
||
| 366 | for (int dx = -1; dx <= 1; dx++) { |
||
| 367 | for (int dy = -1; dy <= 1; dy++) { |
||
| 368 | if ((dx == 0) && (dy == 0)) |
||
| 369 | continue; |
||
| 370 | U64 m = 0; |
||
| 371 | int x = Position::getX(sq1); |
||
| 372 | int y = Position::getY(sq1); |
||
| 373 | while (true) { |
||
| 374 | x += dx; y += dy; |
||
| 375 | if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) |
||
| 376 | break; |
||
| 377 | int sq2 = Position::getSquare(x, y); |
||
| 378 | squaresBetween[sq1][sq2] = m; |
||
| 379 | m |= 1ULL << sq2; |
||
| 380 | } |
||
| 381 | } |
||
| 382 | } |
||
| 383 | } |
||
| 384 | } |
||
| 385 | |||
| 386 | U64 BitBoard::mirrorX(U64 mask) { |
||
| 387 | U64 ret = 0; |
||
| 388 | while (mask != 0) { |
||
| 389 | int sq = extractSquare(mask); |
||
| 390 | int x = Position::getX(sq); |
||
| 391 | int y = Position::getY(sq); |
||
| 392 | int sq2 = Position::getSquare(7-x, y); |
||
| 393 | ret |= (1ULL << sq2); |
||
| 394 | } |
||
| 395 | return ret; |
||
| 396 | } |
||
| 397 | |||
| 398 | U64 BitBoard::mirrorY(U64 mask) { |
||
| 399 | U64 ret = 0; |
||
| 400 | while (mask != 0) { |
||
| 401 | int sq = extractSquare(mask); |
||
| 402 | int x = Position::getX(sq); |
||
| 403 | int y = Position::getY(sq); |
||
| 404 | int sq2 = Position::getSquare(x, 7-y); |
||
| 405 | ret |= (1ULL << sq2); |
||
| 406 | } |
||
| 407 | return ret; |
||
| 408 | } |