#define MOVES_INTERNAL #include "engine/moves.h" void get_king_moves(moves_t* moves, position_t position) { assert_valid_position(position); bitboard_t friendly_king; int king_square; bitboard_t friendly_pieces; bitboard_t enemy_pieces; if (position.turn == WHITE_TURN) { friendly_pieces = whites(position); enemy_pieces = blacks(position); friendly_king = position.bitboards[WHITE_KING]; } else { friendly_pieces = blacks(position); enemy_pieces = whites(position); friendly_king = position.bitboards[BLACK_KING]; } king_square = __builtin_ctzll(friendly_king); bitboard_t movement; if (king_square >= 10) { movement = 920078ULL << (king_square - 10); } else { movement = 920078ULL >> -(king_square - 10); } if (friendly_king & BITMASK_FILE_A) { movement &= BITMASK_FILE_A | BITMASK_FILE_B; } else if (friendly_king & BITMASK_FILE_H) { movement &= BITMASK_FILE_G | BITMASK_FILE_H; } movement &= ~friendly_pieces; while (movement) { int to = __builtin_ctzll(movement); movement &= movement - 1; add_move( moves, king_square, to, .flags = ((enemy_pieces >> to) & 1) ? MOVE_CAPTURE : 0, ); } bitboard_t all_occupied = friendly_pieces | enemy_pieces; if (position.turn == WHITE_TURN) { if ((position.castling & WHITE_SHORT_CASTLE) && king_square == 4 && !((all_occupied >> 5) & 1) && !((all_occupied >> 6) & 1)) { add_move(moves, 4, 6, .flags = MOVE_SHORT_CASTLE); } if ((position.castling & WHITE_LONG_CASTLE) && king_square == 4 && !((all_occupied >> 3) & 1) && !((all_occupied >> 2) & 1) && !((all_occupied >> 1) & 1)) { add_move(moves, 4, 2, .flags = MOVE_LONG_CASTLE); } } else { if ((position.castling & BLACK_SHORT_CASTLE) && king_square == 60 && !((all_occupied >> 61) & 1) && !((all_occupied >> 62) & 1)) { add_move(moves, 60, 62, .flags = MOVE_SHORT_CASTLE); } if ((position.castling & BLACK_LONG_CASTLE) && king_square == 60 && !((all_occupied >> 59) & 1) && !((all_occupied >> 58) & 1) && !((all_occupied >> 57) & 1)) { add_move(moves, 60, 58, .flags = MOVE_LONG_CASTLE); } } } #ifdef TEST_MOD #include bool test_white_king_corners() { moves_t moves; moves_init(&moves); position_t p = {0}; p.bitboards[BLACK_KING] = 100; p.bitboards[WHITE_KING] = 1; p.turn = WHITE_TURN; get_king_moves(&moves, p); if (moves.length != 3) return false; if (moves.moves[0].from != 0) return false; if (moves.moves[0].to != 1) return false; if (moves.moves[1].from != 0) return false; if (moves.moves[1].to != 8) return false; if (moves.moves[2].from != 0) return false; if (moves.moves[2].to != 9) return false; moves.length = 0; p.bitboards[WHITE_KING] = 128; get_king_moves(&moves, p); if (moves.length != 3) return false; if (moves.moves[0].from != 7) return false; if (moves.moves[0].to != 6) return false; if (moves.moves[1].from != 7) return false; if (moves.moves[1].to != 14) return false; if (moves.moves[2].from != 7) return false; if (moves.moves[2].to != 15) return false; moves.length = 0; p.bitboards[WHITE_KING] = 72057594037927936ULL; get_king_moves(&moves, p); if (moves.length != 3) return false; if (moves.moves[0].from != 56) return false; if (moves.moves[0].to != 48) return false; if (moves.moves[1].from != 56) return false; if (moves.moves[1].to != 49) return false; if (moves.moves[2].from != 56) return false; if (moves.moves[2].to != 57) return false; moves_deinit(moves); return true; } bool test_black_king_corners() { moves_t moves; moves_init(&moves); position_t p = {0}; p.bitboards[WHITE_KING] = 100; p.bitboards[BLACK_KING] = 1; p.turn = BLACK_TURN; get_king_moves(&moves, p); if (moves.length != 3) return false; if (moves.moves[0].from != 0) return false; if (moves.moves[0].to != 1) return false; if (moves.moves[1].from != 0) return false; if (moves.moves[1].to != 8) return false; if (moves.moves[2].from != 0) return false; if (moves.moves[2].to != 9) return false; moves.length = 0; p.bitboards[BLACK_KING] = 128; get_king_moves(&moves, p); if (moves.length != 3) return false; if (moves.moves[0].from != 7) return false; if (moves.moves[0].to != 6) return false; if (moves.moves[1].from != 7) return false; if (moves.moves[1].to != 14) return false; if (moves.moves[2].from != 7) return false; if (moves.moves[2].to != 15) return false; moves.length = 0; p.bitboards[BLACK_KING] = 72057594037927936ULL; get_king_moves(&moves, p); if (moves.length != 3) return false; if (moves.moves[0].from != 56) return false; if (moves.moves[0].to != 48) return false; if (moves.moves[1].from != 56) return false; if (moves.moves[1].to != 49) return false; if (moves.moves[2].from != 56) return false; if (moves.moves[2].to != 57) return false; moves_deinit(moves); return true; } #endif