hex.h (3311B)
1 #ifndef HEX_PROTO_H 2 #define HEX_PROTO_H 3 4 #ifdef __cplusplus 5 #include <cassert> 6 #include <cstdbool> 7 #include <cstdint> 8 #include <cstring> 9 #else 10 #include <assert.h> 11 #include <stdbool.h> 12 #include <stdint.h> 13 #include <string.h> 14 #endif /* __cplusplus */ 15 16 #include <arpa/inet.h> 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif /* __cplusplus */ 21 22 enum hex_player { 23 HEX_PLAYER_BLACK = 0, 24 HEX_PLAYER_WHITE = 1, 25 }; 26 27 inline enum hex_player 28 hexopponent(enum hex_player player) 29 { 30 switch (player) { 31 case HEX_PLAYER_BLACK: return HEX_PLAYER_WHITE; 32 case HEX_PLAYER_WHITE: return HEX_PLAYER_BLACK; 33 default: assert(false); return HEX_PLAYER_BLACK; 34 } 35 } 36 37 inline char const * 38 hexplayerstr(enum hex_player val) 39 { 40 switch (val) { 41 case HEX_PLAYER_BLACK: return "black"; 42 case HEX_PLAYER_WHITE: return "white"; 43 default: return "(err)"; 44 } 45 } 46 47 enum hex_msg_type { 48 HEX_MSG_START = 0, 49 HEX_MSG_MOVE = 1, 50 HEX_MSG_SWAP = 2, 51 HEX_MSG_END = 3, 52 }; 53 54 struct hex_msg_start { 55 uint32_t player; 56 uint32_t board_size; 57 uint32_t game_secs; 58 uint32_t thread_limit; 59 uint32_t mem_limit_mib; 60 }; 61 62 struct hex_msg_move { 63 uint32_t board_x; 64 uint32_t board_y; 65 }; 66 67 struct hex_msg_end { 68 uint32_t winner; 69 }; 70 71 union hex_msg_data { 72 struct hex_msg_start start; 73 struct hex_msg_move move; 74 struct hex_msg_end end; 75 }; 76 77 struct hex_msg { 78 uint32_t type; 79 union hex_msg_data data; 80 }; 81 82 #define HEX_MSG_SZ 32 83 84 inline bool 85 #ifdef __cplusplus 86 hex_msg_try_serialise(struct hex_msg const *msg, uint8_t (&out)[HEX_MSG_SZ]) 87 #else 88 hex_msg_try_serialise(struct hex_msg const *msg, uint8_t out[static HEX_MSG_SZ]) 89 #endif 90 { 91 assert(msg); 92 assert(out); 93 94 uint32_t *bufp = (uint32_t *) out; 95 96 *bufp++ = htonl(msg->type); 97 98 switch (msg->type) { 99 case HEX_MSG_START: 100 *bufp++ = htonl(msg->data.start.player); 101 *bufp++ = htonl(msg->data.start.board_size); 102 *bufp++ = htonl(msg->data.start.game_secs); 103 *bufp++ = htonl(msg->data.start.thread_limit); 104 *bufp++ = htonl(msg->data.start.mem_limit_mib); 105 break; 106 107 case HEX_MSG_MOVE: 108 *bufp++ = htonl(msg->data.move.board_x); 109 *bufp++ = htonl(msg->data.move.board_y); 110 break; 111 112 case HEX_MSG_SWAP: 113 break; 114 115 case HEX_MSG_END: 116 *bufp++ = htonl(msg->data.end.winner); 117 break; 118 } 119 120 /* zero out remaining all message bytes */ 121 uint8_t *remaining = (uint8_t *) bufp; 122 assert(remaining < out + HEX_MSG_SZ); 123 memset(remaining, 0, (out + HEX_MSG_SZ) - remaining); 124 125 return true; 126 } 127 128 inline bool 129 #ifdef __cplusplus 130 hex_msg_try_deserialise(uint8_t (&buf)[HEX_MSG_SZ], struct hex_msg *out) 131 #else 132 hex_msg_try_deserialise(uint8_t buf[static HEX_MSG_SZ], struct hex_msg *out) 133 #endif 134 { 135 assert(buf); 136 assert(out); 137 138 uint32_t *bufp = (uint32_t *) buf; 139 140 struct hex_msg msg; 141 msg.type = ntohl(*bufp++); 142 143 switch (msg.type) { 144 case HEX_MSG_START: 145 msg.data.start.player = ntohl(*bufp++); 146 msg.data.start.board_size = ntohl(*bufp++); 147 msg.data.start.game_secs = ntohl(*bufp++); 148 msg.data.start.thread_limit = ntohl(*bufp++); 149 msg.data.start.mem_limit_mib = ntohl(*bufp++); 150 break; 151 152 case HEX_MSG_MOVE: 153 msg.data.move.board_x = ntohl(*bufp++); 154 msg.data.move.board_y = ntohl(*bufp++); 155 break; 156 157 case HEX_MSG_SWAP: 158 break; 159 160 case HEX_MSG_END: 161 msg.data.end.winner = ntohl(*bufp++); 162 break; 163 164 default: 165 return false; 166 } 167 168 *out = msg; 169 170 return true; 171 } 172 173 #ifdef __cplusplus 174 }; 175 #endif /* __cplusplus */ 176 177 #endif /* HEX_PROTO_H */