diff options
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/bitboard.c | 75 | ||||
| -rw-r--r-- | src/engine/bitboard.h | 69 | ||||
| -rw-r--r-- | src/engine/ints.h | 19 | ||||
| -rw-r--r-- | src/engine/moves.c | 7 | ||||
| -rw-r--r-- | src/engine/moves.h | 46 | ||||
| -rw-r--r-- | src/engine/moves/bishop.c | 77 | ||||
| -rw-r--r-- | src/engine/moves/king.c | 53 | ||||
| -rw-r--r-- | src/engine/moves/knight.c | 101 | ||||
| -rw-r--r-- | src/engine/moves/pawn.c | 164 | ||||
| -rw-r--r-- | src/engine/moves/queen.c | 31 | ||||
| -rw-r--r-- | src/engine/moves/rook.c | 77 | ||||
| -rw-r--r-- | src/engine/moves/vec.c | 51 |
12 files changed, 770 insertions, 0 deletions
diff --git a/src/engine/bitboard.c b/src/engine/bitboard.c new file mode 100644 index 0000000..4746020 --- /dev/null +++ b/src/engine/bitboard.c @@ -0,0 +1,75 @@ +#include "bitboard.h" +#include <stdio.h> +#include <inttypes.h> +#include <assert.h> + +position_t position_starting() { + return (position_t) { + .bitboards = { + 16ULL, + 8ULL, + 129ULL, + 36ULL, + 66ULL, + 65280ULL, + 1152921504606846976ULL, + 576460752303423488ULL, + 9295429630892703744ULL, + 2594073385365405696ULL, + 4755801206503243776ULL, + 71776119061217280ULL, + }, + .castling = + ((bitboard_t)1 << WHITE_SHORT_CASTLE) | + ((bitboard_t)1 << WHITE_LONG_CASTLE) | + ((bitboard_t)1 << BLACK_SHORT_CASTLE) | + ((bitboard_t)1 << BLACK_LONG_CASTLE), + .turn = WHITE_TURN, + .passantable_file = 0, + }; +} + +void assert_valid_position(position_t position) { + assert(position.castling <= + ( + ((bitboard_t)1 << WHITE_SHORT_CASTLE) | + ((bitboard_t)1 << WHITE_LONG_CASTLE) | + ((bitboard_t)1 << BLACK_SHORT_CASTLE) | + ((bitboard_t)1 << BLACK_LONG_CASTLE) + ) + ); + assert(position.turn == WHITE_TURN || position.turn == BLACK_TURN); + assert(position.passantable_file <= 8); + assert(position.bitboards[WHITE_KING] != 0); + assert(position.bitboards[BLACK_KING] != 0); +} + +bitboard_t whites(position_t position) { + return + position.bitboards[WHITE_KING] | + position.bitboards[WHITE_QUEEN] | + position.bitboards[WHITE_ROOK] | + position.bitboards[WHITE_BISHOP] | + position.bitboards[WHITE_KNIGHT] | + position.bitboards[WHITE_PAWN]; +} + +bitboard_t blacks(position_t position) { + return + position.bitboards[BLACK_KING] | + position.bitboards[BLACK_QUEEN] | + position.bitboards[BLACK_ROOK] | + position.bitboards[BLACK_BISHOP] | + position.bitboards[BLACK_KNIGHT] | + position.bitboards[BLACK_PAWN]; +} + +void print_bitboard(bitboard_t bitboard) { + printf("Bitboard(%" PRIu64 ")\n", bitboard); + for (int i = 7; i >= 0; i--) { + for (int j = 0; j < 8; j++) { + printf("%" PRIu64 "", (bitboard >> (8 * i + j)) & 1); + } + printf("\n"); + } +} diff --git a/src/engine/bitboard.h b/src/engine/bitboard.h new file mode 100644 index 0000000..912cad0 --- /dev/null +++ b/src/engine/bitboard.h @@ -0,0 +1,69 @@ +#ifndef BITBOARD_H +#define BITBOARD_H + +#include "ints.h" + +typedef u64 bitboard_t; + +enum { + WHITE_KING, + WHITE_QUEEN, + WHITE_ROOK, + WHITE_BISHOP, + WHITE_KNIGHT, + WHITE_PAWN, + BLACK_KING, + BLACK_QUEEN, + BLACK_ROOK, + BLACK_BISHOP, + BLACK_KNIGHT, + BLACK_PAWN, + PIECE_TYPE_COUNT, +}; + +enum { + WHITE_SHORT_CASTLE, + WHITE_LONG_CASTLE, + BLACK_SHORT_CASTLE, + BLACK_LONG_CASTLE, +}; + +enum { + WHITE_TURN, + BLACK_TURN, +}; + +#define BITMASK_RANK_1 255ULL +#define BITMASK_RANK_2 65280ULL +#define BITMASK_RANK_3 16711680ULL +#define BITMASK_RANK_4 4278190080ULL +#define BITMASK_RANK_5 1095216660480ULL +#define BITMASK_RANK_6 280375465082880ULL +#define BITMASK_RANK_7 71776119061217280ULL +#define BITMASK_RANK_8 18374686479671623680ULL +#define BITMASK_FILE_A 72340172838076673ULL +#define BITMASK_FILE_B 144680345676153346ULL +#define BITMASK_FILE_C 289360691352306692ULL +#define BITMASK_FILE_D 578721382704613384ULL +#define BITMASK_FILE_E 1157442765409226768ULL +#define BITMASK_FILE_F 2314885530818453536ULL +#define BITMASK_FILE_G 4629771061636907072ULL +#define BITMASK_FILE_H 9259542123273814144ULL + +#define occupied_by(bitboard, index) (bitboard & ((bitboard_t)1 << index)) + +typedef struct { + bitboard_t bitboards[PIECE_TYPE_COUNT]; + u8 castling; + u8 turn; + u8 passantable_file; +} position_t; + +position_t position_starting(); +void assert_valid_position(position_t position); +bitboard_t whites(position_t position); +bitboard_t blacks(position_t position); + +void print_bitboard(bitboard_t bitboard); + +#endif // BITBOARD_H diff --git a/src/engine/ints.h b/src/engine/ints.h new file mode 100644 index 0000000..b134fe6 --- /dev/null +++ b/src/engine/ints.h @@ -0,0 +1,19 @@ +#ifndef INTS_H +#define INTS_H + +#include <stdint.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef __uint128_t u128; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; +typedef __int128_t i128; +typedef float f32; +typedef double f64; + +#endif // !INTS_H diff --git a/src/engine/moves.c b/src/engine/moves.c new file mode 100644 index 0000000..662aa54 --- /dev/null +++ b/src/engine/moves.c @@ -0,0 +1,7 @@ +#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" diff --git a/src/engine/moves.h b/src/engine/moves.h new file mode 100644 index 0000000..8081ffe --- /dev/null +++ b/src/engine/moves.h @@ -0,0 +1,46 @@ +#ifndef MOVES_H +#define MOVES_H + +#include "ints.h" +#include "bitboard.h" + +typedef u8 square_t; + +typedef struct { + square_t from; + square_t to; +} move_t; +void position_make_move(position_t* position, move_t* move); + +typedef struct { + move_t* moves; + u32 length; + u32 capacity; +} moves_t; + +moves_t moves_init(); +moves_t moves_init_wcapacity(u32 capacity); +moves_t moves_empty(); +void add_move(moves_t* moves, square_t from, square_t to); + +void get_pawn_moves(moves_t* moves, position_t position); +void get_knight_moves(moves_t* moves, position_t position); +void get_king_moves(moves_t* moves, position_t position); +void get_rook_moves(moves_t* moves, position_t position); +void get_bishop_moves(moves_t* moves, position_t position); +void get_queen_moves(moves_t* moves, position_t position); + +void __forloop_rook_moves_gen( + moves_t* moves, + bitboard_t friendly_type, + bitboard_t friendly_pieces, + bitboard_t enemy_pieces +); +void __forloop_bishop_moves_gen( + moves_t* moves, + bitboard_t friendly_type, + bitboard_t friendly_pieces, + bitboard_t enemy_pieces +); + +#endif // !MOVES_H diff --git a/src/engine/moves/bishop.c b/src/engine/moves/bishop.c new file mode 100644 index 0000000..52b90b3 --- /dev/null +++ b/src/engine/moves/bishop.c @@ -0,0 +1,77 @@ +#include "../moves.h" + +void __forloop_bishop_moves_gen( + moves_t* moves, + bitboard_t friendly_type, + bitboard_t friendly_pieces, + bitboard_t enemy_pieces +) { + while (friendly_type) { + int from = __builtin_ctzll(friendly_type); + friendly_type &= friendly_type - 1; + + int og_rank = from / 8; // range: [0, 7] + int og_file = from % 8; // range: [0, 7] + int rank = og_rank + 1, file = og_file + 1, index = rank * 8 + file; + + + while ((rank < 8 && file < 8) && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = ++rank * 8 + ++file; + } + + rank = og_rank - 1, file = og_file - 1, index = rank * 8 + file; + while ((rank >= 0 && file >= 0) && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = --rank * 8 + --file; + } + + rank = og_rank - 1, file = og_file + 1, index = rank * 8 + file; + while ((rank >= 0 && file < 8) && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = --rank * 8 + ++file; + } + + rank = og_rank + 1, file = og_file - 1, index = rank * 8 + file; + while ((rank < 8 && file >= 0) && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = ++rank * 8 + --file; + } + } +} + +void get_bishop_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_bishops; + bitboard_t friendly_pieces; + bitboard_t enemy_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + enemy_pieces = blacks(position); + friendly_bishops = position.bitboards[WHITE_BISHOP]; + } else { + friendly_pieces = blacks(position); + enemy_pieces = whites(position); + friendly_bishops = position.bitboards[BLACK_BISHOP]; + } + + __forloop_bishop_moves_gen( + moves, + friendly_bishops, + friendly_pieces, + enemy_pieces + ); +} diff --git a/src/engine/moves/king.c b/src/engine/moves/king.c new file mode 100644 index 0000000..0637109 --- /dev/null +++ b/src/engine/moves/king.c @@ -0,0 +1,53 @@ +#include "../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; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + friendly_king = position.bitboards[WHITE_KING]; + } else { + friendly_pieces = blacks(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; + print_bitboard(movement); + while (movement) { + int to = __builtin_ctzll(movement); + movement &= movement - 1; + add_move(moves, king_square, to); + } +} + +#ifdef TEST_MOD +#include <stdbool.h> +#include "../bitboard.c" +#include "./moves.c" + +bool test_empty_board() { + int i = 0; + while (i++ < 1000000000); + return true; +} + +bool test_friendly_pieces() { + return false; +} +#endif diff --git a/src/engine/moves/knight.c b/src/engine/moves/knight.c new file mode 100644 index 0000000..c48b48e --- /dev/null +++ b/src/engine/moves/knight.c @@ -0,0 +1,101 @@ +#include "../moves.h" + +bitboard_t knight_moves[64] = { + 132096ULL, + 329728ULL, + 659712ULL, + 659712ULL >> 1, + 659712ULL >> 2, + 659712ULL >> 3, + 10489856ULL, + 4202496ULL, + + 33816580ULL, + 84410376ULL, + 168886289ULL, + 168886289ULL >> 1, + 168886289ULL >> 2, + 168886289ULL >> 3, + 2685403152ULL, + 1075839008ULL, + + 8657044482ULL, + 21609056261ULL, + 43234889994ULL, + 43234889994ULL >> 1, + 43234889994ULL >> 2, + 43234889994ULL >> 3, + 687463207072ULL, + 275414786112ULL, + + 8657044482ULL >> 8, + 21609056261ULL >> 8, + 43234889994ULL >> 8, + 43234889994ULL >> (8 + 1), + 43234889994ULL >> (8 + 2), + 43234889994ULL >> (8 + 3), + 687463207072ULL >> 8, + 275414786112ULL >> 8, + + 8657044482ULL >> 16, + 21609056261ULL >> 16, + 43234889994ULL >> 16, + 43234889994ULL >> (16 + 1), + 43234889994ULL >> (16 + 2), + 43234889994ULL >> (16 + 3), + 687463207072ULL >> 16, + 275414786112ULL >> 16, + + 8657044482ULL >> 24, + 21609056261ULL >> 24, + 43234889994ULL >> 24, + 43234889994ULL >> (24 + 1), + 43234889994ULL >> (24 + 2), + 43234889994ULL >> (24 + 3), + 687463207072ULL >> 24, + 275414786112ULL >> 24, + + 288234782788157440ULL, + 576469569871282176ULL, + 1224997833292120064ULL, + 1224997833292120064ULL >> 1, + 1224997833292120064ULL >> 2, + 1224997833292120064ULL >> 3, + 1152939783987658752ULL, + 2305878468463689728ULL, + + 1128098930098176ULL, + 2257297371824128ULL, + 4796069720358912ULL, + 4796069720358912ULL >> 1, + 4796069720358912ULL >> 2, + 4796069720358912ULL >> 3, + 4679521487814656ULL, + 9077567998918656ULL, +}; + +void get_knight_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_knights; + bitboard_t friendly_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + friendly_knights = position.bitboards[WHITE_KNIGHT]; + } else { + friendly_pieces = blacks(position); + friendly_knights = position.bitboards[BLACK_KNIGHT]; + } + + while (friendly_knights) { + int from = __builtin_ctzll(friendly_knights); + friendly_knights &= friendly_knights - 1; + bitboard_t ATTACK_MASK = knight_moves[from]; + ATTACK_MASK &= ~friendly_pieces; + while (ATTACK_MASK) { + int to = __builtin_ctzll(ATTACK_MASK); + ATTACK_MASK &= ATTACK_MASK - 1; + add_move(moves, from, to); + } + } +} diff --git a/src/engine/moves/pawn.c b/src/engine/moves/pawn.c new file mode 100644 index 0000000..3cd28b8 --- /dev/null +++ b/src/engine/moves/pawn.c @@ -0,0 +1,164 @@ +#include "../moves.h" + +bitboard_t get_white_pawn_forwardmoves(moves_t* moves, position_t position) { + bitboard_t enemy_bitboard = blacks(position); + bitboard_t friendly_pieces = + position.bitboards[WHITE_KING] | + position.bitboards[WHITE_QUEEN] | + position.bitboards[WHITE_ROOK] | + position.bitboards[WHITE_BISHOP] | + position.bitboards[WHITE_KNIGHT] | + position.bitboards[WHITE_PAWN]; + bitboard_t friendly_pawns = position.bitboards[WHITE_PAWN]; + bitboard_t y = friendly_pieces | enemy_bitboard; + bitboard_t x = ~((friendly_pawns << 8) & y) & (friendly_pawns << 8); + bitboard_t first_move_x = x & BITMASK_RANK_3; + + first_move_x |= (first_move_x << 8) & (~y); + x |= first_move_x; + + return x; +} +bitboard_t get_black_pawn_forwardmoves(moves_t* moves, position_t position) { + bitboard_t enemy_bitboard = whites(position); + bitboard_t friendly_pieces = + position.bitboards[BLACK_KING] | + position.bitboards[BLACK_QUEEN] | + position.bitboards[BLACK_ROOK] | + position.bitboards[BLACK_BISHOP] | + position.bitboards[BLACK_KNIGHT] | + position.bitboards[BLACK_PAWN]; + bitboard_t friendly_pawns = position.bitboards[BLACK_PAWN]; + bitboard_t y = friendly_pieces | enemy_bitboard; + bitboard_t x = ~((friendly_pawns >> 8) & y) & (friendly_pawns >> 8); + bitboard_t first_move_x = x & BITMASK_RANK_6; + + first_move_x |= (first_move_x >> 8) & (~y); + x |= first_move_x; + + return x; +} + +void get_pawn_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t forward_moves; + bitboard_t friendly_pawns; + bitboard_t enemy_bitboard; + if (position.turn == WHITE_TURN) { + forward_moves = get_white_pawn_forwardmoves(moves, position); + friendly_pawns = position.bitboards[WHITE_PAWN]; + enemy_bitboard = blacks(position); + } else { + forward_moves = get_black_pawn_forwardmoves(moves, position); + friendly_pawns = position.bitboards[BLACK_PAWN]; + enemy_bitboard = whites(position); + } + + bitboard_t file_masks[8] = { + BITMASK_FILE_A, + BITMASK_FILE_B, + BITMASK_FILE_C, + BITMASK_FILE_D, + BITMASK_FILE_E, + BITMASK_FILE_F, + BITMASK_FILE_G, + BITMASK_FILE_H, + }; + + for (int i = 0; i < 8; i++) { + bitboard_t item = file_masks[i] & forward_moves; + bitboard_t pawns = file_masks[i] & friendly_pawns; + + int from = __builtin_ctzll(pawns); + pawns &= (pawns - 1); + int next_from = __builtin_ctzll(pawns); + if (pawns == 0) next_from = 64; // to work around UB + + while (item) { + int to = __builtin_ctzll(item); + if (to > next_from) { + from = next_from; + pawns &= (pawns - 1); + next_from = __builtin_ctzll(pawns); + if (pawns == 0) next_from = 64; + } + item &= (item - 1); + add_move(moves, from, to); + } + } + + if (position.passantable_file != 0) { + bitboard_t PASSANT_RANK; + int rank_shift; + int from_shift; + if (position.turn == WHITE_TURN) { + PASSANT_RANK = BITMASK_RANK_5; + rank_shift = 40; + from_shift = -9; + } else { + PASSANT_RANK = BITMASK_RANK_4; + from_shift = 7; + rank_shift = 16; + } + + int left = 0, right = 0; + if (position.passantable_file > 1) left = position.passantable_file - 1; + if (position.passantable_file < 8) right = position.passantable_file + 1; + if (left != 0) { + bitboard_t MASK = file_masks[left - 1] & friendly_pawns & PASSANT_RANK; + if (MASK != 0) { + add_move( + moves, + left + rank_shift + from_shift, + position.passantable_file + rank_shift - 1 + ); + } + } + if (right != 0) { + bitboard_t MASK = file_masks[right - 1] & friendly_pawns & PASSANT_RANK; + if (MASK != 0) { + add_move( + moves, + right + rank_shift + from_shift, + position.passantable_file + rank_shift - 1 + ); + } + } + } + + + bitboard_t ATTACK_MASK; + int shift; + if (position.turn == WHITE_TURN) { + shift = 0; + } else { + shift = -16; + } + for (int i = 0; i < 8; i++) { + if (i == 0) ATTACK_MASK = 512; + else if (i == 7) ATTACK_MASK = 128; + else { + ATTACK_MASK = 640; + } + bitboard_t pawns = file_masks[i] & friendly_pawns; + while (pawns) { + int from = __builtin_ctzll(pawns); + pawns &= pawns - 1; + + bitboard_t MASK; + if (from + shift > 0) { + MASK = ATTACK_MASK << (from + shift); + } else { + MASK = ATTACK_MASK >> -(from + shift); + } + + MASK &= enemy_bitboard; + while (MASK) { + int to = __builtin_ctzll(MASK); + MASK &= MASK - 1; + add_move(moves, from, to); + } + } + } +} diff --git a/src/engine/moves/queen.c b/src/engine/moves/queen.c new file mode 100644 index 0000000..9e6e5c4 --- /dev/null +++ b/src/engine/moves/queen.c @@ -0,0 +1,31 @@ +#include "../moves.h" + +void get_queen_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_queens; + bitboard_t friendly_pieces; + bitboard_t enemy_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + enemy_pieces = blacks(position); + friendly_queens = position.bitboards[WHITE_QUEEN]; + } else { + friendly_pieces = blacks(position); + enemy_pieces = whites(position); + friendly_queens = position.bitboards[BLACK_QUEEN]; + } + + __forloop_rook_moves_gen( + moves, + friendly_queens, + friendly_pieces, + enemy_pieces + ); + __forloop_bishop_moves_gen( + moves, + friendly_queens, + friendly_pieces, + enemy_pieces + ); +} diff --git a/src/engine/moves/rook.c b/src/engine/moves/rook.c new file mode 100644 index 0000000..c5867d5 --- /dev/null +++ b/src/engine/moves/rook.c @@ -0,0 +1,77 @@ +#include "../moves.h" + +void __forloop_rook_moves_gen( + moves_t* moves, + bitboard_t friendly_type, + bitboard_t friendly_pieces, + bitboard_t enemy_pieces +) { + while (friendly_type) { + int from = __builtin_ctzll(friendly_type); + friendly_type &= friendly_type - 1; + + int og_rank = from / 8; // range: [0, 7] + int og_file = from % 8; // range: [0, 7] + int rank = og_rank + 1, file = og_file, index = rank * 8 + file; + + + while (rank < 8 && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = ++rank * 8 + file; + } + + rank = og_rank - 1, file = og_file, index = rank * 8 + file; + while (rank >= 0 && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = --rank * 8 + file; + } + + rank = og_rank, file = og_file + 1, index = rank * 8 + file; + while (file < 8 && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = rank * 8 + ++file; + } + + rank = og_rank, file = og_file - 1, index = rank * 8 + file; + while (file >= 0 && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = rank * 8 + --file; + } + } +} + +void get_rook_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_rooks; + bitboard_t friendly_pieces; + bitboard_t enemy_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + enemy_pieces = blacks(position); + friendly_rooks = position.bitboards[WHITE_ROOK]; + } else { + friendly_pieces = blacks(position); + enemy_pieces = whites(position); + friendly_rooks = position.bitboards[BLACK_ROOK]; + } + + __forloop_rook_moves_gen( + moves, + friendly_rooks, + friendly_pieces, + enemy_pieces + ); +} diff --git a/src/engine/moves/vec.c b/src/engine/moves/vec.c new file mode 100644 index 0000000..6192706 --- /dev/null +++ b/src/engine/moves/vec.c @@ -0,0 +1,51 @@ +#include "../moves.h" +#include <assert.h> +#include <stdlib.h> + +void position_make_move(position_t* position, move_t* move) { + +} + +moves_t moves_init() { + return moves_init_wcapacity(16); +} + +moves_t moves_init_wcapacity(u32 capacity) { + move_t* moves = malloc(capacity * sizeof(*moves)); + return (moves_t) { + .moves = moves, + .capacity = capacity, + .length = 0, + }; +} + +moves_t moves_empty() { + return (moves_t) { + .moves = 0, + .capacity = 0, + .length = 0, + }; +} + +int min(int a, int b) { + if (a > b) return b; + return a; +} + +void add_move(moves_t* moves, square_t from, square_t to) { + assert(moves->moves != 0); + assert(from != to); + + if (moves->length + 1 >= moves->capacity) { + moves->capacity += min(32, moves->capacity); + moves->moves = realloc( + moves->moves, + moves->capacity * sizeof(*moves->moves) + ); + } + moves->moves[moves->length] = (move_t){ + .from = from, + .to = to + }; + moves->length++; +} |
