239 lines
7.7 KiB
C
239 lines
7.7 KiB
C
#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_KEY_COUNT 2U
|
|
#define MAZE32_GAME_NO_KEY UINT8_MAX
|
|
#define MAZE32_GAME_VISION_MOVES 10U
|
|
#define MAZE32_GAME_DRAW_WINDOW_MS 200U
|
|
#define MAZE32_GAME_MAX_ARTIFACTS (2U * MAZE32_MAZE_MAX_ARTIFACT_PAIRS)
|
|
#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 12U
|
|
#define MAZE32_GAME_VIEW_OBJECTS_PER_CHUNK 6U
|
|
#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_FINISH_PENDING,
|
|
MAZE32_GAME_PHASE_FINISHED,
|
|
} 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_COMMAND_MOVE = 0,
|
|
MAZE32_GAME_COMMAND_DROP_KEY,
|
|
} maze32_game_command_type_t;
|
|
|
|
typedef enum {
|
|
MAZE32_GAME_FINAL_NONE = 0,
|
|
MAZE32_GAME_FINAL_PLAYER_ONE,
|
|
MAZE32_GAME_FINAL_PLAYER_TWO,
|
|
MAZE32_GAME_FINAL_DRAW,
|
|
} maze32_game_final_result_t;
|
|
|
|
typedef enum {
|
|
MAZE32_GAME_COMPASS_NONE = 0,
|
|
MAZE32_GAME_COMPASS_NORTH,
|
|
MAZE32_GAME_COMPASS_NORTH_EAST,
|
|
MAZE32_GAME_COMPASS_EAST,
|
|
MAZE32_GAME_COMPASS_SOUTH_EAST,
|
|
MAZE32_GAME_COMPASS_SOUTH,
|
|
MAZE32_GAME_COMPASS_SOUTH_WEST,
|
|
MAZE32_GAME_COMPASS_WEST,
|
|
MAZE32_GAME_COMPASS_NORTH_WEST,
|
|
} maze32_game_compass_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_NO_KEY,
|
|
MAZE32_GAME_RESULT_PLAYER_EXITED,
|
|
MAZE32_GAME_RESULT_MATCH_FINISHED,
|
|
} 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 carried_key;
|
|
uint8_t vision_moves_remaining;
|
|
maze32_game_compass_direction_t compass_hint;
|
|
uint8_t has_moved;
|
|
uint8_t exited;
|
|
} maze32_game_player_t;
|
|
|
|
typedef enum {
|
|
MAZE32_GAME_KEY_GROUND = 0,
|
|
MAZE32_GAME_KEY_CARRIED,
|
|
} maze32_game_key_location_t;
|
|
|
|
typedef struct {
|
|
maze32_game_key_location_t location;
|
|
maze32_cell_t ground_position;
|
|
uint8_t carrier;
|
|
} maze32_game_key_t;
|
|
|
|
typedef struct {
|
|
uint8_t open;
|
|
} maze32_game_exit_t;
|
|
|
|
typedef struct {
|
|
uint32_t command_sequence;
|
|
maze32_game_command_type_t type;
|
|
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;
|
|
uint8_t moved;
|
|
uint8_t dropped_key;
|
|
uint8_t picked_key;
|
|
uint8_t returned_keys;
|
|
uint8_t activated_artifact;
|
|
uint8_t opened_exit;
|
|
uint8_t outward_exit;
|
|
uint8_t finished;
|
|
uint8_t key;
|
|
uint8_t artifact;
|
|
maze32_game_compass_direction_t compass_hint;
|
|
maze32_game_final_result_t final_result;
|
|
} 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_key_t keys[MAZE32_GAME_KEY_COUNT];
|
|
maze32_game_exit_t exits[MAZE32_GAME_PLAYER_COUNT];
|
|
uint8_t consumed_artifacts[MAZE32_GAME_MAX_ARTIFACTS];
|
|
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_final_result_t final_result;
|
|
uint8_t first_exited_player;
|
|
uint8_t has_exit_time[MAZE32_GAME_PLAYER_COUNT];
|
|
uint64_t exit_times_ms[MAZE32_GAME_PLAYER_COUNT];
|
|
} 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;
|
|
maze32_game_final_result_t final_result;
|
|
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 self_carried_key;
|
|
uint8_t self_vision_moves_remaining;
|
|
maze32_game_compass_direction_t self_compass_hint;
|
|
uint8_t self_exit_open;
|
|
uint8_t self_exited;
|
|
uint8_t opponent_carried_key;
|
|
uint8_t observer_carried_keys[MAZE32_GAME_PLAYER_COUNT];
|
|
uint8_t observer_vision_moves_remaining[MAZE32_GAME_PLAYER_COUNT];
|
|
maze32_game_compass_direction_t observer_compass_hints[MAZE32_GAME_PLAYER_COUNT];
|
|
uint8_t observer_exited[MAZE32_GAME_PLAYER_COUNT];
|
|
uint8_t observer_exit_open[MAZE32_GAME_PLAYER_COUNT];
|
|
uint8_t observer_has_exit_time[MAZE32_GAME_PLAYER_COUNT];
|
|
uint64_t observer_exit_times_ms[MAZE32_GAME_PLAYER_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_result_t maze32_game_enqueue_drop_key(maze32_game_t* game, maze32_game_role_t role,
|
|
uint64_t submitted_ms,
|
|
uint32_t* command_sequence);
|
|
maze32_game_command_result_t maze32_game_process_next(maze32_game_t* game);
|
|
int maze32_game_advance_time(maze32_game_t* game, uint64_t now_ms);
|
|
uint8_t maze32_game_player_view_radius(const maze32_game_t* game, uint8_t player_index);
|
|
maze32_game_result_t maze32_game_project_view(const maze32_game_t* game, maze32_game_role_t role,
|
|
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
|