38 std::string EnPassant::FEN4(
void)
const 42 std::ostringstream fen;
43 Index passed(this->
index());
44 fen << (char)(
'a' + passed.col()) << (passed.row() + 1);
49 void ChessPosition::clear_en_passant(
void)
51 Index
index = M_en_passant.pawn_index();
52 if (index >
ih1 && piece_at(index - 1) ==
pawn)
53 M_pieces[index - 1].reset_can_take_king_side();
54 if (index <
ia8 && piece_at(index + 1) ==
pawn)
55 M_pieces[index + 1].reset_can_take_queen_side();
62 M_pieces[index].set_type(
nothing);
64 M_castle_flags.clear();
65 M_half_move_clock = 0;
66 M_full_move_number = 1;
67 for (
int i = 0; i < 16; ++i)
69 CodeData data = {
static_cast<uint8_t
>(i) };
70 M_bitboards[data].reset();
72 M_attackers[
black].reset();
73 M_attackers[
white].reset();
74 M_pinning[
black].reset();
75 M_pinning[
white].reset();
76 M_defended[
black].reset();
77 M_defended[
white].reset();
78 M_king_battery_attack_count[
black] = 0;
79 M_king_battery_attack_count[
white] = 0;
80 M_double_check =
false;
97 for (
int ci = 0; ci < 2; ++ci)
112 bool ChessPosition::increment_counters(
bool pawn_advance_or_capture)
114 if (pawn_advance_or_capture)
115 M_half_move_clock = 0;
118 if (M_to_move ==
white)
119 ++M_full_move_number;
120 return M_half_move_clock == 100;
127 M_double_check = M_castle_flags.in_check(M_to_move) ? double_check(M_to_move) :
false;
128 return increment_counters(
false);
134 M_double_check = M_castle_flags.in_check(M_to_move) ? double_check(M_to_move) :
false;
140 new_chess_position.
clear();
141 new_chess_position.M_to_move = M_to_move.
opposite();
144 if (M_en_passant.exists())
146 Index index = M_en_passant.pawn_index();
147 Piece& piece(M_pieces[index]);
148 en_passant_index =
Index(index.col(), 7 - index.row());
156 Index index(iter.index().col(), 7 - iter.index().row());
157 if (index == en_passant_index)
159 new_chess_position.
place(
Code(iter->color().opposite(), iter->type()), index);
161 new_chess_position.M_full_move_number = 1;
162 *
this = new_chess_position;
168 void ChessPosition::update_removed(uint8_t col, uint8_t row,
Color const& color)
183 ok = (int8_t)row >= 1;
191 if (M_pieces[index] == other_pawn)
192 M_pieces[
index].reset_can_take_king_side();
197 if (M_pieces[index] == other_pawn)
198 M_pieces[
index].reset_can_take_queen_side();
206 void ChessPosition::update_placed(uint8_t col, uint8_t row,
Color const& color)
221 ok = (int8_t)row >= 1;
229 if (M_pieces[index] == other_pawn)
230 M_pieces[
index].set_can_take_king_side();
235 if (M_pieces[index] == other_pawn)
236 M_pieces[
index].set_can_take_queen_side();
251 bool king_side_is_msb = (relevant_pieces() < mask);
254 PieceIterator end = king_side_is_msb ? PieceIterator(0) : PieceIterator();
255 Code first_piece_code;
256 Index first_piece_index;
257 bool found_first_piece =
false;
258 bool taking_en_passant_not_allowed =
false;
259 while (piece_iter != end)
261 if (found_first_piece)
263 Code second_piece_code = piece_iter->
code();
270 if (taking_en_passant_not_allowed)
271 M_en_passant.pinned_set();
276 else if (M_en_passant.exists() && M_en_passant.pawn_index() == piece_iter.
index() && first_piece_code.
is_a(
pawn)&&
277 direction.is_horizontal() && M_en_passant.pawn_index() - direction == first_piece_index&&
279 taking_en_passant_not_allowed =
true;
286 first_piece_code = piece_iter->
code();
287 first_piece_index = piece_iter.
index();
290 if (!M_en_passant.exists() || M_en_passant.pawn_index() != first_piece_index || !direction.is_horizontal())
295 taking_en_passant_not_allowed =
true;
298 else if (taking_en_passant_not_allowed&&
299 (!first_piece_code.
is_a(
pawn) || first_piece_index - direction != M_en_passant.pawn_index()))
302 found_first_piece =
true;
304 if (king_side_is_msb)
318 DoutEntering(dc::place,
"ChessPosition::place(" << code <<
", " << index <<
")");
323 int row = index.
row();
324 if (row == 0 || row == 7)
328 if (code.
is_a(
king) && M_bitboards[code].test())
331 Code const old_code = M_pieces[
index].code();
337 if (old_code == code)
341 int index_row = index.
row();
346 M_bitboards[old_code.
color()].reset(mask);
347 M_bitboards[old_code].reset(mask);
350 M_castle_flags.update_removed(old_code, index);
354 update_removed(index.
col(), index_row, old_code.
color());
358 #
if DEBUG_ENPASSANT_EXISTS
359 M_en_passant.exists() &&
362 M_en_passant.pawn_index() ==
index)
368 if (index_row > 1 && M_pieces[index - 8] ==
white_pawn)
370 M_pieces[index - 8].set_is_not_blocked();
371 if (index_row == 2 && M_pieces[index + 8] ==
nothing)
372 M_pieces[index - 8].set_can_move_two_squares();
374 else if (index_row == 3 && M_pieces[index - 16] ==
white_pawn)
375 M_pieces[index - 16].set_can_move_two_squares_if_not_blocked();
376 if (index_row < 6 && M_pieces[index + 8] ==
black_pawn)
378 M_pieces[index + 8].set_is_not_blocked();
379 if (index_row == 5 && M_pieces[index - 8] ==
nothing)
380 M_pieces[index + 8].set_can_move_two_squares();
382 else if (index_row == 4 && M_pieces[index + 16] ==
black_pawn)
383 M_pieces[index + 16].set_can_move_two_squares_if_not_blocked();
389 M_attackers[old_code].reset();
390 M_pinning[old_code].reset();
391 M_en_passant.pinned_reset();
392 M_king_battery_attack_count[old_code.
color().
opposite()] = 0;
396 bool battery =
false;
397 M_defended[old_code.
color()].sub(defendables(old_code, index, battery));
399 --M_king_battery_attack_count[old_code.
color()];
400 update_blocked_defendables(old_code, index,
true);
406 M_bitboards[code.
color()].set(mask);
407 M_bitboards[code].set(mask);
410 M_castle_flags.update_placed(code, index);
413 if (M_en_passant.exists() && (index == M_en_passant.index() || index == M_en_passant.from_index()))
418 update_placed(index.
col(), index_row, code.
color());
423 if (index_row > 1 && M_pieces[index - 8] ==
white_pawn)
424 M_pieces[index - 8].reset_is_not_blocked();
425 else if (index_row == 3 && M_pieces[index - 16] ==
white_pawn)
426 M_pieces[index - 16].reset_can_move_two_squares();
427 if (index_row < 6 && M_pieces[index + 8] ==
black_pawn)
428 M_pieces[index + 8].reset_is_not_blocked();
429 else if (index_row == 4 && M_pieces[index + 16] ==
black_pawn)
430 M_pieces[index + 16].reset_can_move_two_squares();
443 BitBoard rook_attackers(candidates_table[candidates_table_offset(
rook) +
index()]);
444 rook_attackers& = M_bitboards[rook_code] | M_bitboards[queen_code];
447 bishop_attackers& = M_bitboards[bishop_code] | M_bitboards[queen_code];
449 BitBoard attackers(CW_MASK_T_CONST(0));
450 for (
PieceIterator piece_iter(
this, rook_attackers); piece_iter != piece_end(); ++piece_iter)
451 attackers |= squares_from_to(piece_iter.index(),
index);
452 for (
PieceIterator piece_iter(
this, bishop_attackers); piece_iter != piece_end(); ++piece_iter)
453 attackers |= squares_from_to(piece_iter.index(),
index);
454 M_attackers[code] = attackers;
456 BitBoard possible_pinning_directions(candidates_table[candidates_table_offset(
king) +
index()]);
457 possible_pinning_directions& = attackers;
458 for (
PieceIterator direction_iter(
this, possible_pinning_directions); direction_iter != piece_end(); ++direction_iter)
460 Direction direction(direction_from_to(index, direction_iter.index()));
461 BitBoard relevant_pieces(all_pieces);
462 relevant_pieces& = direction.
from(index);
463 update_pinning(code, index, mask, direction, relevant_pieces);
468 bool battery =
false;
469 M_defended[code.
color()].add(defendables(code, index, battery));
471 ++M_king_battery_attack_count[code.
color()];
472 update_blocked_defendables(code, index,
false);
475 Flags flags(fl_none);
492 other_pieces = M_bitboards[
black];
495 all_pieces = other_pieces | M_bitboards[
white];
500 other_pieces = M_bitboards[
white];
503 all_pieces = other_pieces | M_bitboards[
black];
507 kingside.M_bitmask <<= 1;
511 if (!(all_pieces & forward1))
514 if (!(all_pieces & forward2) && initial_row == index_row)
517 if (M_en_passant.exists() && M_en_passant.from_index().row() != initial_row)
518 other_pieces |= M_en_passant.index();
519 if ((other_pieces & queenside))
521 if ((other_pieces & kingside))
675 for (
Color color =
black; color_count < 2; ++color_count, color =
white)
681 BitBoard const line(squares_from_to(index, king_index));
686 Direction const direction(direction_from_to(king_index, index));
687 bool const attacker = (code.
color() != color) && direction.matches(code.
type());
689 bool need_reset =
false;
690 bool need_update =
false;
692 bool const corresponding_bit_in_M_attackers_is_set = M_attackers[color]() & mask;
696 if (!corresponding_bit_in_M_attackers_is_set)
699 M_attackers[color] |= line;
701 need_reset = need_update =
true;
703 else if (corresponding_bit_in_M_attackers_is_set)
709 if (direction.matches(old_code.
type()))
714 Code queen_code(color.opposite(),
queen);
715 Code mover_code(color.opposite(), mover);
716 BitBoard mover_attackers(M_bitboards[mover_code] | M_bitboards[queen_code]);
718 mover_attackers& = line;
719 BitBoard attackers(CW_MASK_T_CONST(0));
720 for (
PieceIterator piece_iter(
this, mover_attackers); piece_iter != piece_end(); ++piece_iter)
721 attackers |= squares_from_to(piece_iter.index(), king_index);
722 M_attackers[color].
reset(line);
723 M_attackers[color].set(attackers);
728 need_reset = need_update = M_pinning[color].test(mask) || !(M_pinning[color] & line).
test();
735 need_update = !(M_pinning[color]() & mask);
738 else if ((M_pinning[color]() & mask))
748 need_reset = need_update =
749 (code.
color() == color || (M_en_passant.exists() && direction.is_horizontal())) && !M_pinning[color].
test(line);
755 M_pinning[color].
reset(line);
758 if (__builtin_expect(M_en_passant.exists(),
false))
762 M_en_passant.pinned_reset();
764 update_pinning(king_code, king_index, M_bitboards[king_code](), direction, (M_bitboards[
black] | M_bitboards[
white]) & line);
770 bool in_check = check();
771 M_castle_flags.set_check(M_to_move, in_check);
772 M_castle_flags.set_check(M_to_move.opposite(), check(M_to_move.opposite()));
773 M_double_check = in_check ? double_check(M_to_move) :
false;
781 DoutEntering(dc::notice,
"ChessPosition::load_FEN(\"" << FEN <<
"\")");
785 std::string::const_iterator iter = FEN.begin();
790 if (iter == FEN.end())
794 int col = 0, row = 7;
795 while ((c =* iter++) !=
' ')
801 if (col != 8 || row <= 0)
814 col += (int)(c -
'0');
844 place(
Code(color, type),
Index(col, row));
851 if (iter == FEN.end())
856 if (iter == FEN.end())
860 if (++iter == FEN.end())
864 if (c !=
'w' && c !=
'b')
867 bool in_check = check();
868 M_double_check = in_check ? double_check(M_to_move) :
false;
869 if (iter == FEN.end() ||* iter !=
' ')
873 if (++iter == FEN.end())
876 uint8_t white_castle_flags = white_rook_queen_side_moved | white_king_moved | white_rook_king_side_moved;
877 uint8_t black_castle_flags = black_rook_queen_side_moved | black_king_moved | black_rook_king_side_moved;
878 while ((c =* iter++) !=
' ')
885 white_castle_flags& = ~(white_king_moved | white_rook_king_side_moved);
888 white_castle_flags& = ~(white_king_moved | white_rook_queen_side_moved);
891 black_castle_flags& = ~(black_king_moved | black_rook_king_side_moved);
894 black_castle_flags& = ~(black_king_moved | black_rook_queen_side_moved);
899 if (iter == FEN.end())
902 M_castle_flags = white_castle_flags | black_castle_flags;
903 M_castle_flags.set_check(M_to_move, in_check);
904 if (iter == FEN.end())
908 if (++iter == FEN.end())
911 if ((c =* iter++) !=
'-')
913 if (c < 'a' || c >
'h' || iter == FEN.end())
917 if (c < '1' || c >
'8' || iter == FEN.end())
921 if (M_to_move ==
white)
933 set_en_passant(
Index(col, row));
935 if (iter == FEN.end() ||* iter !=
' ')
939 if (++iter == FEN.end())
942 M_half_move_clock = 0;
943 while ((c =* iter++) !=
' ')
945 if (!std::isdigit(c))
947 M_half_move_clock = 10 * M_half_move_clock + c -
'0';
948 if (iter == FEN.end())
953 if (++iter == FEN.end())
956 M_full_move_number = 0;
957 while (iter != FEN.end() &&* iter !=
' ')
959 if (!std::isdigit(*iter))
961 M_full_move_number = 10 * M_full_move_number +* iter++ -
'0';
963 if (M_full_move_number == 0)
971 std::ostringstream fen;
972 for (
int row = 7; row >= 0; --row)
975 for (
int col = 0; col <= 7; ++col)
977 Code code = M_pieces[
Index(col, row)].code();
980 else if (empty_count > 0)
982 fen << (char)(
'0' + empty_count);
1025 if (empty_count > 0)
1026 fen << (char)(
'0' + empty_count);
1030 if (M_to_move ==
white)
1034 unsigned int flags = 0;
1035 if (M_castle_flags.can_castle_short(
white))
1037 if (M_castle_flags.can_castle_long(
white))
1039 if (M_castle_flags.can_castle_short(
black))
1041 if (M_castle_flags.can_castle_long(
black))
1047 for (
unsigned int mask = 1; mask <= 8; mask <<= 1)
1069 fen <<
' ' << M_en_passant.FEN4() <<
' ' << (int)M_half_move_clock <<
' ' << (
int)M_full_move_number;
1077 if (index.
row() == 2)
1091 bool possible =
false;
1092 if (index.
col() > 0 && M_pieces[index + offset - 1] == code)
1095 index_of_only_neighboring_pawn = index + offset - 1;
1096 M_pieces[index_of_only_neighboring_pawn].set_can_take_king_side();
1098 if (index.
col() < 7 && M_pieces[index + offset + 1] == code)
1101 Index right_pawn_index = index + offset + 1;
1102 M_pieces[right_pawn_index].set_can_take_queen_side();
1103 if (index_of_only_neighboring_pawn !=
index_end)
1104 index_of_only_neighboring_pawn =
index_end;
1106 index_of_only_neighboring_pawn = right_pawn_index;
1108 if (index_of_only_neighboring_pawn !=
index_end)
1111 if (M_attackers[M_to_move].
test(mask))
1114 mask = M_bitboards[king_code]();
1116 Direction direction(direction_from_to(king_index, index_of_only_neighboring_pawn));
1117 if (direction.is_horizontal())
1120 M_pinning[M_to_move].
reset(line);
1121 update_pinning(king_code, king_index, mask, direction, (M_bitboards[
black] | M_bitboards[
white]) & line);
1122 M_en_passant.pinned_set();
1136 enum down_and_left {
1143 template <
typename T>
1144 inline void move(
mask_t& m, T);
1147 inline void move<up_and_right>(
mask_t& m, up_and_right offset)
1153 inline void move<down_and_left>(
mask_t& m, down_and_left offset)
1158 BitBoard ChessPosition::all_pieces_minus_bishop_movers(
Color const& color,
Index const& index)
const 1168 if (north_west_pawn.
test())
1175 res += north_west.offset;
1179 BitBoard north_east_pawn(M_bitboards[white_pawn]);
1181 if (north_east_pawn.
test())
1188 res += north_east.offset;
1200 if (south_west_pawn.
test())
1207 res += south_west.offset;
1211 BitBoard south_east_pawn(M_bitboards[black_pawn]);
1213 if (south_east_pawn.
test())
1220 res += south_east.offset;
1232 switch(code.
type()())
1242 int col = index.
col();
1243 BitBoard result((color ==
white) ? (pos << 7) | (pos << 9) : (pos >> 9) | (pos >> 7));
1244 if (__builtin_expect(col == 0,
false))
1246 else if (__builtin_expect(col == 7,
false))
1265 BitBoard other_attackers(M_bitboards[queen_code] | M_bitboards[rook_code]);
1266 all_pieces_minus_rook_movers.
reset(other_attackers);
1269 mask_t block = all_pieces_minus_rook_movers();
1275 reachables |= probe;
1277 while((block & probe) != probe);
1284 reachables |= probe;
1286 while((block & probe) != probe);
1297 reachables |= probe;
1299 while((block & probe) != probe);
1303 result |= reachables;
1311 reachables |= probe;
1313 while((block & probe) != probe);
1316 result |= reachables;
1320 if (__builtin_expect(
1321 result.
test(opposite_king_pos) &&
1322 result.
test(other_attackers),
1328 Direction direction(direction_from_to(king_index, index));
1331 line& = other_attackers;
1332 battery = line.
test();
1339 BitBoard all_pieces_minus_bishop_movers(this->all_pieces_minus_bishop_movers(color, index));
1347 move(probe, down_left);
1348 reachables |= probe;
1350 while((block & probe) != probe);
1356 move(probe, up_left);
1357 reachables |= probe;
1359 while((block & probe) != probe);
1370 move(probe, up_right);
1371 reachables |= probe;
1373 while((block & probe) != probe);
1379 move(probe, down_right);
1380 reachables |= probe;
1382 while((block & probe) != probe);
1385 result |= reachables;
1389 if (__builtin_expect(result.
test(opposite_king_pos),
false))
1393 BitBoard other_attackers(M_bitboards[queen_code] | M_bitboards[bishop_code]);
1394 if (result.
test(other_attackers))
1399 Direction direction(direction_from_to(king_index, index));
1402 line& = other_attackers;
1403 battery = line.
test();
1411 BitBoard all_pieces_minus_bishop_movers(this->all_pieces_minus_bishop_movers(color, index));
1415 BitBoard other_rook_movers(M_bitboards[queen_code] | M_bitboards[rook_code]);
1416 all_pieces_minus_rook_movers.
reset(other_rook_movers);
1419 mask_t block = all_pieces_minus_rook_movers();
1425 reachables |= probe;
1427 while((block & probe) != probe);
1434 reachables |= probe;
1436 while((block & probe) != probe);
1447 reachables |= probe;
1449 while((block & probe) != probe);
1458 move(probe, down_left);
1459 reachables |= probe;
1461 while((block & probe) != probe);
1467 move(probe, up_left);
1468 reachables |= probe;
1470 while((block & probe) != probe);
1474 result |= reachables;
1482 reachables |= probe;
1484 while((block & probe) != probe);
1493 move(probe, up_right);
1494 reachables |= probe;
1496 while((block & probe) != probe);
1502 move(probe, down_right);
1503 reachables |= probe;
1505 while((block & probe) != probe);
1508 result |= reachables;
1512 if (__builtin_expect(result.
test(opposite_king_pos),
false))
1516 BitBoard other_attackers(other_rook_movers | M_bitboards[queen_code] | M_bitboards[bishop_code]);
1517 if (result.
test(other_attackers))
1522 Direction direction(direction_from_to(king_index, index));
1525 line& = other_attackers;
1526 battery = line.
test();
1539 void ChessPosition::update_blocked_defendables(
Code const& code,
Index const& index,
bool add)
1559 blocked_rookmovers.
reset(M_bitboards[rook_code] | M_bitboards[queen_code]);
1565 blocked_bishopmovers.
reset(M_bitboards[bishop_code] | M_bitboards[queen_code]);
1576 result[
black].reset();
1577 result[
white].reset();
1620 if (__builtin_expect(blocked_piece !=
index_end&&
1621 blocked_rookmovers.
test(blocked_piece),
false))
1632 Color blocked_piece_color(M_pieces[blocked_piece].color());
1633 Code rook_code(blocked_piece_color,
rook);
1634 Code queen_code(blocked_piece_color,
queen);
1635 BitBoard rookmovers_of_same_color(M_bitboards[rook_code] | M_bitboards[queen_code]);
1645 all_blockers.
reset(rookmovers_of_same_color);
1653 all_blockers& = opposite_line;
1664 BitBoard blocked_squares(opposite_line);
1669 blocked_squares.
reset(south.
from(current_blocker));
1672 if (blocked_squares)
1675 result[blocked_piece_color] |= blocked_squares;
1681 bool king_attack = M_bitboards[king_code].test(blocked_squares);
1682 if (__builtin_expect(king_attack && blocked_squares.
test(rookmovers_of_same_color),
false))
1685 ++M_king_battery_attack_count[blocked_piece_color];
1687 --M_king_battery_attack_count[blocked_piece_color];
1702 blocked_piece !=
index_end && rookmovers_of_same_color.
test(blocked_piece);
1706 M_defended[blocked_piece_color].add(blocked_squares);
1708 M_defended[blocked_piece_color].sub(blocked_squares);
1712 ++M_king_battery_attack_count[blocked_piece_color];
1714 --M_king_battery_attack_count[blocked_piece_color];
1721 line = south.
from(index);
1725 if (__builtin_expect(blocked_piece !=
index_pre_begin && blocked_rookmovers.
test(blocked_piece),
false))
1728 Color blocked_piece_color(M_pieces[blocked_piece].color());
1729 Code rook_code(blocked_piece_color,
rook);
1730 Code queen_code(blocked_piece_color,
queen);
1731 BitBoard rookmovers_of_same_color(M_bitboards[rook_code] | M_bitboards[queen_code]);
1734 all_blockers.
reset(rookmovers_of_same_color);
1736 all_blockers& = opposite_line;
1739 BitBoard blocked_squares(opposite_line);
1741 blocked_squares.
reset(north.
from(current_blocker));
1744 if (blocked_squares)
1746 result[blocked_piece_color] |= blocked_squares;
1748 bool king_attack = M_bitboards[king_code].test(blocked_squares);
1749 if (__builtin_expect(king_attack && blocked_squares.
test(rookmovers_of_same_color),
false))
1752 ++M_king_battery_attack_count[blocked_piece_color];
1754 --M_king_battery_attack_count[blocked_piece_color];
1761 M_defended[blocked_piece_color].add(blocked_squares);
1763 M_defended[blocked_piece_color].sub(blocked_squares);
1767 ++M_king_battery_attack_count[blocked_piece_color];
1769 --M_king_battery_attack_count[blocked_piece_color];
1779 line = east.
from(index);
1783 if (__builtin_expect(blocked_piece !=
index_end && blocked_rookmovers.
test(blocked_piece),
false))
1786 Color blocked_piece_color(M_pieces[blocked_piece].color());
1787 Code rook_code(blocked_piece_color,
rook);
1788 Code queen_code(blocked_piece_color,
queen);
1789 BitBoard rookmovers_of_same_color(M_bitboards[rook_code] | M_bitboards[queen_code]);
1792 all_blockers.
reset(rookmovers_of_same_color);
1794 all_blockers& = opposite_line;
1797 BitBoard blocked_squares(opposite_line);
1799 blocked_squares.
reset(west.
from(current_blocker));
1801 if (blocked_squares)
1803 result[blocked_piece_color] |= blocked_squares;
1805 bool king_attack = M_bitboards[king_code].test(blocked_squares);
1806 if (__builtin_expect(king_attack && blocked_squares.
test(rookmovers_of_same_color),
false))
1809 ++M_king_battery_attack_count[blocked_piece_color];
1811 --M_king_battery_attack_count[blocked_piece_color];
1816 M_defended[blocked_piece_color].add(blocked_squares);
1818 M_defended[blocked_piece_color].sub(blocked_squares);
1822 ++M_king_battery_attack_count[blocked_piece_color];
1824 --M_king_battery_attack_count[blocked_piece_color];
1831 line = west.
from(index);
1835 if (__builtin_expect(blocked_piece !=
index_pre_begin && blocked_rookmovers.
test(blocked_piece),
false))
1838 Color blocked_piece_color(M_pieces[blocked_piece].color());
1839 Code rook_code(blocked_piece_color,
rook);
1840 Code queen_code(blocked_piece_color,
queen);
1841 BitBoard rookmovers_of_same_color(M_bitboards[rook_code] | M_bitboards[queen_code]);
1844 all_blockers.
reset(rookmovers_of_same_color);
1846 all_blockers& = opposite_line;
1849 BitBoard blocked_squares(opposite_line);
1851 blocked_squares.
reset(east.
from(current_blocker));
1853 if (blocked_squares)
1855 result[blocked_piece_color] |= blocked_squares;
1857 bool king_attack = M_bitboards[king_code].test(blocked_squares);
1858 if (__builtin_expect(king_attack && blocked_squares.
test(rookmovers_of_same_color),
false))
1861 ++M_king_battery_attack_count[blocked_piece_color];
1863 --M_king_battery_attack_count[blocked_piece_color];
1870 M_defended[blocked_piece_color].add(blocked_squares);
1872 M_defended[blocked_piece_color].sub(blocked_squares);
1876 ++M_king_battery_attack_count[blocked_piece_color];
1878 --M_king_battery_attack_count[blocked_piece_color];
1888 line = north_west.
from(index);
1892 if (__builtin_expect(blocked_piece !=
index_end && blocked_bishopmovers.
test(blocked_piece),
false))
1895 Color blocked_piece_color(M_pieces[blocked_piece].color());
1896 Code bishop_code(blocked_piece_color,
bishop);
1897 Code queen_code(blocked_piece_color,
queen);
1898 BitBoard bishopmovers_of_same_color(M_bitboards[bishop_code] | M_bitboards[queen_code]);
1901 all_blockers.
reset(bishopmovers_of_same_color);
1903 all_blockers& = opposite_line;
1906 BitBoard blocked_squares(opposite_line);
1908 blocked_squares.
reset(south_east.
from(current_blocker));
1910 if (blocked_squares)
1912 if (__builtin_expect(code ==
black_pawn,
false) && blocked_piece_color ==
black)
1913 blocked_squares.
reset(index + south_east.offset);
1914 result[blocked_piece_color] |= blocked_squares;
1916 bool king_attack = M_bitboards[king_code].test(blocked_squares);
1917 if (__builtin_expect(king_attack && blocked_squares.
test(bishopmovers_of_same_color),
false))
1920 ++M_king_battery_attack_count[blocked_piece_color];
1922 --M_king_battery_attack_count[blocked_piece_color];
1927 M_defended[blocked_piece_color].add(blocked_squares);
1929 M_defended[blocked_piece_color].sub(blocked_squares);
1933 ++M_king_battery_attack_count[blocked_piece_color];
1935 --M_king_battery_attack_count[blocked_piece_color];
1942 line = south_east.
from(index);
1946 if (__builtin_expect(blocked_piece !=
index_pre_begin && blocked_bishopmovers.
test(blocked_piece),
false))
1949 Color blocked_piece_color(M_pieces[blocked_piece].color());
1950 Code bishop_code(blocked_piece_color,
bishop);
1951 Code queen_code(blocked_piece_color,
queen);
1952 BitBoard bishopmovers_of_same_color(M_bitboards[bishop_code] | M_bitboards[queen_code]);
1955 all_blockers.
reset(bishopmovers_of_same_color);
1957 all_blockers& = opposite_line;
1960 BitBoard blocked_squares(opposite_line);
1962 blocked_squares.
reset(north_west.
from(current_blocker));
1964 if (blocked_squares)
1966 if (__builtin_expect(code ==
white_pawn,
false) && blocked_piece_color ==
white)
1967 blocked_squares.
reset(index + north_west.offset);
1968 result[blocked_piece_color] |= blocked_squares;
1970 bool king_attack = M_bitboards[king_code].test(blocked_squares);
1971 if (__builtin_expect(king_attack && blocked_squares.
test(bishopmovers_of_same_color),
false))
1974 ++M_king_battery_attack_count[blocked_piece_color];
1976 --M_king_battery_attack_count[blocked_piece_color];
1983 M_defended[blocked_piece_color].add(blocked_squares);
1985 M_defended[blocked_piece_color].sub(blocked_squares);
1989 ++M_king_battery_attack_count[blocked_piece_color];
1991 --M_king_battery_attack_count[blocked_piece_color];
2001 line = north_east.
from(index);
2005 if (__builtin_expect(blocked_piece !=
index_end && blocked_bishopmovers.
test(blocked_piece),
false))
2008 Color blocked_piece_color(M_pieces[blocked_piece].color());
2009 Code bishop_code(blocked_piece_color,
bishop);
2010 Code queen_code(blocked_piece_color,
queen);
2011 BitBoard bishopmovers_of_same_color(M_bitboards[bishop_code] | M_bitboards[queen_code]);
2014 all_blockers.
reset(bishopmovers_of_same_color);
2016 all_blockers& = opposite_line;
2019 BitBoard blocked_squares(opposite_line);
2021 blocked_squares.
reset(south_west.
from(current_blocker));
2023 if (blocked_squares)
2025 if (__builtin_expect(code ==
black_pawn,
false) && blocked_piece_color ==
black)
2026 blocked_squares.
reset(index + south_west.offset);
2027 result[blocked_piece_color] |= blocked_squares;
2029 bool king_attack = M_bitboards[king_code].test(blocked_squares);
2030 if (__builtin_expect(king_attack && blocked_squares.
test(bishopmovers_of_same_color),
false))
2033 ++M_king_battery_attack_count[blocked_piece_color];
2035 --M_king_battery_attack_count[blocked_piece_color];
2040 M_defended[blocked_piece_color].add(blocked_squares);
2042 M_defended[blocked_piece_color].sub(blocked_squares);
2046 ++M_king_battery_attack_count[blocked_piece_color];
2048 --M_king_battery_attack_count[blocked_piece_color];
2055 line = south_west.
from(index);
2059 if (__builtin_expect(blocked_piece !=
index_pre_begin && blocked_bishopmovers.
test(blocked_piece),
false))
2062 Color blocked_piece_color(M_pieces[blocked_piece].color());
2063 Code bishop_code(blocked_piece_color,
bishop);
2064 Code queen_code(blocked_piece_color,
queen);
2065 BitBoard bishopmovers_of_same_color(M_bitboards[bishop_code] | M_bitboards[queen_code]);
2068 all_blockers.
reset(bishopmovers_of_same_color);
2070 all_blockers& = opposite_line;
2073 BitBoard blocked_squares(opposite_line);
2075 blocked_squares.
reset(north_east.
from(current_blocker));
2077 if (blocked_squares)
2079 if (__builtin_expect(code ==
white_pawn,
false) && blocked_piece_color ==
white)
2080 blocked_squares.
reset(index + north_east.offset);
2081 result[blocked_piece_color] |= blocked_squares;
2083 bool king_attack = M_bitboards[king_code].test(blocked_squares);
2084 if (__builtin_expect(king_attack && blocked_squares.
test(bishopmovers_of_same_color),
false))
2087 ++M_king_battery_attack_count[blocked_piece_color];
2089 --M_king_battery_attack_count[blocked_piece_color];
2096 M_defended[blocked_piece_color].add(blocked_squares);
2098 M_defended[blocked_piece_color].sub(blocked_squares);
2102 ++M_king_battery_attack_count[blocked_piece_color];
2104 --M_king_battery_attack_count[blocked_piece_color];
2114 if (
BitBoard black_result = result[black])
2117 M_defended[
black].add(black_result);
2119 M_defended[
black].sub(black_result);
2124 M_defended[
white].add(white_result);
2126 M_defended[
white].sub(white_result);
2133 Piece piece(M_pieces[index]);
2136 switch(piece.
type()())
2146 if (attacked_squares)
2148 BitBoard result((color ==
white) ? (pos << 7) | (pos << 9) : (pos >> 9) | (pos >> 7));
2149 result.
reset(M_bitboards[color]);
2150 int col = index.col();
2151 if (__builtin_expect(col == 0,
false))
2153 else if (__builtin_expect(col == 7,
false))
2157 return candidates(index);
2162 mask_t block = all_pieces();
2168 reachables |= probe;
2170 while((block & probe) != probe);
2177 reachables |= probe;
2179 while((block & probe) != probe);
2190 reachables |= probe;
2192 while((block & probe) != probe);
2196 result |= reachables;
2204 reachables |= probe;
2206 while((block & probe) != probe);
2209 result |= reachables;
2210 result.
reset(M_bitboards[color]);
2216 result.
reset(M_bitboards[color]);
2227 move(probe, down_left);
2228 reachables |= probe;
2230 while((block & probe) != probe);
2236 move(probe, up_left);
2237 reachables |= probe;
2239 while((block & probe) != probe);
2250 move(probe, up_right);
2251 reachables |= probe;
2253 while((block & probe) != probe);
2259 move(probe, down_right);
2260 reachables |= probe;
2262 while((block & probe) != probe);
2265 result |= reachables;
2266 result.
reset(M_bitboards[color]);
2272 mask_t block = all_pieces();
2278 reachables |= probe;
2280 while((block & probe) != probe);
2287 reachables |= probe;
2289 while((block & probe) != probe);
2300 reachables |= probe;
2302 while((block & probe) != probe);
2308 move(probe, down_left);
2309 reachables |= probe;
2311 while((block & probe) != probe);
2317 move(probe, up_left);
2318 reachables |= probe;
2320 while((block & probe) != probe);
2324 result |= reachables;
2332 reachables |= probe;
2334 while((block & probe) != probe);
2340 move(probe, up_right);
2341 reachables |= probe;
2343 while((block & probe) != probe);
2349 move(probe, down_right);
2350 reachables |= probe;
2352 while((block & probe) != probe);
2355 result |= reachables;
2356 result.
reset(M_bitboards[color]);
2362 result.
reset(M_bitboards[color]);
2363 if (attacked_squares || !M_castle_flags.can_castle(color))
2365 BitBoard long_castle_squares(0), short_castle_squares(0);
2366 bool can_castle_long =
false, can_castle_short =
false;
2367 if (M_castle_flags.can_castle_short(color))
2370 if (!(all_pieces & short_castle_squares))
2372 can_castle_short =
true;
2373 short_castle_squares.reset(
f1|
f8);
2376 if (M_castle_flags.can_castle_long(color))
2379 if (!(all_pieces & long_castle_squares))
2381 can_castle_long =
true;
2382 long_castle_squares.reset(
b1|
b8|
d1|
d8);
2385 if (can_castle_short || can_castle_long)
2389 attacked_squares.
reset();
2390 for (
PieceIterator iter = piece_begin(color.opposite()); iter != piece_end(); ++iter)
2391 attacked_squares |= reachables(iter.index(),
true);
2392 if (can_castle_short && !(attacked_squares & ((color ==
white) ? (
e1|
f1|
g1) : (
e8|
f8|
g8))))
2393 result |= short_castle_squares;
2394 if (can_castle_long && !(attacked_squares & ((color ==
white) ? (
c1|
d1|
e1) : (
c8|
d8|
e8))))
2395 result |= long_castle_squares;
2405 Code code(M_pieces[index].code());
2408 BitBoard reachables(this->reachables(index));
2412 if (__builtin_expect(color == M_to_move && M_castle_flags.in_check(M_to_move),
false))
2416 if (__builtin_expect(M_double_check && !is_king,
false))
2421 attacker_squares.
reset();
2423 BitBoard king_pos(M_bitboards[king_code]);
2425 if (__builtin_expect(!M_double_check && !is_king,
true))
2429 BitBoard queenside_pawn(king_pos() >> 9);
2430 BitBoard kingside_pawn(king_pos() >> 7);
2433 attacker_squares = (queenside_pawn | kingside_pawn) & M_bitboards[
white_pawn];
2434 attacker_squares |= candidates_table[candidates_table_offset(
knight) + king_index()] & M_bitboards[
white_knight];
2438 BitBoard queenside_pawn(king_pos() << 7);
2439 BitBoard kingside_pawn(king_pos() << 9);
2442 attacker_squares = (queenside_pawn | kingside_pawn) & M_bitboards[
black_pawn];
2443 attacker_squares |= candidates_table[candidates_table_offset(
knight) + king_index()] & M_bitboards[
black_knight];
2448 if (!attacker_squares)
2452 Code rook_code(opposite_color,
rook);
2454 BitBoard rookmovers(candidates_table[candidates_table_offset(
rook) + king_index()] & (M_bitboards[rook_code] | M_bitboards[queen_code]));
2455 for (
PieceIterator piece_iter(
this, rookmovers); piece_iter != piece_end(); ++piece_iter)
2457 Direction const& direction(direction_from_to(king_index, piece_iter.index()));
2458 BitBoard line(squares_from_to(piece_iter.index(), king_index));
2459 if ((line & all_pieces) ==
BitBoard(piece_iter.index()))
2465 Index one_step_away_from_attacker(king_index - direction);
2467 if (one_step_away_from_attacker() < 64)
2468 reachables.reset(one_step_away_from_attacker);
2471 attacker_squares |= line;
2475 if (M_double_check || !attacker_squares)
2478 BitBoard bishopmovers(candidates_table[candidates_table_offset(
bishop) + king_index()] & (M_bitboards[bishop_code] | M_bitboards[queen_code]));
2479 for (
PieceIterator piece_iter(
this, bishopmovers); piece_iter != piece_end(); ++piece_iter)
2481 Direction const& direction(direction_from_to(king_index, piece_iter.index()));
2482 BitBoard line(squares_from_to(piece_iter.index(), king_index));
2483 if ((line & all_pieces) == piece_iter.index())
2488 Index one_step_away_from_attacker(king_index - direction);
2489 if (one_step_away_from_attacker() < 64)
2490 reachables.reset(one_step_away_from_attacker);
2493 attacker_squares |= line;
2502 reachables& = attacker_squares;
2505 BitBoard pinning(M_pinning[color]);
2506 if (__builtin_expect(pinning.
test(index),
false))
2510 reachables& = pinning;
2513 Index king_index(index_of_king(color));
2514 Direction direction(direction_from_to(king_index, index));
2519 if (__builtin_expect(M_en_passant.exists() && M_en_passant.pinned() && code.
is_a(
pawn),
false))
2520 reachables.
reset(M_en_passant.index());
2521 if (__builtin_expect(code.
is_a(
king),
false))
2522 reachables.reset(M_defended[color.opposite()].any());
2532 if (to() > 63 || from() > 63)
2536 Piece const& piece(M_pieces[from]);
2540 bool is_pawn_promotion = piece.
code().
is_a(
pawn) && (to.row() == 0 || to.row() == 7);
2542 if (is_pawn_promotion)
2545 if (promotion_type !=
rook && promotion_type !=
knight && promotion_type !=
bishop && promotion_type !=
queen)
2551 return moves(from).test(to_pos);
2559 bool pawn_move = (from_pos & M_bitboards[
Code(M_to_move,
pawn)]);
2560 bool pawn_advance_or_capture = pawn_move | !!(to_pos & all_pieces);
2562 if (__builtin_expect(M_en_passant.exists(),
false))
2564 if (pawn_move && M_en_passant.index() == move.
to())
2568 place(
Code(), M_en_passant.pawn_index());
2579 uint8_t offset = move.
to()() - move.
from()();
2580 bool pawn_advanced_two_squares = !(offset & 0xf);
2581 if (pawn_advanced_two_squares)
2585 IndexData passed_square = {
static_cast<uint8_t
>(move.
to()() ^ 8) };
2586 set_en_passant(passed_square);
2600 place(piece.code(), move.
to());
2602 uint8_t col_diff = move.
to().
col() - move.
from().
col();
2603 if (__builtin_expect(piece.code().is_a(
king),
false) && __builtin_expect(col_diff && !(col_diff & 1),
false))
2605 IndexData rook_from = {
static_cast<uint8_t
>(move.
from()() - 4 + 7 * (2 + move.
to()() - move.
from()()) / 4) };
2606 IndexData rook_to = {
static_cast<uint8_t
>(move.
from()() + (move.
to()() - move.
from()()) / 2) };
2607 place(
Code(), rook_from);
2608 place(
Code(M_to_move,
rook), rook_to);
2616 bool in_check = M_castle_flags.in_check(M_to_move);
2617 M_castle_flags = castle_flags;
2618 M_castle_flags.set_check(M_to_move, in_check);
2619 M_castle_flags.piece_moved_from(piece, move.
from());
2622 M_double_check = M_castle_flags.in_check(M_to_move) ? double_check(M_to_move) :
false;
2624 return increment_counters(pawn_advance_or_capture);
2627 BitBoardData ChessPosition::candidates_table[5 * 64] = {
2629 { CW_MASK_T_CONST(0x0000000000020400)}, { CW_MASK_T_CONST(0x0000000000050800)}, { CW_MASK_T_CONST(0x00000000000a1100)}, { CW_MASK_T_CONST(0x0000000000142200)},
2630 { CW_MASK_T_CONST(0x0000000000284400)}, { CW_MASK_T_CONST(0x0000000000508800)}, { CW_MASK_T_CONST(0x0000000000a01000)}, { CW_MASK_T_CONST(0x0000000000402000)},
2631 { CW_MASK_T_CONST(0x0000000002040004)}, { CW_MASK_T_CONST(0x0000000005080008)}, { CW_MASK_T_CONST(0x000000000a110011)}, { CW_MASK_T_CONST(0x0000000014220022)},
2632 { CW_MASK_T_CONST(0x0000000028440044)}, { CW_MASK_T_CONST(0x0000000050880088)}, { CW_MASK_T_CONST(0x00000000a0100010)}, { CW_MASK_T_CONST(0x0000000040200020)},
2633 { CW_MASK_T_CONST(0x0000000204000402)}, { CW_MASK_T_CONST(0x0000000508000805)}, { CW_MASK_T_CONST(0x0000000a1100110a)}, { CW_MASK_T_CONST(0x0000001422002214)},
2634 { CW_MASK_T_CONST(0x0000002844004428)}, { CW_MASK_T_CONST(0x0000005088008850)}, { CW_MASK_T_CONST(0x000000a0100010a0)}, { CW_MASK_T_CONST(0x0000004020002040)},
2635 { CW_MASK_T_CONST(0x0000020400040200)}, { CW_MASK_T_CONST(0x0000050800080500)}, { CW_MASK_T_CONST(0x00000a1100110a00)}, { CW_MASK_T_CONST(0x0000142200221400)},
2636 { CW_MASK_T_CONST(0x0000284400442800)}, { CW_MASK_T_CONST(0x0000508800885000)}, { CW_MASK_T_CONST(0x0000a0100010a000)}, { CW_MASK_T_CONST(0x0000402000204000)},
2637 { CW_MASK_T_CONST(0x0002040004020000)}, { CW_MASK_T_CONST(0x0005080008050000)}, { CW_MASK_T_CONST(0x000a1100110a0000)}, { CW_MASK_T_CONST(0x0014220022140000)},
2638 { CW_MASK_T_CONST(0x0028440044280000)}, { CW_MASK_T_CONST(0x0050880088500000)}, { CW_MASK_T_CONST(0x00a0100010a00000)}, { CW_MASK_T_CONST(0x0040200020400000)},
2639 { CW_MASK_T_CONST(0x0204000402000000)}, { CW_MASK_T_CONST(0x0508000805000000)}, { CW_MASK_T_CONST(0x0a1100110a000000)}, { CW_MASK_T_CONST(0x1422002214000000)},
2640 { CW_MASK_T_CONST(0x2844004428000000)}, { CW_MASK_T_CONST(0x5088008850000000)}, { CW_MASK_T_CONST(0xa0100010a0000000)}, { CW_MASK_T_CONST(0x4020002040000000)},
2641 { CW_MASK_T_CONST(0x0400040200000000)}, { CW_MASK_T_CONST(0x0800080500000000)}, { CW_MASK_T_CONST(0x1100110a00000000)}, { CW_MASK_T_CONST(0x2200221400000000)},
2642 { CW_MASK_T_CONST(0x4400442800000000)}, { CW_MASK_T_CONST(0x8800885000000000)}, { CW_MASK_T_CONST(0x100010a000000000)}, { CW_MASK_T_CONST(0x2000204000000000)},
2643 { CW_MASK_T_CONST(0x0004020000000000)}, { CW_MASK_T_CONST(0x0008050000000000)}, { CW_MASK_T_CONST(0x00110a0000000000)}, { CW_MASK_T_CONST(0x0022140000000000)},
2644 { CW_MASK_T_CONST(0x0044280000000000)}, { CW_MASK_T_CONST(0x0088500000000000)}, { CW_MASK_T_CONST(0x0010a00000000000)}, { CW_MASK_T_CONST(0x0020400000000000)},
2646 { CW_MASK_T_CONST(0x0000000000000302)}, { CW_MASK_T_CONST(0x0000000000000705)}, { CW_MASK_T_CONST(0x0000000000000e0a)}, { CW_MASK_T_CONST(0x0000000000001c14)},
2647 { CW_MASK_T_CONST(0x0000000000003828)}, { CW_MASK_T_CONST(0x0000000000007050)}, { CW_MASK_T_CONST(0x000000000000e0a0)}, { CW_MASK_T_CONST(0x000000000000c040)},
2648 { CW_MASK_T_CONST(0x0000000000030203)}, { CW_MASK_T_CONST(0x0000000000070507)}, { CW_MASK_T_CONST(0x00000000000e0a0e)}, { CW_MASK_T_CONST(0x00000000001c141c)},
2649 { CW_MASK_T_CONST(0x0000000000382838)}, { CW_MASK_T_CONST(0x0000000000705070)}, { CW_MASK_T_CONST(0x0000000000e0a0e0)}, { CW_MASK_T_CONST(0x0000000000c040c0)},
2650 { CW_MASK_T_CONST(0x0000000003020300)}, { CW_MASK_T_CONST(0x0000000007050700)}, { CW_MASK_T_CONST(0x000000000e0a0e00)}, { CW_MASK_T_CONST(0x000000001c141c00)},
2651 { CW_MASK_T_CONST(0x0000000038283800)}, { CW_MASK_T_CONST(0x0000000070507000)}, { CW_MASK_T_CONST(0x00000000e0a0e000)}, { CW_MASK_T_CONST(0x00000000c040c000)},
2652 { CW_MASK_T_CONST(0x0000000302030000)}, { CW_MASK_T_CONST(0x0000000705070000)}, { CW_MASK_T_CONST(0x0000000e0a0e0000)}, { CW_MASK_T_CONST(0x0000001c141c0000)},
2653 { CW_MASK_T_CONST(0x0000003828380000)}, { CW_MASK_T_CONST(0x0000007050700000)}, { CW_MASK_T_CONST(0x000000e0a0e00000)}, { CW_MASK_T_CONST(0x000000c040c00000)},
2654 { CW_MASK_T_CONST(0x0000030203000000)}, { CW_MASK_T_CONST(0x0000070507000000)}, { CW_MASK_T_CONST(0x00000e0a0e000000)}, { CW_MASK_T_CONST(0x00001c141c000000)},
2655 { CW_MASK_T_CONST(0x0000382838000000)}, { CW_MASK_T_CONST(0x0000705070000000)}, { CW_MASK_T_CONST(0x0000e0a0e0000000)}, { CW_MASK_T_CONST(0x0000c040c0000000)},
2656 { CW_MASK_T_CONST(0x0003020300000000)}, { CW_MASK_T_CONST(0x0007050700000000)}, { CW_MASK_T_CONST(0x000e0a0e00000000)}, { CW_MASK_T_CONST(0x001c141c00000000)},
2657 { CW_MASK_T_CONST(0x0038283800000000)}, { CW_MASK_T_CONST(0x0070507000000000)}, { CW_MASK_T_CONST(0x00e0a0e000000000)}, { CW_MASK_T_CONST(0x00c040c000000000)},
2658 { CW_MASK_T_CONST(0x0302030000000000)}, { CW_MASK_T_CONST(0x0705070000000000)}, { CW_MASK_T_CONST(0x0e0a0e0000000000)}, { CW_MASK_T_CONST(0x1c141c0000000000)},
2659 { CW_MASK_T_CONST(0x3828380000000000)}, { CW_MASK_T_CONST(0x7050700000000000)}, { CW_MASK_T_CONST(0xe0a0e00000000000)}, { CW_MASK_T_CONST(0xc040c00000000000)},
2660 { CW_MASK_T_CONST(0x0203000000000000)}, { CW_MASK_T_CONST(0x0507000000000000)}, { CW_MASK_T_CONST(0x0a0e000000000000)}, { CW_MASK_T_CONST(0x141c000000000000)},
2661 { CW_MASK_T_CONST(0x2838000000000000)}, { CW_MASK_T_CONST(0x5070000000000000)}, { CW_MASK_T_CONST(0xa0e0000000000000)}, { CW_MASK_T_CONST(0x40c0000000000000)},
2663 { CW_MASK_T_CONST(0x8040201008040200)}, { CW_MASK_T_CONST(0x0080402010080500)}, { CW_MASK_T_CONST(0x0000804020110a00)}, { CW_MASK_T_CONST(0x0000008041221400)},
2664 { CW_MASK_T_CONST(0x0000000182442800)}, { CW_MASK_T_CONST(0x0000010204885000)}, { CW_MASK_T_CONST(0x000102040810a000)}, { CW_MASK_T_CONST(0x0102040810204000)},
2665 { CW_MASK_T_CONST(0x4020100804020002)}, { CW_MASK_T_CONST(0x8040201008050005)}, { CW_MASK_T_CONST(0x00804020110a000a)}, { CW_MASK_T_CONST(0x0000804122140014)},
2666 { CW_MASK_T_CONST(0x0000018244280028)}, { CW_MASK_T_CONST(0x0001020488500050)}, { CW_MASK_T_CONST(0x0102040810a000a0)}, { CW_MASK_T_CONST(0x0204081020400040)},
2667 { CW_MASK_T_CONST(0x2010080402000204)}, { CW_MASK_T_CONST(0x4020100805000508)}, { CW_MASK_T_CONST(0x804020110a000a11)}, { CW_MASK_T_CONST(0x0080412214001422)},
2668 { CW_MASK_T_CONST(0x0001824428002844)}, { CW_MASK_T_CONST(0x0102048850005088)}, { CW_MASK_T_CONST(0x02040810a000a010)}, { CW_MASK_T_CONST(0x0408102040004020)},
2669 { CW_MASK_T_CONST(0x1008040200020408)}, { CW_MASK_T_CONST(0x2010080500050810)}, { CW_MASK_T_CONST(0x4020110a000a1120)}, { CW_MASK_T_CONST(0x8041221400142241)},
2670 { CW_MASK_T_CONST(0x0182442800284482)}, { CW_MASK_T_CONST(0x0204885000508804)}, { CW_MASK_T_CONST(0x040810a000a01008)}, { CW_MASK_T_CONST(0x0810204000402010)},
2671 { CW_MASK_T_CONST(0x0804020002040810)}, { CW_MASK_T_CONST(0x1008050005081020)}, { CW_MASK_T_CONST(0x20110a000a112040)}, { CW_MASK_T_CONST(0x4122140014224180)},
2672 { CW_MASK_T_CONST(0x8244280028448201)}, { CW_MASK_T_CONST(0x0488500050880402)}, { CW_MASK_T_CONST(0x0810a000a0100804)}, { CW_MASK_T_CONST(0x1020400040201008)},
2673 { CW_MASK_T_CONST(0x0402000204081020)}, { CW_MASK_T_CONST(0x0805000508102040)}, { CW_MASK_T_CONST(0x110a000a11204080)}, { CW_MASK_T_CONST(0x2214001422418000)},
2674 { CW_MASK_T_CONST(0x4428002844820100)}, { CW_MASK_T_CONST(0x8850005088040201)}, { CW_MASK_T_CONST(0x10a000a010080402)}, { CW_MASK_T_CONST(0x2040004020100804)},
2675 { CW_MASK_T_CONST(0x0200020408102040)}, { CW_MASK_T_CONST(0x0500050810204080)}, { CW_MASK_T_CONST(0x0a000a1120408000)}, { CW_MASK_T_CONST(0x1400142241800000)},
2676 { CW_MASK_T_CONST(0x2800284482010000)}, { CW_MASK_T_CONST(0x5000508804020100)}, { CW_MASK_T_CONST(0xa000a01008040201)}, { CW_MASK_T_CONST(0x4000402010080402)},
2677 { CW_MASK_T_CONST(0x0002040810204080)}, { CW_MASK_T_CONST(0x0005081020408000)}, { CW_MASK_T_CONST(0x000a112040800000)}, { CW_MASK_T_CONST(0x0014224180000000)},
2678 { CW_MASK_T_CONST(0x0028448201000000)}, { CW_MASK_T_CONST(0x0050880402010000)}, { CW_MASK_T_CONST(0x00a0100804020100)}, { CW_MASK_T_CONST(0x0040201008040201)},
2680 { CW_MASK_T_CONST(0x01010101010101fe)}, { CW_MASK_T_CONST(0x02020202020202fd)}, { CW_MASK_T_CONST(0x04040404040404fb)}, { CW_MASK_T_CONST(0x08080808080808f7)},
2681 { CW_MASK_T_CONST(0x10101010101010ef)}, { CW_MASK_T_CONST(0x20202020202020df)}, { CW_MASK_T_CONST(0x40404040404040bf)}, { CW_MASK_T_CONST(0x808080808080807f)},
2682 { CW_MASK_T_CONST(0x010101010101fe01)}, { CW_MASK_T_CONST(0x020202020202fd02)}, { CW_MASK_T_CONST(0x040404040404fb04)}, { CW_MASK_T_CONST(0x080808080808f708)},
2683 { CW_MASK_T_CONST(0x101010101010ef10)}, { CW_MASK_T_CONST(0x202020202020df20)}, { CW_MASK_T_CONST(0x404040404040bf40)}, { CW_MASK_T_CONST(0x8080808080807f80)},
2684 { CW_MASK_T_CONST(0x0101010101fe0101)}, { CW_MASK_T_CONST(0x0202020202fd0202)}, { CW_MASK_T_CONST(0x0404040404fb0404)}, { CW_MASK_T_CONST(0x0808080808f70808)},
2685 { CW_MASK_T_CONST(0x1010101010ef1010)}, { CW_MASK_T_CONST(0x2020202020df2020)}, { CW_MASK_T_CONST(0x4040404040bf4040)}, { CW_MASK_T_CONST(0x80808080807f8080)},
2686 { CW_MASK_T_CONST(0x01010101fe010101)}, { CW_MASK_T_CONST(0x02020202fd020202)}, { CW_MASK_T_CONST(0x04040404fb040404)}, { CW_MASK_T_CONST(0x08080808f7080808)},
2687 { CW_MASK_T_CONST(0x10101010ef101010)}, { CW_MASK_T_CONST(0x20202020df202020)}, { CW_MASK_T_CONST(0x40404040bf404040)}, { CW_MASK_T_CONST(0x808080807f808080)},
2688 { CW_MASK_T_CONST(0x010101fe01010101)}, { CW_MASK_T_CONST(0x020202fd02020202)}, { CW_MASK_T_CONST(0x040404fb04040404)}, { CW_MASK_T_CONST(0x080808f708080808)},
2689 { CW_MASK_T_CONST(0x101010ef10101010)}, { CW_MASK_T_CONST(0x202020df20202020)}, { CW_MASK_T_CONST(0x404040bf40404040)}, { CW_MASK_T_CONST(0x8080807f80808080)},
2690 { CW_MASK_T_CONST(0x0101fe0101010101)}, { CW_MASK_T_CONST(0x0202fd0202020202)}, { CW_MASK_T_CONST(0x0404fb0404040404)}, { CW_MASK_T_CONST(0x0808f70808080808)},
2691 { CW_MASK_T_CONST(0x1010ef1010101010)}, { CW_MASK_T_CONST(0x2020df2020202020)}, { CW_MASK_T_CONST(0x4040bf4040404040)}, { CW_MASK_T_CONST(0x80807f8080808080)},
2692 { CW_MASK_T_CONST(0x01fe010101010101)}, { CW_MASK_T_CONST(0x02fd020202020202)}, { CW_MASK_T_CONST(0x04fb040404040404)}, { CW_MASK_T_CONST(0x08f7080808080808)},
2693 { CW_MASK_T_CONST(0x10ef101010101010)}, { CW_MASK_T_CONST(0x20df202020202020)}, { CW_MASK_T_CONST(0x40bf404040404040)}, { CW_MASK_T_CONST(0x807f808080808080)},
2694 { CW_MASK_T_CONST(0xfe01010101010101)}, { CW_MASK_T_CONST(0xfd02020202020202)}, { CW_MASK_T_CONST(0xfb04040404040404)}, { CW_MASK_T_CONST(0xf708080808080808)},
2695 { CW_MASK_T_CONST(0xef10101010101010)}, { CW_MASK_T_CONST(0xdf20202020202020)}, { CW_MASK_T_CONST(0xbf40404040404040)}, { CW_MASK_T_CONST(0x7f80808080808080)},
2697 { CW_MASK_T_CONST(0x81412111090503fe)}, { CW_MASK_T_CONST(0x02824222120a07fd)}, { CW_MASK_T_CONST(0x0404844424150efb)}, { CW_MASK_T_CONST(0x08080888492a1cf7)},
2698 { CW_MASK_T_CONST(0x10101011925438ef)}, { CW_MASK_T_CONST(0x2020212224a870df)}, { CW_MASK_T_CONST(0x404142444850e0bf)}, { CW_MASK_T_CONST(0x8182848890a0c07f)},
2699 { CW_MASK_T_CONST(0x412111090503fe03)}, { CW_MASK_T_CONST(0x824222120a07fd07)}, { CW_MASK_T_CONST(0x04844424150efb0e)}, { CW_MASK_T_CONST(0x080888492a1cf71c)},
2700 { CW_MASK_T_CONST(0x101011925438ef38)}, { CW_MASK_T_CONST(0x20212224a870df70)}, { CW_MASK_T_CONST(0x4142444850e0bfe0)}, { CW_MASK_T_CONST(0x82848890a0c07fc0)},
2701 { CW_MASK_T_CONST(0x2111090503fe0305)}, { CW_MASK_T_CONST(0x4222120a07fd070a)}, { CW_MASK_T_CONST(0x844424150efb0e15)}, { CW_MASK_T_CONST(0x0888492a1cf71c2a)},
2702 { CW_MASK_T_CONST(0x1011925438ef3854)}, { CW_MASK_T_CONST(0x212224a870df70a8)}, { CW_MASK_T_CONST(0x42444850e0bfe050)}, { CW_MASK_T_CONST(0x848890a0c07fc0a0)},
2703 { CW_MASK_T_CONST(0x11090503fe030509)}, { CW_MASK_T_CONST(0x22120a07fd070a12)}, { CW_MASK_T_CONST(0x4424150efb0e1524)}, { CW_MASK_T_CONST(0x88492a1cf71c2a49)},
2704 { CW_MASK_T_CONST(0x11925438ef385492)}, { CW_MASK_T_CONST(0x2224a870df70a824)}, { CW_MASK_T_CONST(0x444850e0bfe05048)}, { CW_MASK_T_CONST(0x8890a0c07fc0a090)},
2705 { CW_MASK_T_CONST(0x090503fe03050911)}, { CW_MASK_T_CONST(0x120a07fd070a1222)}, { CW_MASK_T_CONST(0x24150efb0e152444)}, { CW_MASK_T_CONST(0x492a1cf71c2a4988)},
2706 { CW_MASK_T_CONST(0x925438ef38549211)}, { CW_MASK_T_CONST(0x24a870df70a82422)}, { CW_MASK_T_CONST(0x4850e0bfe0504844)}, { CW_MASK_T_CONST(0x90a0c07fc0a09088)},
2707 { CW_MASK_T_CONST(0x0503fe0305091121)}, { CW_MASK_T_CONST(0x0a07fd070a122242)}, { CW_MASK_T_CONST(0x150efb0e15244484)}, { CW_MASK_T_CONST(0x2a1cf71c2a498808)},
2708 { CW_MASK_T_CONST(0x5438ef3854921110)}, { CW_MASK_T_CONST(0xa870df70a8242221)}, { CW_MASK_T_CONST(0x50e0bfe050484442)}, { CW_MASK_T_CONST(0xa0c07fc0a0908884)},
2709 { CW_MASK_T_CONST(0x03fe030509112141)}, { CW_MASK_T_CONST(0x07fd070a12224282)}, { CW_MASK_T_CONST(0x0efb0e1524448404)}, { CW_MASK_T_CONST(0x1cf71c2a49880808)},
2710 { CW_MASK_T_CONST(0x38ef385492111010)}, { CW_MASK_T_CONST(0x70df70a824222120)}, { CW_MASK_T_CONST(0xe0bfe05048444241)}, { CW_MASK_T_CONST(0xc07fc0a090888482)},
2711 { CW_MASK_T_CONST(0xfe03050911214181)}, { CW_MASK_T_CONST(0xfd070a1222428202)}, { CW_MASK_T_CONST(0xfb0e152444840404)}, { CW_MASK_T_CONST(0xf71c2a4988080808)},
2712 { CW_MASK_T_CONST(0xef38549211101010)}, { CW_MASK_T_CONST(0xdf70a82422212020)}, { CW_MASK_T_CONST(0xbfe0504844424140)}, { CW_MASK_T_CONST(0x7fc0a09088848281)},
CodeData const black_pawn
A constant representing a black pawn.
BitBoardData const b8
The square b8.
BitBoardData const d8
The square d8.
IndexData const index_begin
A constant representing the& #39;first' index.
The POD base type of class Code.
BitBoardData const c8
The square c8.
A namespace for all chess related objects that are not related to the GUI.
mask_t M_bitmask
A one-bit-per-square chessboard mask.
IndexData const ia7
A constant representing the index to square a7.
TypeData const bishop
A constant representing a bishop.
BitBoardData const file_h
The h-file.
bool load_FEN(std::string const& FEN)
Read a FEN code.
void prev_bit_in(uint64_t mask)
Retreat Index to the previous bit that is set.
CodeData const white_queen
A constant representing a white queen.
TypeData const queen
A constant representing a queen.
Color opposite(void) const
Return a Color object with the opposite color of this object.
BitBoardData const f1
The square f1.
TypeData const rook
A constant representing a rook.
bool execute(Move const& move)
Execute move move.
Index mask2index(mask_t mask)
Convert a single bit mask into it's Index.
mask_t index2mask(Index index)
Convert Index to a mask_t.
ColorData const white
A constant representing the color white.
FlagsData const fl_pawn_is_not_blocked
A constant representing the flag& #39;pawn is not blocked'.
IndexData const ia1
A constant representing the index to square a1.
IndexData const ih1
A constant representing the index to square h1.
void toggle(void)
Change the color from black to white or vica versa.
bool is_nothing(void) const
Returns TRUE if the code represents& #39;nothing'.
This file contains the declaration of class Direction.
A chess move in a particular chess position.
BitBoardData const file_a
The a-file.
TypeData const pawn
A constant representing a pawn.
TypeData const king
A constant representing a king.
Flags representing the state of a piece on the chessboard.
void next_bit_in(uint64_t mask)
Advance the index to the next bit that is set in mask.
CodeData const black_queen
A constant representing a black queen;.
The POD base type of class BitBoard.
bool set_en_passant(Index const& index)
Explicity set the en passant information.
uint8_t const bishop_bits
The underlaying integral value of type& #39;bishop'.
void set()
Set all values to TRUE.
bool moves_along(Direction const& direction)
Return TRUE if this piece moves along direction.
BitBoardData const e1
The square e1.
IndexData const ia8
A constant representing the index to square a8.
The POD base type of class Index.
CodeData const black_rook
A constant representing a black rook;.
BitBoardData const c1
The square c1.
FlagsData const fl_pawn_can_take_king_side
A constant representing the flag& #39;pawn can take king side'.
Type type(void) const
The type of this piece.
void clear(void)
Clear the board.
bool is_promotion(void) const
Return TRUE if this move is a pawn promotion.
bool is_a_slider(void) const
Returns TRUE if the type is a bishop, rook or queen.
An object representing en passant information.
A one-boolean-per-square chessboard.
The index of a chess square.
bool test() const
Test if any bit is set at all.
uint8_t M_bits
00000STT, where STT is the type. If S == 1 then the piece is a slider.
IndexData const ih2
A constant representing the index to square h2.
BitBoardData const e8
The square e8.
bool has_opposite_color_of(Code const& code)
Return TRUE if the colors are different.
IndexData const ih7
A constant representing the index to square h7.
int col(void) const
Returns the column.
CodeData const white_rook
A constant representing a white rook.
bool legal(Move const& move) const
Return true if the move is a legal move.
A class to keep track of castling rights.
A particular piece on the board.
Index index(void) const
Return the index of the square that was passed.
uint64_t mask_t
The type of an internal BitBoard mask.
BitBoardData const d1
The square d1.
bool is_a(Type const& type) const
Returns TRUE if the type is equal.
uint8_t const white_bits
The underlaying integral value of color& #39;white'.
uint8_t const king_bits
The underlaying integral value of type& #39;king'.
TypeData const knight
A constant representing a knight.
Index pawn_index(void) const
Return the index of the pawn that just advanced two squares.
CodeData const black_bishop
A constant representing a black bishop;.
bool skip_move(void)
Skip a move.
bool is_white(void) const
Return TRUE if this color is white.
Index from(void) const
Return the square the piece moves from.
BitBoardData const b1
The square b1.
BitBoardData const g8
The square g8.
int row(void) const
Returns the row.
Color color(void) const
Return the color of the piece.
IndexData const ia2
A constant representing the index to square a2.
bool is_a_rookmover(void) const
Returns TRUE if the type is a rook or queen.
BitBoard reachables(Index const& index, bool attacked_squares=false) const
Return a BitBoard with bits set for each square that a piece can reach in one move.
BitBoard from(Index const& index) const
Return a BitBoard with all squares in this direction.
A chess piece type including color.
Index to(void) const
Return the square the piece moves to.
uint8_t const black_bits
The underlaying integral value of color& #39;black'.
bool is_a_bishopmover(void) const
Returns TRUE if the type is a bishop or queen.
FlagsData const fl_pawn_can_move_two_squares
A constant representing the flag& #39;pawn can move two squares'.
This file contains the declaration of class ChessPosition.
std::string FEN(void) const
Return the FEN code for this position.
TypeData const nothing
A constant representing the absence of a piece.
Type type(void) const
Return the Type of this Code.
IndexData const index_pre_begin
A constant representing& #39;one before the start'.
CodeData const white_pawn
A constant representing a white pawn.
BitBoardData const f8
The square f8.
bool exists(void) const
Return TRUE if the last move was a pawn advancing two squares.
CodeData const black_knight
A constant representing a black knight;.
void swap_colors(void)
Swap colors.
A color (black or white).
uint8_t const type_mask
A mask for the bits used for the type of a piece.
BitBoard defendables(Code const& code, Index const& index, bool& battery) const
Return a BitBoard with bits set for each square that a piece defends, or would defend if an exchange ...
BitBoardData const g1
The square g1.
BitBoard moves(Index const& index) const
Return a BitBoard with bits set for each square the piece at index can legally go to...
IndexData const index_end
A constant representing& #39;one past the end'.
Non-mutable iterator over selective chess pieces in a chess position.
uint8_t const knight_bits
The underlaying integral value of type& #39;knight'.
The POD base type of class Type.
void initial_position(void)
Set up the initial position.
Color color(void) const
Return the Color of this Code.
uint8_t const queen_bits
The underlaying integral value of type& #39;queen'.
Type promotion_type(void) const
Return the promotion type. Returns empty if this isn't a promotion.
Color to_move(void) const
Return whose turn it is.
This file contains the declaration of class ChessNotation.
void reset()
Set all values to FALSE.
FlagsData const fl_pawn_can_take_queen_side
A constant representing the flag& #39;pawn can take queen side'.
CodeData const white_bishop
A constant representing a white bishop.
bool place(Code const& code, Index const& index)
Place a piece on the board.
CodeData const white_knight
A constant representing a white knight.
uint8_t const nothing_bits
The underlaying integral value of type& #39;nothing'.
uint8_t const pawn_bits
The underlaying integral value of type& #39;pawn'.
Code code(void) const
The code of this piece.
uint8_t const rook_bits
The underlaying integral value of type& #39;rook'.
Index const & index(void) const
Return the current index.
ColorData const black
A constant representing the color black.