feat(game): implement authoritative movement and visibility core

This commit is contained in:
2026-09-04 11:29:20 +03:00
parent 5d780def9d
commit 2aaa1650ae
11 changed files with 1085 additions and 7 deletions
@@ -0,0 +1,146 @@
#ifndef MAZE32_GAME_H
#define MAZE32_GAME_H
#include "maze32_maze.h"
#include <stddef.h>
#include <stdint.h>
#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