commit 64a67cd47dc75e777739555b0380a7134fe1cef8
parent 55197a63e49580de502e4ec9885ea85a10ef5049
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Mon, 7 Aug 2023 17:27:17 +0200
Split moves into generation and make file
Diffstat:
4 files changed, 232 insertions(+), 225 deletions(-)
diff --git a/src/moves/CMakeLists.txt b/src/moves/CMakeLists.txt
@@ -1,5 +1,7 @@
add_library(moves OBJECT
moves.c
+ moves_make.c
+ moves_generate.c
)
target_include_directories(moves
diff --git a/src/moves/moves.c b/src/moves/moves.c
@@ -6,7 +6,6 @@
#include "board.h"
#include "moves.h"
-#include "zobrist.h"
int move_cmp(Move a, Move b) { return *(uint32_t *)&a == *(uint32_t *)&b; }
@@ -63,227 +62,3 @@ void move_list_print(const MoveList *self) {
printf("Total: %d\n", self->count);
}
-#define pawn_canPromote(color, source) \
- ((color == WHITE && source >= a7 && source <= h7) || \
- (color == BLACK && source >= a2 && source <= h2))
-
-#define pawn_onStart(color, source) \
- ((color == BLACK && source >= a7 && source <= h7) || \
- (color == WHITE && source >= a2 && source <= h2))
-
-#define pawn_promote(source, target, Piece, Capture) \
- for (int i = 1; i < 5; i++) { \
- move = move_encode(source, target, Piece, Capture, \
- piece_get(i, color), 0, 0, 0); \
- move_list_add(moves, move); \
- }
-
-MoveList *move_list_generate(MoveList *moves, const Board *board) {
- Move move;
- Square src, tgt;
- eColor color = board_side(board);
-
- if (!moves)
- moves = move_list_new();
- else
- move_list_reset(moves);
-
- // pawn moves
- Piece piece = piece_get(PAWN, color);
- U64 bitboard = board_pieceSet(board, piece);
- bitboard_for_each_bit(src, bitboard) {
- { // quiet
- int add = (color == WHITE) ? +8 : -8;
- tgt = src + add;
- if (!board_square_isOccupied(board, tgt)) {
- if (pawn_canPromote(color, src)) {
- pawn_promote(src, tgt, piece, 0);
- } else {
- move_list_add(moves,
- move_encode(src, tgt, piece, 0, 0, 0, 0, 0));
-
- // two ahead
- if (pawn_onStart(color, src) &&
- !board_square_isOccupied(board, tgt += add))
- move_list_add(
- moves, move_encode(src, tgt, piece, 0, 0, 1, 0, 0));
- }
- }
- }
- { // capture
- U64 attack = board_piece_attacks(board, piece, src) &
- board_color(board, !color);
- bitboard_for_each_bit(tgt, attack) {
- if (pawn_canPromote(color, src)) {
- pawn_promote(src, tgt, piece,
- board_square_piece(board, tgt, !color));
- } else {
- move_list_add(moves, move_encode(src, tgt, piece,
- board_square_piece(
- board, tgt, !color),
- 0, 0, 0, 0));
- }
- }
- }
-
- { // en passant
- if (board_enpassant(board) != no_sq &&
- board_piece_attacks(board, piece, src) &
- (C64(1) << board_enpassant(board)))
- move_list_add(moves,
- move_encode(src, board_enpassant(board), piece,
- piece_get(PAWN, !color), 0, 0, 1, 0));
- }
- }
-
- // All piece move
- for (int piece_idx = 1; piece_idx < 6; piece_idx++) {
- Piece piece = piece_get(piece_idx, color);
- U64 bitboard = board_pieceSet(board, piece);
- bitboard_for_each_bit(src, bitboard) {
- U64 attack = board_piece_attacks(board, piece, src) &
- ~board_color(board, color);
- bitboard_for_each_bit(tgt, attack) {
- move_list_add(
- moves, move_encode(src, tgt, piece,
- board_square_piece(board, tgt, !color),
- 0, 0, 0, 0));
- }
- }
- }
-
- // Castling
- if (color == WHITE) {
- Piece piece = piece_get(KING, WHITE);
- if (board_castle(board) & WK) {
- if (!board_square_isOccupied(board, f1) &&
- !board_square_isOccupied(board, g1) &&
- !board_square_isAttack(board, e1, BLACK) &&
- !board_square_isAttack(board, f1, BLACK))
- move_list_add(moves, move_encode(e1, g1, piece, 0, 0, 0, 0, 1));
- }
- if (board_castle(board) & WQ) {
- if (!board_square_isOccupied(board, d1) &&
- !board_square_isOccupied(board, c1) &&
- !board_square_isOccupied(board, b1) &&
- !board_square_isAttack(board, e1, BLACK) &&
- !board_square_isAttack(board, d1, BLACK))
- move_list_add(moves, move_encode(e1, c1, piece, 0, 0, 0, 0, 1));
- }
- } else {
- Piece piece = piece_get(KING, BLACK);
- if (board_castle(board) & BK) {
- if (!board_square_isOccupied(board, f8) &&
- !board_square_isOccupied(board, g8) &&
- !board_square_isAttack(board, e8, WHITE) &&
- !board_square_isAttack(board, f8, WHITE))
- move_list_add(moves, move_encode(e8, g8, piece, 0, 0, 0, 0, 1));
- }
- if (board_castle(board) & BQ) {
- if (!board_square_isOccupied(board, d8) &&
- !board_square_isOccupied(board, c8) &&
- !board_square_isOccupied(board, b8) &&
- !board_square_isAttack(board, e8, WHITE) &&
- !board_square_isAttack(board, d8, WHITE))
- move_list_add(moves, move_encode(e8, c8, piece, 0, 0, 0, 0, 1));
- }
- }
-
- return moves;
-}
-
-// clang-format off
-const int castling_rights[64] = {
- 13, 15, 15, 15, 12, 15, 15, 14,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 7, 15, 15, 15, 3, 15, 15, 11,
-};
-// clang-format on
-
-void _piece_remove(Board *self, Piece piece, Square square) {
- board_piece_pop(self, piece, square);
- self->hash ^= zobrist_key_piece(piece, square);
-}
-
-void _piece_set(Board *self, Piece piece, Square square) {
- board_piece_set(self, piece, square);
- self->hash ^= zobrist_key_piece(piece, square);
-}
-
-void _piece_move(Board *self, Piece piece, Square source, Square target) {
- _piece_remove(self, piece, source);
- _piece_set(self, piece, target);
-}
-
-int move_make(Move move, Board *board, int flag) {
- if (flag) {
- if (move_capture(move)) return move_make(move, board, 0);
- return 0;
- } else {
- Piece piece = move_piece(move);
- eColor color = board_side(board);
- Square source = move_source(move);
- Square target = move_target(move);
- Square ntarget = target + (color == WHITE ? -8 : +8);
-
- if (!move_capture(move)) {
- if (move_promote(move)) {
- _piece_remove(board, piece, source);
- _piece_set(board, move_piece_promote(move), target);
- } else {
- _piece_move(board, piece, source, target);
- }
- } else {
- if (move_enpassant(move)) {
- _piece_move(board, piece, source, target);
- _piece_remove(board, move_piece_capture(move), ntarget);
- } else if (move_promote(move)) {
- _piece_remove(board, piece, source);
- _piece_remove(board, move_piece_capture(move), target);
- _piece_set(board, move_piece_promote(move), target);
- } else {
- _piece_remove(board, piece, source);
- _piece_remove(board, move_piece_capture(move), target);
- _piece_set(board, piece, target);
- }
- }
-
- board_enpassant_set(board, move_double(move) ? ntarget : no_sq);
-
- if (move_castle(move)) {
- Piece Rook = piece_get(ROOK, board_side(board));
- switch (target) {
- case g1:
- _piece_move(board, Rook, h1, f1);
- break;
- case c1:
- _piece_move(board, Rook, a1, d1);
- break;
- case g8:
- _piece_move(board, Rook, h8, f8);
- break;
- case c8:
- _piece_move(board, Rook, a8, d8);
- break;
- default:
- break;
- }
- }
-
- board->hash ^= zobrist_key_castle(board_castle(board));
- board_castle_and(board, castling_rights[source]);
- board_castle_and(board, castling_rights[target]);
- board->hash ^= zobrist_key_castle(board_castle(board));
-
- if (!board_isCheck(board)) {
- board_side_switch(board);
- return 1;
- }
- return 0;
- }
-}
diff --git a/src/moves/moves_generate.c b/src/moves/moves_generate.c
@@ -0,0 +1,131 @@
+#include "board.h"
+#include "moves.h"
+
+#define pawn_canPromote(color, source) \
+ ((color == WHITE && source >= a7 && source <= h7) || \
+ (color == BLACK && source >= a2 && source <= h2))
+
+#define pawn_onStart(color, source) \
+ ((color == BLACK && source >= a7 && source <= h7) || \
+ (color == WHITE && source >= a2 && source <= h2))
+
+#define pawn_promote(source, target, Piece, Capture) \
+ for (int i = 1; i < 5; i++) { \
+ move = move_encode(source, target, Piece, Capture, \
+ piece_get(i, color), 0, 0, 0); \
+ move_list_add(moves, move); \
+ }
+
+MoveList *move_list_generate(MoveList *moves, const Board *board) {
+ Move move;
+ Square src, tgt;
+ eColor color = board_side(board);
+
+ if (!moves)
+ moves = move_list_new();
+ else
+ move_list_reset(moves);
+
+ // pawn moves
+ Piece piece = piece_get(PAWN, color);
+ U64 bitboard = board_pieceSet(board, piece);
+ bitboard_for_each_bit(src, bitboard) {
+ { // quiet
+ int add = (color == WHITE) ? +8 : -8;
+ tgt = src + add;
+ if (!board_square_isOccupied(board, tgt)) {
+ if (pawn_canPromote(color, src)) {
+ pawn_promote(src, tgt, piece, 0);
+ } else {
+ move_list_add(moves,
+ move_encode(src, tgt, piece, 0, 0, 0, 0, 0));
+
+ // two ahead
+ if (pawn_onStart(color, src) &&
+ !board_square_isOccupied(board, tgt += add))
+ move_list_add(
+ moves, move_encode(src, tgt, piece, 0, 0, 1, 0, 0));
+ }
+ }
+ }
+ { // capture
+ U64 attack = board_piece_attacks(board, piece, src) &
+ board_color(board, !color);
+ bitboard_for_each_bit(tgt, attack) {
+ if (pawn_canPromote(color, src)) {
+ pawn_promote(src, tgt, piece,
+ board_square_piece(board, tgt, !color));
+ } else {
+ move_list_add(moves, move_encode(src, tgt, piece,
+ board_square_piece(
+ board, tgt, !color),
+ 0, 0, 0, 0));
+ }
+ }
+ }
+
+ { // en passant
+ if (board_enpassant(board) != no_sq &&
+ board_piece_attacks(board, piece, src) &
+ (C64(1) << board_enpassant(board)))
+ move_list_add(moves,
+ move_encode(src, board_enpassant(board), piece,
+ piece_get(PAWN, !color), 0, 0, 1, 0));
+ }
+ }
+
+ // All piece move
+ for (int piece_idx = 1; piece_idx < 6; piece_idx++) {
+ Piece piece = piece_get(piece_idx, color);
+ U64 bitboard = board_pieceSet(board, piece);
+ bitboard_for_each_bit(src, bitboard) {
+ U64 attack = board_piece_attacks(board, piece, src) &
+ ~board_color(board, color);
+ bitboard_for_each_bit(tgt, attack) {
+ move_list_add(
+ moves, move_encode(src, tgt, piece,
+ board_square_piece(board, tgt, !color),
+ 0, 0, 0, 0));
+ }
+ }
+ }
+
+ // Castling
+ if (color == WHITE) {
+ Piece piece = piece_get(KING, WHITE);
+ if (board_castle(board) & WK) {
+ if (!board_square_isOccupied(board, f1) &&
+ !board_square_isOccupied(board, g1) &&
+ !board_square_isAttack(board, e1, BLACK) &&
+ !board_square_isAttack(board, f1, BLACK))
+ move_list_add(moves, move_encode(e1, g1, piece, 0, 0, 0, 0, 1));
+ }
+ if (board_castle(board) & WQ) {
+ if (!board_square_isOccupied(board, d1) &&
+ !board_square_isOccupied(board, c1) &&
+ !board_square_isOccupied(board, b1) &&
+ !board_square_isAttack(board, e1, BLACK) &&
+ !board_square_isAttack(board, d1, BLACK))
+ move_list_add(moves, move_encode(e1, c1, piece, 0, 0, 0, 0, 1));
+ }
+ } else {
+ Piece piece = piece_get(KING, BLACK);
+ if (board_castle(board) & BK) {
+ if (!board_square_isOccupied(board, f8) &&
+ !board_square_isOccupied(board, g8) &&
+ !board_square_isAttack(board, e8, WHITE) &&
+ !board_square_isAttack(board, f8, WHITE))
+ move_list_add(moves, move_encode(e8, g8, piece, 0, 0, 0, 0, 1));
+ }
+ if (board_castle(board) & BQ) {
+ if (!board_square_isOccupied(board, d8) &&
+ !board_square_isOccupied(board, c8) &&
+ !board_square_isOccupied(board, b8) &&
+ !board_square_isAttack(board, e8, WHITE) &&
+ !board_square_isAttack(board, d8, WHITE))
+ move_list_add(moves, move_encode(e8, c8, piece, 0, 0, 0, 0, 1));
+ }
+ }
+
+ return moves;
+}
diff --git a/src/moves/moves_make.c b/src/moves/moves_make.c
@@ -0,0 +1,99 @@
+#include "board.h"
+#include "moves.h"
+#include "zobrist.h"
+
+// clang-format off
+const int castling_rights[64] = {
+ 13, 15, 15, 15, 12, 15, 15, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 7, 15, 15, 15, 3, 15, 15, 11,
+};
+// clang-format on
+
+void _piece_remove(Board *self, Piece piece, Square square) {
+ board_piece_pop(self, piece, square);
+ self->hash ^= zobrist_key_piece(piece, square);
+}
+
+void _piece_set(Board *self, Piece piece, Square square) {
+ board_piece_set(self, piece, square);
+ self->hash ^= zobrist_key_piece(piece, square);
+}
+
+void _piece_move(Board *self, Piece piece, Square source, Square target) {
+ _piece_remove(self, piece, source);
+ _piece_set(self, piece, target);
+}
+
+int move_make(Move move, Board *board, int flag) {
+ if (flag) {
+ if (move_capture(move)) return move_make(move, board, 0);
+ return 0;
+ } else {
+ Piece piece = move_piece(move);
+ eColor color = board_side(board);
+ Square source = move_source(move);
+ Square target = move_target(move);
+ Square ntarget = target + (color == WHITE ? -8 : +8);
+
+ if (!move_capture(move)) {
+ if (move_promote(move)) {
+ _piece_remove(board, piece, source);
+ _piece_set(board, move_piece_promote(move), target);
+ } else {
+ _piece_move(board, piece, source, target);
+ }
+ } else {
+ if (move_enpassant(move)) {
+ _piece_move(board, piece, source, target);
+ _piece_remove(board, move_piece_capture(move), ntarget);
+ } else if (move_promote(move)) {
+ _piece_remove(board, piece, source);
+ _piece_remove(board, move_piece_capture(move), target);
+ _piece_set(board, move_piece_promote(move), target);
+ } else {
+ _piece_remove(board, piece, source);
+ _piece_remove(board, move_piece_capture(move), target);
+ _piece_set(board, piece, target);
+ }
+ }
+
+ board_enpassant_set(board, move_double(move) ? ntarget : no_sq);
+
+ if (move_castle(move)) {
+ Piece Rook = piece_get(ROOK, board_side(board));
+ switch (target) {
+ case g1:
+ _piece_move(board, Rook, h1, f1);
+ break;
+ case c1:
+ _piece_move(board, Rook, a1, d1);
+ break;
+ case g8:
+ _piece_move(board, Rook, h8, f8);
+ break;
+ case c8:
+ _piece_move(board, Rook, a8, d8);
+ break;
+ default:
+ break;
+ }
+ }
+
+ board->hash ^= zobrist_key_castle(board_castle(board));
+ board_castle_and(board, castling_rights[source]);
+ board_castle_and(board, castling_rights[target]);
+ board->hash ^= zobrist_key_castle(board_castle(board));
+
+ if (!board_isCheck(board)) {
+ board_side_switch(board);
+ return 1;
+ }
+ return 0;
+ }
+}