hex

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

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:
Aproto/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 */