hex

hex.git
git clone git://git.lenczewski.org/hex.git
Log | Files | Refs

commit b47497710846b98f5c5e404b588a9bb2e27ec781
parent 8c4938660f9306a5178d310d44ecf5eff6d10ec0
Author: MikoĊ‚aj Lenczewski <mblenczewski@gmail.com>
Date:   Thu,  2 Jan 2025 14:11:55 +0000

hexes: Reorganise headers and source files

Diffstat:
Magents/hexes/build.sh | 8--------
Magents/hexes/include/hexes.h | 419++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Dagents/hexes/include/hexes/agent.h | 41-----------------------------------------
Dagents/hexes/include/hexes/agent/mcts.h | 71-----------------------------------------------------------------------
Dagents/hexes/include/hexes/agent/random.h | 29-----------------------------
Dagents/hexes/include/hexes/board.h | 94-------------------------------------------------------------------------------
Dagents/hexes/include/hexes/log.h | 33---------------------------------
Dagents/hexes/include/hexes/network.h | 22----------------------
Dagents/hexes/include/hexes/threadpool.h | 16----------------
Dagents/hexes/include/hexes/types.h | 58----------------------------------------------------------
Dagents/hexes/include/hexes/utils.h | 103-------------------------------------------------------------------------------
Magents/hexes/src/agent.c | 5++++-
Magents/hexes/src/agent/mcts.c | 4++--
Magents/hexes/src/agent/random.c | 2+-
Magents/hexes/src/board.c | 2+-
Magents/hexes/src/hexes.c | 11++++++-----
Dagents/hexes/src/log.c | 4----
Magents/hexes/src/network.c | 2+-
Magents/hexes/src/threadpool.c | 2+-
Magents/hexes/src/utils.c | 5++++-
20 files changed, 437 insertions(+), 494 deletions(-)

