Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  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. }
  409.