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:
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);