Maze Runner Program
++ Maze Runner Files ++ Makefile for Maze Runner
This commit is contained in:
parent
42fc64e613
commit
bf83664da4
6 changed files with 324 additions and 0 deletions
162
MazeRunner/mazelib.c
Normal file
162
MazeRunner/mazelib.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// PAY NO MIND TO ANYTHING FROM HERE...
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include "mazelib.h"
|
||||
|
||||
#define NORTH 0
|
||||
#define EAST 1
|
||||
#define SOUTH 2
|
||||
#define WEST 3
|
||||
|
||||
static void carve(int, int);
|
||||
static void shuffle(int[4]);
|
||||
|
||||
static int maze_width;
|
||||
static int maze_height;
|
||||
static char *maze;
|
||||
static bool is_maze_being_initialized = false;
|
||||
// ... TO HERE
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// BEGIN: THINGS YOU SHOULD LOOK AT (mostly the comments) //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Returns the character in the maze at the given row and column. First checks
|
||||
// to ensure that the attempted access is valid and, if not, terminates the
|
||||
// program.
|
||||
char maze_get_char(int row, int col) {
|
||||
bool is_in_bounds = ((0 <= row && row < maze_height) &&
|
||||
(0 <= col && col < maze_width));
|
||||
if (!is_in_bounds) {
|
||||
printf("Illegal maze access at row %i and col %i\n", row, col);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return maze[(row * maze_width) + col];
|
||||
}
|
||||
|
||||
|
||||
// Sets the character at the given row and column to the replacement
|
||||
// character. Replacement of the start and end signifiers and walls (#'s)
|
||||
// will be prevented unless the maze is being initialized, in which case, it
|
||||
// is allowed.
|
||||
//
|
||||
// Since it calls maze_get_char first, this function will also cause program
|
||||
// termination if passed a row or column that is out of bounds
|
||||
void maze_set_char(int row, int col, char replacement) {
|
||||
char c = maze_get_char(row, col);
|
||||
if (!is_maze_being_initialized && (c == '#' || c == 'S' || c == 'E')) {
|
||||
return;
|
||||
}
|
||||
|
||||
maze[(row * maze_width) + col] = replacement;
|
||||
}
|
||||
|
||||
|
||||
void maze_display(void) {
|
||||
for(int row = 0; row < maze_height; row++) {
|
||||
for(int col = 0; col < maze_width; col++) {
|
||||
printf("%c", maze_get_char(row, col));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// BEGIN: STUFF YOU DON'T NEED TO LOOK AT OR UNDERSTAND FOR THE PROJECT //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// maze_init allocates the memory for the maze array based on width and height,
|
||||
// fills every square of the maze with walls, and then calls carve() to
|
||||
// remove walls in a way that creates valid maze paths
|
||||
void maze_init(int width, int height, int seed) {
|
||||
maze_width = width;
|
||||
maze_height = height;
|
||||
|
||||
maze = malloc(sizeof(*maze) * maze_width * maze_height);
|
||||
|
||||
// Fill maze completely with walls
|
||||
for(int i = 0; i < maze_width * maze_height; i++) {
|
||||
maze[i] = '#';
|
||||
}
|
||||
|
||||
is_maze_being_initialized = true;
|
||||
// Seed the random number generator, since carve() uses of random numbers
|
||||
srand(seed);
|
||||
// We always start carving the maze from row 1 column 1 to ensure
|
||||
// that we always have a valid start there and a valid end in the bottom
|
||||
// right hand corner
|
||||
carve(1, 1);
|
||||
|
||||
maze_set_char(1, 1, 'S');
|
||||
maze_set_char(maze_height-2, maze_width-2, 'E');
|
||||
is_maze_being_initialized = false;
|
||||
}
|
||||
|
||||
/*
|
||||
Starts at a given index and recursively carves toward every direction in a
|
||||
randomized order. Recursion ends at a particular location when the blocks in
|
||||
every possible direction have already been carved.
|
||||
*/
|
||||
static void carve(int row, int col) {
|
||||
maze_set_char(row, col, ' ');
|
||||
|
||||
int directions[4] = {NORTH, EAST, SOUTH, WEST};
|
||||
shuffle(directions);
|
||||
|
||||
for (int i=0; i < 4; i++) {
|
||||
// Find the appropriate offsets for the row and column to move in the
|
||||
// current direction
|
||||
|
||||
int row_offset = 0;
|
||||
int col_offset = 0;
|
||||
int current_direction = directions[i];
|
||||
// Only one offset will be changed and the other will remain zero
|
||||
if (current_direction == NORTH) {
|
||||
row_offset = -1;
|
||||
}
|
||||
else if (current_direction == SOUTH) {
|
||||
row_offset = +1;
|
||||
}
|
||||
else if (current_direction == WEST) {
|
||||
col_offset = -1;
|
||||
}
|
||||
else {
|
||||
col_offset = +1;
|
||||
}
|
||||
|
||||
// Find the row and col for the spot *two* squares forward in the current
|
||||
// direction
|
||||
int next_row = row + (2 * row_offset);
|
||||
int next_col = col + (2 * col_offset);
|
||||
|
||||
bool is_in_bounds = ((0 <= next_row && next_row < maze_height) &&
|
||||
(0 <= next_col && next_col < maze_width));
|
||||
|
||||
// If that spot is in bounds and hasn't already been carved out...
|
||||
if (is_in_bounds && maze_get_char(next_row, next_col) == '#') {
|
||||
// carve out the wall between the current spot from and the next spot...
|
||||
maze_set_char(row + row_offset, col + col_offset, ' ');
|
||||
// and then continue carving from the new spot
|
||||
carve(next_row, next_col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void shuffle(int directions[4]) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
// Random number between 0 and 3
|
||||
int random_index = rand() % 4;
|
||||
// Swap the thing at the random index and the current index (i)
|
||||
int temp = directions[random_index];
|
||||
directions[random_index] = directions[i];
|
||||
directions[i] = temp;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue