125 lines
3.7 KiB
C
125 lines
3.7 KiB
C
#ifndef MAZE32_MAZE_H
|
|
#define MAZE32_MAZE_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define MAZE32_MAZE_MAX_WIDTH 32U
|
|
#define MAZE32_MAZE_MAX_HEIGHT 32U
|
|
#define MAZE32_MAZE_MAX_CELLS (MAZE32_MAZE_MAX_WIDTH * MAZE32_MAZE_MAX_HEIGHT)
|
|
#define MAZE32_MAZE_DEFAULT_WIDTH 32U
|
|
#define MAZE32_MAZE_DEFAULT_HEIGHT 32U
|
|
#define MAZE32_MAZE_MAX_LANDMARK_PAIRS 16U
|
|
#define MAZE32_MAZE_MAX_ARTIFACT_PAIRS 16U
|
|
#define MAZE32_MAZE_RAM_BUDGET_BYTES (64U * 1024U)
|
|
#define MAZE32_MAZE_RUNTIME_BUDGET_MS 250U
|
|
|
|
typedef enum {
|
|
MAZE32_PASSAGE_NORTH = 1U << 0U,
|
|
MAZE32_PASSAGE_EAST = 1U << 1U,
|
|
MAZE32_PASSAGE_SOUTH = 1U << 2U,
|
|
MAZE32_PASSAGE_WEST = 1U << 3U,
|
|
} maze32_passage_t;
|
|
|
|
typedef struct {
|
|
uint16_t x;
|
|
uint16_t y;
|
|
} maze32_cell_t;
|
|
|
|
typedef struct {
|
|
uint16_t width;
|
|
uint16_t height;
|
|
uint8_t initial_view_radius;
|
|
uint8_t cross_half_pairs;
|
|
uint16_t extra_cycle_pairs;
|
|
uint16_t minimum_exit_separation;
|
|
uint8_t landmark_pairs;
|
|
uint8_t artifact_pairs;
|
|
uint8_t maximum_attempts;
|
|
} maze32_maze_config_t;
|
|
|
|
typedef struct {
|
|
maze32_cell_t cells[2];
|
|
uint8_t kind;
|
|
} maze32_landmark_pair_t;
|
|
|
|
typedef struct {
|
|
maze32_maze_config_t config;
|
|
uint32_t requested_seed;
|
|
uint32_t generation_seed;
|
|
uint8_t generation_attempts;
|
|
uint8_t passages[MAZE32_MAZE_MAX_CELLS];
|
|
maze32_cell_t starts[2];
|
|
maze32_cell_t keys[2];
|
|
maze32_cell_t exits[2];
|
|
maze32_cell_t compasses[2];
|
|
maze32_landmark_pair_t landmarks[MAZE32_MAZE_MAX_LANDMARK_PAIRS];
|
|
maze32_cell_t artifacts[MAZE32_MAZE_MAX_ARTIFACT_PAIRS][2];
|
|
} maze32_maze_t;
|
|
|
|
typedef struct {
|
|
uint8_t visited[(MAZE32_MAZE_MAX_CELLS + 7U) / 8U];
|
|
uint16_t traversal[MAZE32_MAZE_MAX_CELLS];
|
|
uint16_t distances[MAZE32_MAZE_MAX_CELLS];
|
|
} maze32_maze_workspace_t;
|
|
|
|
typedef struct {
|
|
uint16_t reachable_cells;
|
|
uint16_t passage_edges;
|
|
uint16_t cycle_count;
|
|
uint16_t dead_end_count;
|
|
uint16_t branching_cells;
|
|
uint16_t cross_half_connections;
|
|
uint16_t start_to_key[2];
|
|
uint16_t key_to_exit[2];
|
|
uint16_t start_to_exit[2];
|
|
uint16_t start_to_compass[2];
|
|
uint32_t landmark_distance_total[2];
|
|
uint32_t artifact_distance_total[2];
|
|
} maze32_maze_metrics_t;
|
|
|
|
typedef enum {
|
|
MAZE32_MAZE_OK = 0,
|
|
MAZE32_MAZE_INVALID_ARGUMENT,
|
|
MAZE32_MAZE_INVALID_CONFIG,
|
|
MAZE32_MAZE_UNREACHABLE,
|
|
MAZE32_MAZE_ASYMMETRIC,
|
|
MAZE32_MAZE_INSUFFICIENT_CYCLES,
|
|
MAZE32_MAZE_INSUFFICIENT_CROSSINGS,
|
|
MAZE32_MAZE_PLACEMENT_COLLISION,
|
|
MAZE32_MAZE_UNFAIR_PLACEMENT,
|
|
MAZE32_MAZE_KEY_IN_INITIAL_VIEW,
|
|
MAZE32_MAZE_GENERATION_EXHAUSTED,
|
|
} maze32_maze_result_t;
|
|
|
|
typedef struct {
|
|
maze32_maze_result_t result;
|
|
maze32_maze_result_t last_validation_result;
|
|
uint8_t attempts;
|
|
maze32_maze_metrics_t metrics;
|
|
} maze32_maze_report_t;
|
|
|
|
maze32_maze_config_t maze32_maze_default_config(void);
|
|
maze32_maze_result_t maze32_maze_generate(maze32_maze_t* maze, maze32_maze_workspace_t* workspace,
|
|
const maze32_maze_config_t* config, uint32_t seed,
|
|
maze32_maze_report_t* report);
|
|
maze32_maze_result_t maze32_maze_validate(const maze32_maze_t* maze,
|
|
maze32_maze_workspace_t* workspace,
|
|
maze32_maze_metrics_t* metrics);
|
|
uint16_t maze32_maze_cell_index(const maze32_maze_t* maze, maze32_cell_t cell);
|
|
maze32_cell_t maze32_maze_rotate(const maze32_maze_t* maze, maze32_cell_t cell);
|
|
int maze32_maze_has_passage(const maze32_maze_t* maze, maze32_cell_t cell,
|
|
maze32_passage_t passage);
|
|
uint64_t maze32_maze_hash(const maze32_maze_t* maze);
|
|
const char* maze32_maze_result_name(maze32_maze_result_t result);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|