feat: establish the bounded production architecture
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
kBoardWidth = 10,
|
||||
kBoardHeight = 10,
|
||||
kBoardCellCount = kBoardWidth * kBoardHeight,
|
||||
kFleetShipCount = 10,
|
||||
kPlayerCapacity = 2,
|
||||
kSpectatorCapacity = 8,
|
||||
kSessionCapacity = kPlayerCapacity + kSpectatorCapacity,
|
||||
kCommandQueueCapacity = 16,
|
||||
kStateMessageCapacity = 512,
|
||||
kRequestBodyCapacity = 192,
|
||||
kSessionTokenBytes = 16,
|
||||
kDisplayNameBytes = 80,
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct { uint64_t (*now_ms)(void *context); void *context; } clock_t;
|
||||
typedef struct { uint32_t (*next_u32)(void *context); void *context; } random_source_t;
|
||||
typedef struct { bool (*schedule_after_ms)(void *context, uint32_t delay_ms); void *context; } scheduler_t;
|
||||
typedef struct { bool (*send)(void *context, int client_id, const char *data, size_t length); void *context; } transport_t;
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "command_queue.h"
|
||||
|
||||
/* The application task is the sole owner of game_state_t mutations. */
|
||||
typedef struct { command_queue_t command_queue; game_state_t state; } application_t;
|
||||
|
||||
bool application_enqueue(application_t *application, const app_command_t *command);
|
||||
bool application_take_next_command(application_t *application, app_command_t *command);
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "app_interfaces.h"
|
||||
|
||||
typedef struct { random_source_t random; scheduler_t scheduler; } bot_player_t;
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_config.h"
|
||||
#include "game_types.h"
|
||||
|
||||
typedef uint8_t command_type_t;
|
||||
enum { COMMAND_CONFIG, COMMAND_START, COMMAND_SHOT, COMMAND_REMATCH, COMMAND_ABORT };
|
||||
typedef struct { command_type_t type; uint8_t session_index; uint32_t game_id; uint32_t version; coordinate_t coordinate; game_mode_t mode; } app_command_t;
|
||||
typedef struct { app_command_t entries[kCommandQueueCapacity]; uint8_t head; uint8_t tail; uint8_t count; } command_queue_t;
|
||||
|
||||
bool command_queue_push(command_queue_t *queue, const app_command_t *command);
|
||||
bool command_queue_pop(command_queue_t *queue, app_command_t *command);
|
||||
_Static_assert(sizeof(command_queue_t) <= 320, "command queue grew beyond fixed budget");
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint64_t uptime_ms;
|
||||
uint32_t free_heap_bytes;
|
||||
uint32_t minimum_free_heap_bytes;
|
||||
uint32_t largest_free_block_bytes;
|
||||
uint16_t connected_clients;
|
||||
uint16_t rejected_oversized_input;
|
||||
int reset_reason;
|
||||
} diagnostics_t;
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "app_interfaces.h"
|
||||
#include "game_types.h"
|
||||
|
||||
typedef struct { random_source_t random; } fleet_generator_t;
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "game_types.h"
|
||||
|
||||
/* Rule implementation begins in Milestone 007. */
|
||||
typedef struct { game_state_t state; } game_engine_t;
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_config.h"
|
||||
|
||||
typedef uint8_t cell_t;
|
||||
enum { CELL_UNKNOWN, CELL_WATER, CELL_SHIP, CELL_MISS, CELL_HIT };
|
||||
typedef uint8_t phase_t;
|
||||
enum { PHASE_LOBBY, PHASE_PREPARING, PHASE_IN_PROGRESS, PHASE_FINISHED, PHASE_REMATCH_WAIT };
|
||||
typedef uint8_t role_t;
|
||||
enum { ROLE_PLAYER_1, ROLE_PLAYER_2, ROLE_SPECTATOR };
|
||||
typedef uint8_t game_mode_t;
|
||||
enum { MODE_HUMAN, MODE_BOT };
|
||||
|
||||
typedef struct { uint8_t x; uint8_t y; } coordinate_t;
|
||||
typedef struct { uint8_t x; uint8_t y; uint8_t length; uint8_t hits; bool horizontal; } ship_t;
|
||||
typedef struct { cell_t cells[kBoardCellCount]; ship_t ships[kFleetShipCount]; uint8_t ships_alive; } board_t;
|
||||
typedef struct { uint32_t game_id; uint32_t version; phase_t phase; game_mode_t mode; uint8_t current_player; board_t boards[kPlayerCapacity]; } game_state_t;
|
||||
|
||||
_Static_assert(kBoardCellCount == 100, "board contract changed");
|
||||
_Static_assert(kFleetShipCount == 10, "fleet contract changed");
|
||||
_Static_assert(kSessionCapacity == 10, "session contract changed");
|
||||
_Static_assert(sizeof(coordinate_t) == 2, "coordinate must remain compact");
|
||||
_Static_assert(sizeof(ship_t) <= 6, "ship grew beyond fixed budget");
|
||||
_Static_assert(sizeof(board_t) <= 164, "board grew beyond fixed budget");
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "app_config.h"
|
||||
#include "game_types.h"
|
||||
|
||||
typedef struct { role_t role; bool occupied; uint8_t token[kSessionTokenBytes]; char name[kDisplayNameBytes + 1]; } session_t;
|
||||
typedef struct { session_t entries[kSessionCapacity]; } session_manager_t;
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "game_types.h"
|
||||
|
||||
bool state_presenter_write(const game_state_t *state, role_t viewer, char *output, size_t output_size, size_t *written);
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct { uint16_t shots; uint16_t hits; uint16_t misses; uint8_t ships_sunk; } match_statistics_t;
|
||||
typedef struct { uint16_t games; uint16_t wins; uint16_t losses; uint32_t shots; uint32_t hits; } cumulative_statistics_t;
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "app_interfaces.h"
|
||||
|
||||
typedef struct { transport_t transport; } transport_service_t;
|
||||
Reference in New Issue
Block a user