#ifndef MAZE32_GAME_H #define MAZE32_GAME_H #include "maze32_maze.h" #include #include #ifdef __cplusplus extern "C" { #endif #define MAZE32_GAME_PLAYER_COUNT 2U #define MAZE32_GAME_COMMAND_CAPACITY 16U #define MAZE32_GAME_MAX_OBJECTS \ (6U + 2U * MAZE32_MAZE_MAX_LANDMARK_PAIRS + 2U * MAZE32_MAZE_MAX_ARTIFACT_PAIRS) #define MAZE32_GAME_VIEW_CELLS_PER_CHUNK 24U #define MAZE32_GAME_VIEW_OBJECTS_PER_CHUNK 10U #define MAZE32_GAME_VIEW_CHUNK_BYTES 512U #define MAZE32_GAME_RAM_BUDGET_BYTES (40U * 1024U) #define MAZE32_GAME_RUNTIME_BUDGET_MS 50U typedef enum { MAZE32_GAME_PHASE_COUNTDOWN = 0, MAZE32_GAME_PHASE_ACTIVE, } maze32_game_phase_t; typedef enum { MAZE32_GAME_ROLE_PLAYER_ONE = 0, MAZE32_GAME_ROLE_PLAYER_TWO, MAZE32_GAME_ROLE_OBSERVER, } maze32_game_role_t; typedef enum { MAZE32_GAME_DIRECTION_NORTH = 0, MAZE32_GAME_DIRECTION_EAST, MAZE32_GAME_DIRECTION_SOUTH, MAZE32_GAME_DIRECTION_WEST, } maze32_game_direction_t; typedef enum { MAZE32_GAME_RESULT_ACCEPTED = 0, MAZE32_GAME_RESULT_INVALID_ARGUMENT, MAZE32_GAME_RESULT_QUEUE_FULL, MAZE32_GAME_RESULT_QUEUE_EMPTY, MAZE32_GAME_RESULT_READ_ONLY, MAZE32_GAME_RESULT_PREMATURE, MAZE32_GAME_RESULT_RATE_LIMITED, MAZE32_GAME_RESULT_BLOCKED, MAZE32_GAME_RESULT_BUFFER_TOO_SMALL, } maze32_game_result_t; typedef struct { uint32_t movement_cooldown_ms; } maze32_game_config_t; typedef struct { maze32_cell_t position; uint64_t last_move_ms; uint32_t accepted_moves; uint8_t has_moved; } maze32_game_player_t; typedef struct { uint32_t command_sequence; maze32_game_role_t role; maze32_game_direction_t direction; uint64_t submitted_ms; } maze32_game_command_t; typedef struct { maze32_game_result_t result; uint32_t command_sequence; uint32_t state_sequence; uint32_t meeting_sequence; uint8_t meeting; } maze32_game_command_result_t; typedef struct { const maze32_maze_t* maze; maze32_game_config_t config; maze32_game_phase_t phase; maze32_game_player_t players[MAZE32_GAME_PLAYER_COUNT]; maze32_game_command_t commands[MAZE32_GAME_COMMAND_CAPACITY]; uint8_t command_head; uint8_t command_count; uint32_t next_command_sequence; uint32_t state_sequence; uint32_t meeting_sequence; } maze32_game_t; typedef enum { MAZE32_VIEW_OBJECT_KEY = 0, MAZE32_VIEW_OBJECT_EXIT, MAZE32_VIEW_OBJECT_COMPASS, MAZE32_VIEW_OBJECT_LANDMARK, MAZE32_VIEW_OBJECT_VISION_ARTIFACT, } maze32_view_object_kind_t; typedef struct { uint16_t cell_index; uint8_t passages; } maze32_view_cell_t; typedef struct { uint16_t cell_index; maze32_view_object_kind_t kind; uint8_t owner; uint8_t variant; } maze32_view_object_t; typedef struct { maze32_game_role_t role; maze32_game_phase_t phase; uint32_t state_sequence; uint32_t meeting_sequence; uint16_t self_cell_index; uint16_t opponent_cell_index; uint16_t observer_player_cell_indices[MAZE32_GAME_PLAYER_COUNT]; uint16_t cell_count; uint8_t object_count; uint8_t opponent_visible; maze32_view_cell_t cells[MAZE32_MAZE_MAX_CELLS]; maze32_view_object_t objects[MAZE32_GAME_MAX_OBJECTS]; } maze32_view_t; maze32_game_config_t maze32_game_default_config(void); maze32_game_result_t maze32_game_init(maze32_game_t* game, const maze32_maze_t* maze, const maze32_game_config_t* config); void maze32_game_set_phase(maze32_game_t* game, maze32_game_phase_t phase); maze32_game_result_t maze32_game_enqueue_move(maze32_game_t* game, maze32_game_role_t role, maze32_game_direction_t direction, uint64_t submitted_ms, uint32_t* command_sequence); maze32_game_command_result_t maze32_game_process_next(maze32_game_t* game); maze32_game_result_t maze32_game_project_view(const maze32_game_t* game, maze32_game_role_t role, uint8_t radius, maze32_view_t* view); size_t maze32_game_view_chunk_count(const maze32_view_t* view); maze32_game_result_t maze32_game_serialize_view_chunk(const maze32_view_t* view, size_t chunk_index, char* output, size_t output_size, size_t* written); const char* maze32_game_result_name(maze32_game_result_t result); #ifdef __cplusplus } #endif #endif