diff --git a/agents/hexes/build.sh b/agents/hexes/build.sh @@ -12,14 +12,6 @@ TARGET="hexes" SOURCES=" src/hexes.c - src/agent.c - src/agent/mcts.c - src/agent/random.c - src/board.c - src/log.c - src/network.c - src/threadpool.c - src/utils.c " set -ex diff --git a/agents/hexes/include/hexes.h b/agents/hexes/include/hexes.h @@ -19,6 +19,7 @@ #include <assert.h> #include <errno.h> +#include <inttypes.h> #include <stdalign.h> #include <stdarg.h> #include <stdbool.h> @@ -36,7 +37,53 @@ #include <time.h> #include <unistd.h> -#include "hexes/types.h" +typedef int32_t b32; + +typedef unsigned char c8; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +typedef float f32; +typedef double f64; + +#define ARRLEN(arr) (sizeof (arr) / sizeof (arr)[0]) + +#define MIN(a, b) ((a) > (b) ? (a) : (b)) +#define MAX(a, b) ((a) < (b) ? (b) : (a)) + +#define RELPTR_NULL (0) + +#define _RELPTR_MASK(ty_relptr) ((ty_relptr)1 << ((sizeof(ty_relptr) * 8) - 1)) +#define _RELPTR_ENC(ty_relptr, ptroff) \ + ((ty_relptr)((ptroff) ^ _RELPTR_MASK(ty_relptr))) +#define _RELPTR_DEC(ty_relptr, relptr) \ + ((ty_relptr)((relptr) ^ _RELPTR_MASK(ty_relptr))) + +#define RELPTR_ABS2REL(ty_relptr, base, absptr) \ + ((absptr) \ + ? _RELPTR_ENC(ty_relptr, (u8 *) absptr - (u8 *) base) \ + : RELPTR_NULL) + +#define RELPTR_REL2ABS(ty_absptr, ty_relptr, base, relptr) \ + ((relptr) \ + ? ((ty_absptr)((u8 *) base + _RELPTR_DEC(ty_relptr, relptr))) \ + : NULL) + +#define NANOSECS (1000000000ULL) + +#define TIMESPEC_TO_NANOS(sec, nsec) (((u64) (sec) * NANOSECS) + (nsec)) + +#define KiB (1024ULL) +#define MiB (1024ULL * KiB) +#define GiB (1024ULL * MiB) struct opts { u32 log_level, agent_type; @@ -45,6 +92,374 @@ struct opts { extern struct opts opts; -#include "hexes/log.h" +/* utility definitions + * =========================================================================== + */ + +enum log_level { + LOG_ERROR, + LOG_WARN, + LOG_INFO, + LOG_DEBUG, +}; + +inline void +dbglog(enum log_level log_level, char const *fmt, ...) +{ + if (opts.log_level < log_level) return; + + switch (log_level) { + case LOG_ERROR: fputs("[ERROR]", stderr); break; + case LOG_WARN: fputs("[WARN] ", stderr); break; + case LOG_INFO: fputs("[INFO] ", stderr); break; + case LOG_DEBUG: fputs("[DEBUG]", stderr); break; + } + + fputc(' ', stderr); + + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + + +inline void +swap(void *restrict lhs, void *restrict rhs, size_t size) +{ + assert(lhs); + assert(rhs); + assert(size); + + u8 tmp[size]; + + memcpy(tmp, rhs, size); + memcpy(rhs, lhs, size); + memcpy(lhs, tmp, size); +} + +inline void +shuffle(void *arr, size_t size, size_t len) +{ + assert(arr); + assert(size); + + for (size_t i = 0; i < len - 2; i++) { + size_t j = (i + random()) % len; + + swap((u8 *) arr + (i * size), + (u8 *) arr + (j * size), + size); + } +} + +inline void +difftimespec(struct timespec *restrict lhs, struct timespec *restrict rhs, struct timespec *restrict out) +{ + if (lhs->tv_sec <= rhs->tv_sec && lhs->tv_nsec < rhs->tv_nsec) { + out->tv_sec = 0; + out->tv_nsec = 0; + } else { + out->tv_sec = lhs->tv_sec - rhs->tv_sec - (lhs->tv_nsec < rhs->tv_nsec); + out->tv_nsec = lhs->tv_nsec - rhs->tv_nsec + (lhs->tv_nsec < rhs->tv_nsec) * NANOSECS; + } +} + +#define IS_POW2(v) (((v) & ((v) - 1)) == 0) +#define IS_ALIGNED(v, align) (((v) & ((align) - 1)) == 0) + +#define ALIGN_PREV(v, align) ((v) & ~((v) - 1)) +#define ALIGN_NEXT(v, align) ALIGN_PREV((v) + ((align) - 1), (align)) + +struct mem_pool { + void *ptr; + size_t cap, len; +}; + +inline bool +mem_pool_init(struct mem_pool *self, size_t align, size_t capacity) +{ + assert(self); + assert(align); + assert(IS_POW2(align)); + assert(capacity % align == 0); + + self->ptr = aligned_alloc(align, capacity); + if (!self->ptr) return false; + + self->cap = capacity; + self->len = 0; + + return true; +} + +inline void +mem_pool_free(struct mem_pool *self) +{ + assert(self); + + free(self->ptr); +} + +inline void +mem_pool_reset(struct mem_pool *self) +{ + assert(self); + + self->len = 0; +} + +inline void * +mem_pool_alloc(struct mem_pool *self, size_t align, size_t size) +{ + assert(self); + assert(align); + assert(IS_POW2(align)); + + size_t aligned_len = ALIGN_NEXT(self->len, align); + if (aligned_len + size > self->cap) + return NULL; + + void *ptr = (void *) ((intptr_t) self->ptr + aligned_len); + self->len = aligned_len + size; + + return ptr; +} + +/* network definitions + * =========================================================================== + */ + +struct network { + int sockfd; +}; + +bool +network_init(struct network *self, char const *host, char const *port); + +void +network_free(struct network *self); + +bool +network_send(struct network *self, struct hex_msg const *msg); + +bool +network_recv(struct network *self, struct hex_msg *out, enum hex_msg_type *expected, + size_t len); + +/* board definitions + * =========================================================================== + */ + +enum cell { + CELL_BLACK = HEX_PLAYER_BLACK, + CELL_WHITE = HEX_PLAYER_WHITE, + CELL_EMPTY, +}; + +typedef s16 segment_relptr_t; + +struct segment { + enum cell occupant; + u32 rank; + segment_relptr_t parent; +}; + +inline segment_relptr_t +segment_abs2rel(void const *base, struct segment *absptr) +{ + return RELPTR_ABS2REL(segment_relptr_t, base, absptr); +} + +inline struct segment * +segment_rel2abs(void const *base, segment_relptr_t relptr) +{ + return RELPTR_REL2ABS(struct segment *, segment_relptr_t, base, relptr); +} + +enum board_edges { + BLACK_SOURCE, + BLACK_SINK, + WHITE_SOURCE, + WHITE_SINK, + _BOARD_EDGE_COUNT, +}; + +struct board { + u32 size; + struct segment *segments; +}; + +inline struct segment * +board_black_source(struct board *self) +{ + return &self->segments[self->size * self->size + BLACK_SOURCE]; +} + +inline struct segment * +board_black_sink(struct board *self) +{ + return &self->segments[self->size * self->size + BLACK_SINK]; +} + +inline struct segment * +board_white_source(struct board *self) +{ + return &self->segments[self->size * self->size + WHITE_SOURCE]; +} + +inline struct segment * +board_white_sink(struct board *self) +{ + return &self->segments[self->size * self->size + WHITE_SINK]; +} + +struct move { + u8 x, y; +}; + +bool +board_init(struct board *self, u32 size); + +void +board_free(struct board *self); + +void +board_copy(struct board const *restrict self, struct board *restrict other); + +bool +board_play(struct board *self, enum hex_player player, u32 x, u32 y); + +void +board_swap(struct board *self); + +size_t +board_available_moves(struct board const *self, struct move *buf); + +bool +board_winner(struct board *self, enum hex_player *out); + +/* agent definitions + * =========================================================================== + */ + +struct threadpool { + u32 threads; +}; + +bool +threadpool_init(struct threadpool *self, u32 threads); + +void +threadpool_free(struct threadpool *self); + +struct agent_random { + size_t len; + struct move *moves; +}; + +bool +agent_random_init(struct agent_random *self, struct board const *board); + +void +agent_random_free(struct agent_random *self); + +void +agent_random_play(struct agent_random *self, enum hex_player player, u32 x, u32 y); + +void +agent_random_swap(struct agent_random *self); + +bool +agent_random_next(struct agent_random *self, struct timespec timeout, u32 *out_x, u32 *out_y); + +#define MCTS_RESERVED_MEM (MiB) + +typedef s64 mcts_node_relptr_t; + +struct mcts_node { + mcts_node_relptr_t parent; + enum hex_player player; + u8 x, y; + + s32 wins, rave_wins; + u32 plays, rave_plays; + + u16 children_cap, children_len; + mcts_node_relptr_t children[]; +}; + +inline size_t +mcts_node_sizeof(size_t children) +{ + return sizeof(struct mcts_node) + children * sizeof(mcts_node_relptr_t); +} + +inline mcts_node_relptr_t +mcts_node_abs2rel(void *base, struct mcts_node *absptr) +{ + return RELPTR_ABS2REL(mcts_node_relptr_t, base, absptr); +} + +inline struct mcts_node * +mcts_node_rel2abs(void *base, mcts_node_relptr_t relptr) +{ + return RELPTR_REL2ABS(struct mcts_node *, mcts_node_relptr_t, base, relptr); +} + +struct agent_mcts { + struct board const *board; + struct threadpool *threadpool; + + struct board shadow_board; + + struct mem_pool pool; + struct mcts_node *root; +}; + +bool +agent_mcts_init(struct agent_mcts *self, struct board const *board, struct threadpool *threadpool, + u32 mem_limit_mib, enum hex_player player); + +void +agent_mcts_free(struct agent_mcts *self); + +void +agent_mcts_play(struct agent_mcts *self, enum hex_player player, u32 x, u32 y); + +void +agent_mcts_swap(struct agent_mcts *self); + +bool +agent_mcts_next(struct agent_mcts *self, struct timespec timeout, u32 *out_x, u32 *out_y); + +enum agent_type { + AGENT_RANDOM, + AGENT_MCTS, +}; + +struct agent { + enum agent_type type; + union { + struct agent_random random; + struct agent_mcts mcts; + } backend; +}; + +bool +agent_init(struct agent *self, enum agent_type type, struct board const *board, + struct threadpool *threadpool, u32 mem_limit_mib, enum hex_player player); + +void +agent_free(struct agent *self); + +void +agent_play(struct agent *self, enum hex_player player, u32 x, u32 y); + +void +agent_swap(struct agent *self); + +bool +agent_next(struct agent *self, struct timespec timeout, u32 *out_x, u32 *out_y); #endif /* HEXES_H */ diff --git a/agents/hexes/include/hexes/agent.h b/agents/hexes/include/hexes/agent.h @@ -1,41 +0,0 @@ -#ifndef HEXES_AGENT_H -#define HEXES_AGENT_H - -#include "hexes.h" - -#include "hexes/board.h" -#include "hexes/threadpool.h" - -#include "hexes/agent/random.h" -#include "hexes/agent/mcts.h" - -enum agent_type { - AGENT_RANDOM, - AGENT_MCTS, -}; - -struct agent { - enum agent_type type; - union { - struct agent_random random; - struct agent_mcts mcts; - } backend; -}; - -bool -agent_init(struct agent *self, enum agent_type type, struct board const *board, - struct threadpool *threadpool, u32 mem_limit_mib, enum hex_player player); - -void -agent_free(struct agent *self); - -void -agent_play(struct agent *self, enum hex_player player, u32 x, u32 y); - -void -agent_swap(struct agent *self); - -bool -agent_next(struct agent *self, struct timespec timeout, u32 *out_x, u32 *out_y); - -#endif /* HEXES_AGENT_H */ diff --git a/agents/hexes/include/hexes/agent/mcts.h b/agents/hexes/include/hexes/agent/mcts.h @@ -1,71 +0,0 @@ -#ifndef HEXES_AGENT_MCTS_H -#define HEXES_AGENT_MCTS_H - -#include "hexes.h" - -#include "hexes/board.h" -#include "hexes/threadpool.h" -#include "hexes/utils.h" - -#define RESERVED_MEM (MiB) - -typedef s64 mcts_node_relptr_t; - -struct mcts_node { - mcts_node_relptr_t parent; - enum hex_player player; - u8 x, y; - - s32 wins, rave_wins; - u32 plays, rave_plays; - - u16 children_cap, children_len; - mcts_node_relptr_t children[]; -}; - -inline size_t -mcts_node_sizeof(size_t children) -{ - return sizeof(struct mcts_node) + children * sizeof(mcts_node_relptr_t); -} - -inline mcts_node_relptr_t -mcts_node_abs2rel(void *base, struct mcts_node *absptr) -{ - return RELPTR_ABS2REL(mcts_node_relptr_t, base, absptr); -} - -inline struct mcts_node * -mcts_node_rel2abs(void *base, mcts_node_relptr_t relptr) -{ - return RELPTR_REL2ABS(struct mcts_node *, mcts_node_relptr_t, base, relptr); -} - -struct agent_mcts { - struct board const *board; - struct threadpool *threadpool; - - struct board shadow_board; - - struct mem_pool pool; - struct mcts_node *root; -}; - -bool -agent_mcts_init(struct agent_mcts *self, struct board const *board, struct threadpool *threadpool, - u32 mem_limit_mib, enum hex_player player); - -void -agent_mcts_free(struct agent_mcts *self); - -void -agent_mcts_play(struct agent_mcts *self, enum hex_player player, u32 x, u32 y); - -void -agent_mcts_swap(struct agent_mcts *self); - -bool -agent_mcts_next(struct agent_mcts *self, struct timespec timeout, u32 *out_x, u32 *out_y); - - -#endif /* HEXES_AGENT_MCTS_H */ diff --git a/agents/hexes/include/hexes/agent/random.h b/agents/hexes/include/hexes/agent/random.h @@ -1,29 +0,0 @@ -#ifndef HEXES_AGENT_RANDOM_H -#define HEXES_AGENT_RANDOM_H - -#include "hexes.h" - -#include "hexes/board.h" -#include "hexes/utils.h" - -struct agent_random { - size_t len; - struct move *moves; -}; - -bool -agent_random_init(struct agent_random *self, struct board const *board); - -void -agent_random_free(struct agent_random *self); - -void -agent_random_play(struct agent_random *self, enum hex_player player, u32 x, u32 y); - -void -agent_random_swap(struct agent_random *self); - -bool -agent_random_next(struct agent_random *self, struct timespec timeout, u32 *out_x, u32 *out_y); - -#endif /* HEXES_AGENT_RANDOM_H */ diff --git a/agents/hexes/include/hexes/board.h b/agents/hexes/include/hexes/board.h @@ -1,94 +0,0 @@ -#ifndef HEXES_BOARD_H -#define HEXES_BOARD_H - -#include "hexes.h" - -enum cell { - CELL_BLACK = HEX_PLAYER_BLACK, - CELL_WHITE = HEX_PLAYER_WHITE, - CELL_EMPTY, -}; - -typedef s16 segment_relptr_t; - -struct segment { - enum cell occupant; - u32 rank; - segment_relptr_t parent; -}; - -inline segment_relptr_t -segment_abs2rel(void const *base, struct segment *absptr) -{ - return RELPTR_ABS2REL(segment_relptr_t, base, absptr); -} - -inline struct segment * -segment_rel2abs(void const *base, segment_relptr_t relptr) -{ - return RELPTR_REL2ABS(struct segment *, segment_relptr_t, base, relptr); -} - -enum board_edges { - BLACK_SOURCE, - BLACK_SINK, - WHITE_SOURCE, - WHITE_SINK, - _BOARD_EDGE_COUNT, -}; - -struct board { - u32 size; - struct segment *segments; -}; - -inline struct segment * -board_black_source(struct board *self) -{ - return &self->segments[self->size * self->size + BLACK_SOURCE]; -} - -inline struct segment * -board_black_sink(struct board *self) -{ - return &self->segments[self->size * self->size + BLACK_SINK]; -} - -inline struct segment * -board_white_source(struct board *self) -{ - return &self->segments[self->size * self->size + WHITE_SOURCE]; -} - -inline struct segment * -board_white_sink(struct board *self) -{ - return &self->segments[self->size * self->size + WHITE_SINK]; -} - -struct move { - u8 x, y; -}; - -bool -board_init(struct board *self, u32 size); - -void -board_free(struct board *self); - -void -board_copy(struct board const *restrict self, struct board *restrict other); - -bool -board_play(struct board *self, enum hex_player player, u32 x, u32 y); - -void -board_swap(struct board *self); - -size_t -board_available_moves(struct board const *self, struct move *buf); - -bool -board_winner(struct board *self, enum hex_player *out); - -#endif /* HEXES_BOARD_H */ diff --git a/agents/hexes/include/hexes/log.h b/agents/hexes/include/hexes/log.h @@ -1,33 +0,0 @@ -#ifndef HEXES_LOG_H -#define HEXES_LOG_H - -#include "hexes.h" - -enum log_level { - LOG_ERROR, - LOG_WARN, - LOG_INFO, - LOG_DEBUG, -}; - -inline void -dbglog(enum log_level log_level, char const *fmt, ...) -{ - if (opts.log_level < log_level) return; - - switch (log_level) { - case LOG_ERROR: fputs("[ERROR]", stderr); break; - case LOG_WARN: fputs("[WARN] ", stderr); break; - case LOG_INFO: fputs("[INFO] ", stderr); break; - case LOG_DEBUG: fputs("[DEBUG]", stderr); break; - } - - fputc(' ', stderr); - - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -#endif /* HEXES_LOG_H */ diff --git a/agents/hexes/include/hexes/network.h b/agents/hexes/include/hexes/network.h @@ -1,22 +0,0 @@ -#ifndef HEXES_NETWORK_H -#define HEXES_NETWORK_H - -#include "hexes.h" - -struct network { - int sockfd; -}; - -bool -network_init(struct network *self, char const *host, char const *port); - -void -network_free(struct network *self); - -bool -network_send(struct network *self, struct hex_msg const *msg); - -bool -network_recv(struct network *self, struct hex_msg *out, enum hex_msg_type *expected, size_t len); - -#endif /* HEXES_NETWORK_H */ diff --git a/agents/hexes/include/hexes/threadpool.h b/agents/hexes/include/hexes/threadpool.h @@ -1,16 +0,0 @@ -#ifndef HEXES_THREADPOOL_H -#define HEXES_THREADPOOL_H - -#include "hexes.h" - -struct threadpool { - u32 threads; -}; - -bool -threadpool_init(struct threadpool *self, u32 threads); - -void -threadpool_free(struct threadpool *self); - -#endif /* HEXES_THREADPOOL_H */ diff --git a/agents/hexes/include/hexes/types.h b/agents/hexes/include/hexes/types.h @@ -1,58 +0,0 @@ -#ifndef HEXES_TYPES_H -#define HEXES_TYPES_H - -#include <assert.h> -#include <inttypes.h> -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - -typedef int32_t b32; - -typedef unsigned char c8; - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; - -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; - -typedef float f32; -typedef double f64; - -#define ARRLEN(arr) (sizeof (arr) / sizeof (arr)[0]) - -#define MIN(a, b) ((a) > (b) ? (a) : (b)) -#define MAX(a, b) ((a) < (b) ? (b) : (a)) - -#define RELPTR_NULL (0) - -#define _RELPTR_MASK(ty_relptr) ((ty_relptr)1 << ((sizeof(ty_relptr) * 8) - 1)) -#define _RELPTR_ENC(ty_relptr, ptroff) \ - ((ty_relptr)((ptroff) ^ _RELPTR_MASK(ty_relptr))) -#define _RELPTR_DEC(ty_relptr, relptr) \ - ((ty_relptr)((relptr) ^ _RELPTR_MASK(ty_relptr))) - -#define RELPTR_ABS2REL(ty_relptr, base, absptr) \ - ((absptr) \ - ? _RELPTR_ENC(ty_relptr, (u8 *) absptr - (u8 *) base) \ - : RELPTR_NULL) - -#define RELPTR_REL2ABS(ty_absptr, ty_relptr, base, relptr) \ - ((relptr) \ - ? ((ty_absptr)((u8 *) base + _RELPTR_DEC(ty_relptr, relptr))) \ - : NULL) - -#define NANOSECS (1000000000ULL) - -#define TIMESPEC_TO_NANOS(sec, nsec) (((u64) (sec) * NANOSECS) + (nsec)) - -#define KiB (1024ULL) -#define MiB (1024ULL * KiB) -#define GiB (1024ULL * MiB) - -#endif /* HEXES_TYPES_H */ diff --git a/agents/hexes/include/hexes/utils.h b/agents/hexes/include/hexes/utils.h @@ -1,103 +0,0 @@ -#ifndef HEXES_UTILS_H -#define HEXES_UTILS_H - -#include "hexes.h" - -inline void -swap(void *restrict lhs, void *restrict rhs, size_t size) -{ - assert(lhs); - assert(rhs); - assert(size); - - u8 tmp[size]; - - memcpy(tmp, rhs, size); - memcpy(rhs, lhs, size); - memcpy(lhs, tmp, size); -} - -inline void -shuffle(void *arr, size_t size, size_t len) -{ - assert(arr); - assert(size); - - for (size_t i = 0; i < len - 2; i++) { - size_t j = (i + random()) % len; - - swap((u8 *) arr + (i * size), - (u8 *) arr + (j * size), - size); - } -} - -inline void -difftimespec(struct timespec *restrict lhs, struct timespec *restrict rhs, struct timespec *restrict out) -{ - if (lhs->tv_sec <= rhs->tv_sec && lhs->tv_nsec < rhs->tv_nsec) { - out->tv_sec = 0; - out->tv_nsec = 0; - } else { - out->tv_sec = lhs->tv_sec - rhs->tv_sec - (lhs->tv_nsec < rhs->tv_nsec); - out->tv_nsec = lhs->tv_nsec - rhs->tv_nsec + (lhs->tv_nsec < rhs->tv_nsec) * NANOSECS; - } -} - -struct mem_pool { - void *ptr; - size_t cap, len; -}; - -inline bool -mem_pool_init(struct mem_pool *self, size_t align, size_t capacity) -{ - assert(self); - assert(align); - assert(align % 2 == 0); - assert(capacity % align == 0); - - self->ptr = aligned_alloc(align, capacity); - if (!self->ptr) return false; - - self->cap = capacity; - self->len = 0; - - return true; -} - -inline void -mem_pool_free(struct mem_pool *self) -{ - assert(self); - - free(self->ptr); -} - -inline void -mem_pool_reset(struct mem_pool *self) -{ - assert(self); - - self->len = 0; -} - -inline void * -mem_pool_alloc(struct mem_pool *self, size_t align, size_t size) -{ - assert(self); - assert(align); - assert(align % 2 == 0); - - size_t align_off = align - 1, align_mask = ~align_off; - size_t aligned_len = (self->len + align_off) & align_mask; - - if (aligned_len + size >= self->cap) return NULL; - - void *ptr = (u8 *) self->ptr + aligned_len; - self->len = aligned_len + size; - - return ptr; -} - -#endif /* HEXES_UTILS_H */ diff --git a/agents/hexes/src/agent.c b/agents/hexes/src/agent.c @@ -1,4 +1,4 @@ -#include "hexes/agent.h" +#include "hexes.h" bool agent_init(struct agent *self, enum agent_type type, struct board const *board, @@ -68,3 +68,6 @@ agent_next(struct agent *self, struct timespec timeout, u32 *out_x, u32 *out_y) return false; } + +#include "agent/random.c" +#include "agent/mcts.c" diff --git a/agents/hexes/src/agent/mcts.c b/agents/hexes/src/agent/mcts.c @@ -1,4 +1,4 @@ -#include "hexes/agent/mcts.h" +#include "hexes.h" extern inline size_t mcts_node_sizeof(size_t children); @@ -148,7 +148,7 @@ agent_mcts_init(struct agent_mcts *self, struct board const *board, struct threa if (!board_init(&self->shadow_board, board->size)) return false; size_t align = alignof(struct mcts_node); - size_t cap = ((mem_limit_mib * MiB) - RESERVED_MEM) & ~(align - 1); + size_t cap = ((mem_limit_mib * MiB) - MCTS_RESERVED_MEM) & ~(align - 1); if (!mem_pool_init(&self->pool, align, cap)) { board_free(&self->shadow_board); diff --git a/agents/hexes/src/agent/random.c b/agents/hexes/src/agent/random.c @@ -1,4 +1,4 @@ -#include "hexes/agent/random.h" +#include "hexes.h" bool agent_random_init(struct agent_random *self, struct board const *board) diff --git a/agents/hexes/src/board.c b/agents/hexes/src/board.c @@ -1,4 +1,4 @@ -#include "hexes/board.h" +#include "hexes.h" #define NEIGHBOUR_COUNT 6 diff --git a/agents/hexes/src/hexes.c b/agents/hexes/src/hexes.c @@ -1,9 +1,4 @@ #include "hexes.h" -#include "hexes/agent.h" -#include "hexes/board.h" -#include "hexes/log.h" -#include "hexes/network.h" -#include "hexes/threadpool.h" struct opts opts = { .log_level = LOG_INFO, @@ -292,3 +287,9 @@ end_handler(struct game *game) game->game_over = true; } + +#include "network.c" +#include "board.c" +#include "threadpool.c" +#include "utils.c" +#include "agent.c" diff --git a/agents/hexes/src/log.c b/agents/hexes/src/log.c @@ -1,4 +0,0 @@ -#include "hexes/log.h" - -extern inline void -dbglog(enum log_level, char const *, ...); diff --git a/agents/hexes/src/network.c b/agents/hexes/src/network.c @@ -1,4 +1,4 @@ -#include "hexes/network.h" +#include "hexes.h" bool network_init(struct network *self, char const *host, char const *port) diff --git a/agents/hexes/src/threadpool.c b/agents/hexes/src/threadpool.c @@ -1,4 +1,4 @@ -#include "hexes/threadpool.h" +#include "hexes.h" bool threadpool_init(struct threadpool *self, u32 threads) diff --git a/agents/hexes/src/utils.c b/agents/hexes/src/utils.c @@ -1,4 +1,7 @@ -#include "hexes/utils.h" +#include "hexes.h" + +extern inline void +dbglog(enum log_level, char const *, ...); extern inline void swap(void *restrict lhs, void *restrict rhs, size_t size);