254 lines
5 KiB
C
254 lines
5 KiB
C
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
// Including a header file lets your file refer to the functions *declared* in
|
|
// that header file. The functions are usually *defined* elsewhere though, in
|
|
// this case, mazelib.c
|
|
#include "mazelib.h"
|
|
|
|
#define NORTH 0
|
|
#define EAST 1
|
|
#define SOUTH 2
|
|
#define WEST 3
|
|
|
|
// function prototypes
|
|
void breadcrumb(int row, int column);
|
|
bool checkForwardBlocked(int row, int column, int heading);
|
|
bool checkLeftBlocked(int row, int column, int heading);
|
|
bool checkRightBlocked(int row, int column, int heading);
|
|
int turnLeft(int heading);
|
|
int turnRight(int heading);
|
|
|
|
void runner_solve(void) {
|
|
// set the runner in the maze
|
|
int row = 1;
|
|
int column = 2;
|
|
int heading = EAST;
|
|
|
|
// "indefinately move through the maze"
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
// check to see if the end of the maze is here
|
|
if (maze_get_char(row, column) == 'E')
|
|
{
|
|
return;
|
|
}
|
|
// set a breadcrumb through the maze
|
|
breadcrumb(row, column);
|
|
// check to see if the forward position is blocked
|
|
if (checkForwardBlocked(row, column, heading))
|
|
{
|
|
// check to see if the left position is blocked
|
|
if (checkLeftBlocked(row, column, heading))
|
|
{
|
|
// check to see if the right position is blocked
|
|
if (checkRightBlocked(row, column, heading))
|
|
{
|
|
// if it is, then turn left instead.
|
|
heading = turnLeft(heading);
|
|
}
|
|
else
|
|
{
|
|
// otherwise, turn right instead.
|
|
heading = turnRight(heading);
|
|
}
|
|
}
|
|
}
|
|
// keep track of the heading through the maze, "moving" the 'S'
|
|
if (heading == NORTH)
|
|
{
|
|
row = row + 1;
|
|
}
|
|
if (heading == EAST)
|
|
{
|
|
column = column + 1;
|
|
}
|
|
if (heading == SOUTH)
|
|
{
|
|
row = row - 1;
|
|
}
|
|
if (heading == WEST)
|
|
{
|
|
column = column - 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// function definitions, given logical breakdown of the problem.
|
|
int turnLeft(int heading)
|
|
{
|
|
// turns left given the current direction.
|
|
if (heading == NORTH)
|
|
{
|
|
heading = WEST;
|
|
}
|
|
if (heading == EAST)
|
|
{
|
|
heading = NORTH;
|
|
}
|
|
if (heading == SOUTH)
|
|
{
|
|
heading = EAST;
|
|
}
|
|
if (heading == WEST)
|
|
{
|
|
heading = SOUTH;
|
|
}
|
|
// returns the new heading.
|
|
return heading;
|
|
}
|
|
|
|
int turnRight(int heading)
|
|
{
|
|
// turns right given current direction
|
|
if (heading == NORTH)
|
|
{
|
|
heading = EAST;
|
|
}
|
|
if (heading == EAST)
|
|
{
|
|
heading = SOUTH;
|
|
}
|
|
if (heading == SOUTH)
|
|
{
|
|
heading = WEST;
|
|
}
|
|
if (heading == WEST)
|
|
{
|
|
heading = NORTH;
|
|
}
|
|
// returns the new direction
|
|
return heading;
|
|
}
|
|
|
|
void breadcrumb(int row, int column)
|
|
{
|
|
// leaves a "breadcrumb" as given by the spec
|
|
if(maze_get_char(row, column) == '.')
|
|
{
|
|
// set a 'o'
|
|
maze_set_char(row, column, 'o');
|
|
}
|
|
else if (maze_get_char(row, column) == 'o')
|
|
{
|
|
// set a 'O'
|
|
maze_set_char(row, column, 'O');
|
|
}
|
|
else if (maze_get_char(row, column) == 'O')
|
|
{
|
|
// set a '@'
|
|
maze_set_char(row, column, '@');
|
|
}
|
|
else
|
|
{
|
|
// set a '.'
|
|
maze_set_char(row, column, '.');
|
|
}
|
|
}
|
|
|
|
bool checkForwardBlocked(int row, int column, int heading)
|
|
{
|
|
// checks to see if the path is blocked from where the runner is in each
|
|
// direction.
|
|
if (heading == NORTH)
|
|
{
|
|
if (maze_get_char(row - 1, column) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == EAST)
|
|
{
|
|
if (maze_get_char(row, column + 1) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == SOUTH)
|
|
{
|
|
if (maze_get_char(row + 1, column) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == WEST)
|
|
{
|
|
if (maze_get_char(row, column - 1) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
// return false if there is no # within the given area.
|
|
return false;
|
|
}
|
|
|
|
bool checkLeftBlocked(int row, int column, int heading)
|
|
{
|
|
// checks to see if the path is blocked from where the runner is in each
|
|
// direction.
|
|
if (heading == NORTH)
|
|
{
|
|
if (maze_get_char(row, column - 1) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == EAST)
|
|
{
|
|
if (maze_get_char(row - 1, column) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == SOUTH)
|
|
{
|
|
if (maze_get_char(row, column + 1) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == WEST)
|
|
{
|
|
if (maze_get_char(row + 1, column) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
// return false if there is no # within the given area.
|
|
return false;
|
|
}
|
|
|
|
bool checkRightBlocked(int row, int column, int heading)
|
|
{
|
|
// checks to see if the path is blocked from where the runner is in each
|
|
// direction.
|
|
if (heading == NORTH)
|
|
{
|
|
if (maze_get_char(row, column + 1) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == EAST)
|
|
{
|
|
if (maze_get_char(row + 1, column + 1) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == SOUTH)
|
|
{
|
|
if (maze_get_char(row, column - 1) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (heading == WEST)
|
|
{
|
|
if (maze_get_char(row - 1, column) == '#')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
// return false if there is no # within the given area.
|
|
return false;
|
|
}
|