#ifndef MAZE32_MAZE_H #define MAZE32_MAZE_H #include #include #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