1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include "moves.h"
#include "bitboard.h"
#include "moves/vec.c"
#include "moves/king.c"
#include "moves/knight.c"
#include "moves/pawn.c"
#include "moves/rook.c"
#include "moves/bishop.c"
#include "moves/queen.c"
#include <assert.h>
void get_moves(moves_t* moves, position_t position) {
get_pawn_moves(moves, position);
get_knight_moves(moves, position);
get_king_moves(moves, position);
get_rook_moves(moves, position);
get_bishop_moves(moves, position);
get_queen_moves(moves, position);
}
int find_piece_on_square(position_t* p, int square) {
if ((p->bitboards[WHITE_KING] >> square) & 1) return WHITE_KING;
if ((p->bitboards[WHITE_QUEEN] >> square) & 1) return WHITE_QUEEN;
if ((p->bitboards[WHITE_ROOK] >> square) & 1) return WHITE_ROOK;
if ((p->bitboards[WHITE_BISHOP] >> square) & 1) return WHITE_BISHOP;
if ((p->bitboards[WHITE_KNIGHT] >> square) & 1) return WHITE_KNIGHT;
if ((p->bitboards[WHITE_PAWN] >> square) & 1) return WHITE_PAWN;
if ((p->bitboards[BLACK_KING] >> square) & 1) return BLACK_KING;
if ((p->bitboards[BLACK_QUEEN] >> square) & 1) return BLACK_QUEEN;
if ((p->bitboards[BLACK_ROOK] >> square) & 1) return BLACK_ROOK;
if ((p->bitboards[BLACK_BISHOP] >> square) & 1) return BLACK_BISHOP;
if ((p->bitboards[BLACK_KNIGHT] >> square) & 1) return BLACK_KNIGHT;
if ((p->bitboards[BLACK_PAWN] >> square) & 1) return BLACK_PAWN;
assert(0);
}
void position_make_move(position_t* position, move_t* move) {
if (move->flags & MOVE_LONG_CASTLE) {
if (position->turn == WHITE_TURN) {
assert(position->bitboards[WHITE_KING] == 16);
assert((position->bitboards[WHITE_ROOK] >> 0) & 1);
position->bitboards[WHITE_KING] = 2;
position->bitboards[WHITE_ROOK] += 3;
} else if (position->turn == BLACK_TURN) {
assert(position->bitboards[BLACK_KING] == 1152921504606846976ULL);
assert((position->bitboards[BLACK_ROOK] >> 56) & 1);
position->bitboards[BLACK_KING] = 144115188075855872ULL;
position->bitboards[WHITE_ROOK] &= ~((bitboard_t)1 << 56);
position->bitboards[WHITE_ROOK] |= (bitboard_t)1 << 58;
}
return;
}
if (move->flags & MOVE_SHORT_CASTLE) {
if (position->turn == WHITE_TURN) {
assert(position->bitboards[WHITE_KING] == 16);
assert((position->bitboards[WHITE_ROOK] >> 7) & 1);
position->bitboards[WHITE_KING] = 64;
position->bitboards[WHITE_ROOK] &= ~((bitboard_t)1 << 7);
position->bitboards[WHITE_ROOK] |= (bitboard_t)1 << 5;
} else if (position->turn == BLACK_TURN) {
assert(position->bitboards[BLACK_KING] == 1152921504606846976ULL);
assert((position->bitboards[BLACK_ROOK] >> 63) & 1);
position->bitboards[WHITE_KING] = 4611686018427387904ULL;
position->bitboards[WHITE_ROOK] &= ~((bitboard_t)1 << 63);
position->bitboards[WHITE_ROOK] |= (bitboard_t)1 << 61;
}
return;
}
int piece_type = find_piece_on_square(position, move->from);
position->bitboards[piece_type] &= ~(1 << move->from);
if (move->flags & MOVE_PROMOTE_Q) {
int q_type = position->turn == WHITE_TURN ? WHITE_QUEEN : BLACK_QUEEN;
position->bitboards[q_type] |= 1 << move->to;
return;
}
if (move->flags & MOVE_PROMOTE_R) {
int q_type = position->turn == WHITE_TURN ? WHITE_ROOK : BLACK_ROOK;
position->bitboards[q_type] |= 1 << move->to;
return;
}
if (move->flags & MOVE_PROMOTE_B) {
int q_type = position->turn == WHITE_TURN ? WHITE_BISHOP : BLACK_BISHOP;
position->bitboards[q_type] |= 1 << move->to;
return;
}
if (move->flags & MOVE_PROMOTE_N) {
int q_type = position->turn == WHITE_TURN ? WHITE_KNIGHT : BLACK_KNIGHT;
position->bitboards[q_type] |= 1 << move->to;
return;
}
if (move->flags & MOVE_EN_PASSANT) {
int target_sqr;
if (position->turn == WHITE_TURN) target_sqr = move->to - 8;
else target_sqr = move->to + 8;
int to_remove_piece_type = find_piece_on_square(position, target_sqr);
position->bitboards[piece_type] |= 1 << move->to;
position->bitboards[to_remove_piece_type] &= ~(1 << target_sqr);
return;
}
if (move->flags & MOVE_CAPTURE) {
int to_remove_piece_type = find_piece_on_square(position, move->to);
position->bitboards[to_remove_piece_type] &= ~(1 << move->to);
}
// i can't put this above the find_piece_on_square function, because there
// is a possibility that piece_type would resolve to the piece that is being
// moved, which would mess with the ~(1 << to_sqr)
position->bitboards[piece_type] |= 1 << move->to;
}
|