commit c9f28e3c5f003fe79e63695e9503ae8aafaa8071
parent 392b8ab7730395e637796272305b1d70a1aafcdd
Author: MikoĊaj Lenczewski <mblenczewski@gmail.com>
Date: Sun, 28 Apr 2024 15:14:34 +0000
Split out hex network protocol into separate directory
Diffstat:
A | proto/hex.h | | | 177 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 177 insertions(+), 0 deletions(-)
diff --git a/proto/hex.h b/proto/hex.h
@@ -0,0 +1,177 @@
+#ifndef HEX_PROTO_H
+#define HEX_PROTO_H
+
+#ifdef __cplusplus
+ #include <cassert>
+ #include <cstdbool>
+ #include <cstdint>
+ #include <cstring>
+#else
+ #include <assert.h>
+ #include <stdbool.h>
+ #include <stdint.h>
+ #include <string.h>
+#endif /* __cplusplus */
+
+#include <arpa/inet.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+enum hex_player {
+ HEX_PLAYER_BLACK = 0,
+ HEX_PLAYER_WHITE = 1,
+};
+
+inline enum hex_player
+hexopponent(enum hex_player player)
+{
+ switch (player) {
+ case HEX_PLAYER_BLACK: return HEX_PLAYER_WHITE;
+ case HEX_PLAYER_WHITE: return HEX_PLAYER_BLACK;
+ default: assert(false); return HEX_PLAYER_BLACK;
+ }
+}
+
+inline char const *
+hexplayerstr(enum hex_player val)
+{
+ switch (val) {
+ case HEX_PLAYER_BLACK: return "black";
+ case HEX_PLAYER_WHITE: return "white";
+ default: return "(err)";
+ }
+}
+
+enum hex_msg_type {
+ HEX_MSG_START = 0,
+ HEX_MSG_MOVE = 1,
+ HEX_MSG_SWAP = 2,
+ HEX_MSG_END = 3,
+};
+
+struct hex_msg_start {
+ uint32_t player;
+ uint32_t board_size;
+ uint32_t game_secs;
+ uint32_t thread_limit;
+ uint32_t mem_limit_mib;
+};
+
+struct hex_msg_move {
+ uint32_t board_x;
+ uint32_t board_y;
+};
+
+struct hex_msg_end {
+ uint32_t winner;
+};
+
+union hex_msg_data {
+ struct hex_msg_start start;
+ struct hex_msg_move move;
+ struct hex_msg_end end;
+};
+
+struct hex_msg {
+ uint32_t type;
+ union hex_msg_data data;
+};
+
+#define HEX_MSG_SZ 32
+
+inline bool
+#ifdef __cplusplus
+hex_msg_try_serialise(struct hex_msg const *msg, uint8_t (&out)[HEX_MSG_SZ])
+#else
+hex_msg_try_serialise(struct hex_msg const *msg, uint8_t out[static HEX_MSG_SZ])
+#endif
+{
+ assert(msg);
+ assert(out);
+
+ uint32_t *bufp = (uint32_t *) out;
+
+ *bufp++ = htonl(msg->type);
+
+ switch (msg->type) {
+ case HEX_MSG_START:
+ *bufp++ = htonl(msg->data.start.player);
+ *bufp++ = htonl(msg->data.start.board_size);
+ *bufp++ = htonl(msg->data.start.game_secs);
+ *bufp++ = htonl(msg->data.start.thread_limit);
+ *bufp++ = htonl(msg->data.start.mem_limit_mib);
+ break;
+
+ case HEX_MSG_MOVE:
+ *bufp++ = htonl(msg->data.move.board_x);
+ *bufp++ = htonl(msg->data.move.board_y);
+ break;
+
+ case HEX_MSG_SWAP:
+ break;
+
+ case HEX_MSG_END:
+ *bufp++ = htonl(msg->data.end.winner);
+ break;
+ }
+
+ /* zero out remaining all message bytes */
+ uint8_t *remaining = (uint8_t *) bufp;
+ assert(remaining < out + HEX_MSG_SZ);
+ memset(remaining, 0, (out + HEX_MSG_SZ) - remaining);
+
+ return true;
+}
+
+inline bool
+#ifdef __cplusplus
+hex_msg_try_deserialise(uint8_t (&buf)[HEX_MSG_SZ], struct hex_msg *out)
+#else
+hex_msg_try_deserialise(uint8_t buf[static HEX_MSG_SZ], struct hex_msg *out)
+#endif
+{
+ assert(buf);
+ assert(out);
+
+ uint32_t *bufp = (uint32_t *) buf;
+
+ struct hex_msg msg;
+ msg.type = ntohl(*bufp++);
+
+ switch (msg.type) {
+ case HEX_MSG_START:
+ msg.data.start.player = ntohl(*bufp++);
+ msg.data.start.board_size = ntohl(*bufp++);
+ msg.data.start.game_secs = ntohl(*bufp++);
+ msg.data.start.thread_limit = ntohl(*bufp++);
+ msg.data.start.mem_limit_mib = ntohl(*bufp++);
+ break;
+
+ case HEX_MSG_MOVE:
+ msg.data.move.board_x = ntohl(*bufp++);
+ msg.data.move.board_y = ntohl(*bufp++);
+ break;
+
+ case HEX_MSG_SWAP:
+ break;
+
+ case HEX_MSG_END:
+ msg.data.end.winner = ntohl(*bufp++);
+ break;
+
+ default:
+ return false;
+ }
+
+ *out = msg;
+
+ return true;
+}
+
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
+#endif /* HEX_PROTO_H */