fork download
  1. #include <algorithm>
  2. #include <bitset>
  3. #include <iomanip>
  4. #include <iostream>
  5. #include <numeric>
  6. #include <vector>
  7.  
  8. static const std::pair<int, int> kBishopDirections[] = {
  9. {1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
  10.  
  11. static bool valid_square(int row, int col) {
  12. return row >= 0 && col >= 0 && row < 8 && col < 8;
  13. }
  14.  
  15. template <typename TCont>
  16. auto relevant_squares(int square, const TCont& directions) {
  17. std::vector<int> res;
  18. int start_row = square / 8;
  19. int start_col = square % 8;
  20. for (auto direction : directions) {
  21. auto dst_row = start_row + direction.first;
  22. auto dst_col = start_col + direction.second;
  23. // If the next square in this direction is invalid, the current square
  24. // is at the board's edge and should not be added.
  25. while (valid_square(dst_row + direction.first, dst_col + direction.second)) {
  26. res.push_back(dst_row * 8 + dst_col);
  27. dst_row += direction.first;
  28. dst_col += direction.second;
  29. }
  30. }
  31. std::sort(res.begin(), res.end());
  32. return res;
  33. }
  34.  
  35. template <typename TCont, typename TOp>
  36. void for_each_bitboard(const TCont& squares, TOp op) {
  37. const auto i_max = 1ull << squares.size();
  38. for (auto i = 0ull; i < i_max; ++i) {
  39. auto bitboard = 0ull;
  40. auto bits = i;
  41. for (const auto sq : squares) {
  42. if (bits & 1) {
  43. bitboard |= 1ull << sq;
  44. }
  45. bits >>= 1;
  46. }
  47. op(bitboard);
  48. }
  49. }
  50.  
  51. template <typename TMagic, typename TBitboard>
  52. auto index(TMagic magic, TBitboard bitboard) {
  53. const auto shift = magic >> 56;
  54. return (bitboard * magic) >> shift;
  55. }
  56.  
  57. template <typename TBitboard>
  58. void print_board(TBitboard bitboard) {
  59. auto reverse_8bits = [](auto b) {
  60. b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
  61. b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
  62. b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
  63. return b;
  64. };
  65.  
  66. for (int shift = 56; shift >= 0; shift -= 8) {
  67. auto row = reverse_8bits((bitboard >> shift) & 0xFF);
  68. std::cout << std::bitset<8>(row);
  69. if (shift)
  70. std::cout << "\n";
  71. }
  72. }
  73.  
  74. int main() {
  75. // const auto square = 2; // C1
  76. const auto square = 62; // G8
  77. const auto squares = relevant_squares(square, kBishopDirections);
  78. std::cout << "Relevant squares:";
  79. for (auto wtf : squares) {
  80. std::cout << " " << wtf;
  81. }
  82. std::cout << std::endl;
  83.  
  84. std::vector<int> bits(64);
  85. std::iota(bits.begin(), bits.end(), 0);
  86. std::reverse(bits.begin(), bits.end());
  87. for (auto square : squares) {
  88. std::cout << "<<" << std::setw(2) << square << ": ";
  89. auto shifted = bits;
  90. shifted.erase(shifted.begin(), shifted.begin() + square);
  91. for (auto bit : shifted) {
  92. std::cout << std::setw(3) << bit;
  93. }
  94. std::cout << "\n";
  95. }
  96. std::cout << "\n";
  97.  
  98. const auto magic = 0x3c007f2491c5c260;
  99. std::cout << "Magic:";
  100. for (int i = 56; i >= 0; i -= 8) {
  101. std::cout << std::setw(9) << std::bitset<8>(magic >> i);
  102. std::cout << "(" << i << ")";
  103. }
  104. std::cout << "\n";
  105. for (auto square : squares) {
  106. std::cout << "<<" << std::setw(2) << square << ": ";
  107. auto str = std::bitset<64>(magic << square).to_string();
  108. for (auto bit : str) {
  109. std::cout << std::setw(2) << bit;
  110. }
  111. std::cout << "\n";
  112. }
  113. std::cout << "\n";
  114.  
  115. for_each_bitboard(squares, [&](auto bitboard) {
  116. print_board(bitboard);
  117. std::cout << " ==> ";
  118. std::cout << std::setw(3) << std::dec << index(magic, bitboard);
  119. std::cout << "\n\n";
  120. });
  121. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Relevant squares: 17 26 35 44 53
<<17:  46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
<<26:  37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
<<35:  28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
<<44:  19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
<<53:  10  9  8  7  6  5  4  3  2  1  0

Magic: 00111100(56) 00000000(48) 01111111(40) 00100100(32) 10010001(24) 11000101(16) 11000010(8) 01100000(0)
<<17:  1 1 1 1 1 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
<<26:  1 0 0 1 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
<<35:  1 0 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
<<44:  0 1 0 1 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
<<53:  0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000 ==>   0

00000000
00000000
00000000
00000000
00000000
01000000
00000000
00000000 ==>  15

00000000
00000000
00000000
00000000
00100000
00000000
00000000
00000000 ==>   9

00000000
00000000
00000000
00000000
00100000
01000000
00000000
00000000 ==>   9

00000000
00000000
00000000
00010000
00000000
00000000
00000000
00000000 ==>   8

00000000
00000000
00000000
00010000
00000000
01000000
00000000
00000000 ==>   8

00000000
00000000
00000000
00010000
00100000
00000000
00000000
00000000 ==>   2

00000000
00000000
00000000
00010000
00100000
01000000
00000000
00000000 ==>   1

00000000
00000000
00001000
00000000
00000000
00000000
00000000
00000000 ==>   5

00000000
00000000
00001000
00000000
00000000
01000000
00000000
00000000 ==>   5

00000000
00000000
00001000
00000000
00100000
00000000
00000000
00000000 ==>  14

00000000
00000000
00001000
00000000
00100000
01000000
00000000
00000000 ==>  14

00000000
00000000
00001000
00010000
00000000
00000000
00000000
00000000 ==>  14

00000000
00000000
00001000
00010000
00000000
01000000
00000000
00000000 ==>  14

00000000
00000000
00001000
00010000
00100000
00000000
00000000
00000000 ==>   7

00000000
00000000
00001000
00010000
00100000
01000000
00000000
00000000 ==>   7

00000000
00000100
00000000
00000000
00000000
00000000
00000000
00000000 ==>   4

00000000
00000100
00000000
00000000
00000000
01000000
00000000
00000000 ==>   4

00000000
00000100
00000000
00000000
00100000
00000000
00000000
00000000 ==>  13

00000000
00000100
00000000
00000000
00100000
01000000
00000000
00000000 ==>  13

00000000
00000100
00000000
00010000
00000000
00000000
00000000
00000000 ==>  13

00000000
00000100
00000000
00010000
00000000
01000000
00000000
00000000 ==>  13

00000000
00000100
00000000
00010000
00100000
00000000
00000000
00000000 ==>   6

00000000
00000100
00000000
00010000
00100000
01000000
00000000
00000000 ==>   6

00000000
00000100
00001000
00000000
00000000
00000000
00000000
00000000 ==>  10

00000000
00000100
00001000
00000000
00000000
01000000
00000000
00000000 ==>  10

00000000
00000100
00001000
00000000
00100000
00000000
00000000
00000000 ==>   3

00000000
00000100
00001000
00000000
00100000
01000000
00000000
00000000 ==>   3

00000000
00000100
00001000
00010000
00000000
00000000
00000000
00000000 ==>   3

00000000
00000100
00001000
00010000
00000000
01000000
00000000
00000000 ==>   3

00000000
00000100
00001000
00010000
00100000
00000000
00000000
00000000 ==>  12

00000000
00000100
00001000
00010000
00100000
01000000
00000000
00000000 ==>  12