Town.cpp

/*

Programmer: Jennifer Leopold

Date: November 10, 2016

File: town.cpp

Purpose: This file contains the definitions of the functions

for the Town class.

*/

#include "town.h"

using namespace std;

Town::Town(const short gridSize)

{

// Make sure the grid size is reasonable

if ((gridSize >= MIN_SIZE) && (gridSize <= MAX_SIZE))

m_size = gridSize;

else m_size = MAX_SIZE;

// Initialize the grid entries to be 'empty'

clearGrid();

// Populate the grid with walls and exits

build();

}

char Town::getLocation(const Point p) const

{

char symbol;

// Double-check that point p is within boundaries of grid

// before accessing symbol at that position

if (inRange(p))

symbol = m_grid[p.getX()][p.getY()];

else symbol = ERROR_DISPLAY;

return(symbol);

}

bool Town::setLocation(const Point p, const char symbol)

{

bool success = true;

// Double-check that point p is within boundaries of grid

// before setting symbol at that position

if (inRange(p))

m_grid[p.getX()][p.getY()] = symbol;

else success = false;

return(success);

}

ostream& operator <<(ostream& outs, const Town& town)

{

for (int i = 0; i < town.m_size; ++i)

{

for (int j = 0; j < town.m_size; ++j)

outs << town.m_grid[i][j];

outs << endl;

}

return outs;

}

void Town::clearGrid()

{

for (int i = 0; i < m_size; ++i)

for (int j = 0; j < m_size; ++j)

m_grid[i][j] = EMPTY_DISPLAY;

return;

}

void Town::vacateLocation(const Point &p)

{

// Double-check that point p is within boundaries of grid

// before setting symbol at that position

if (inRange(p))

m_grid[p.getX()][p.getY()] = EMPTY_DISPLAY;

return;

}

void Town::build()

{

int midPoint = m_size/2;

// Put a WALL_DISPLAY symbol around the "boundaries"

// of the grid

for (int i = 0; i < m_size; i++)

for (int j = 0; j < m_size; j++)

if ((i == 0) || (j == 0) ||

(i == m_size - 1) || (j == m_size - 1))

m_grid[i][j] = WALL_DISPLAY;

// Put 4 EXIT_DISPLAY symbols in the grid, one in

// the middle of each "boundary wall" of the grid

m_grid[0][midPoint] = EXIT_DISPLAY;

m_grid[midPoint][0] = EXIT_DISPLAY;

m_grid[midPoint][m_size - 1] = EXIT_DISPLAY;

m_grid[m_size - 1][midPoint] = EXIT_DISPLAY;

return;

}

bool Town::inRange(const Point &p) const

{

return((p.getX() >= 0) && (p.getX() < m_size) &&

(p.getY() >= 0) && (p.getY() < m_size));

}

void Town::checkForOverPopulatedTown() const

{

bool emptyFound = false;

int i, j;

// Determine if grid is completely full. If it is,

// terminate program because no one will be able to

// move without stepping on someone/something!

i = 0;

while ((i < m_size) && (! emptyFound))

{

j = 0;

while ((j < m_size) && (! emptyFound))

if (! positionOccupied(Point(i, j)))

emptyFound = true;

else j++;

i++;

}

if (! emptyFound)

{

cout << "\nGrid is completely filled -- "

<< "no one will be able to move.\n";

cout << "Execute with a larger grid!\n";

exit(1);

}

return;

}

Point Town::getRandomEmpty() const

{

bool emptyFound = false;

int x, y; // coords of point selected

// First, make sure the grid isn't completely full

checkForOverPopulatedTown();

// Keep looking until we randomly find an "empty" position

// in grid

while (! emptyFound)

{

// Generate random x, y coordinates for a position in

// grid

x = rand() % m_size;

y = rand() % m_size;

if (! positionOccupied(Point(x, y)))

emptyFound = true;

}

return(Point(x, y));

}