In: Computer Science
Main Program's grading:
Student's main program will be used to generate output files. These output files will be compared to the solution output files and also to output files generated through instructor code, i.e., C++ code that will call the appropriate members of the Board class with the appropriate command line arguments. Students are free to impliment their main program however they like but the output must be correct (according to the solution) and must match the output using student's Board class. Pseudocode for generating the output files from the instructor's end is shown below
#include "Cell.hpp"
#include "Board.hpp"
#include "Gary.hpp"
int main(int argc, char** argv){
unsigned int boardSize = (from command line arguments)
unsigned int numberSteps = (from command line arguments)
std::string outputFilename = (from optional command line argument)
Board B(boardSize);
if (an output filename is given){
B.setOutputFilename(outputFilename);
}
B.move_gary(numberSteps);
return 0;
}
and student code must be capable of generating the correct output in the correct location when calling these member functions of the Board class. Please note that the only "pseudo" above is the parsing of command line arguments and the if statement - the member functions and construction of variable B of type Board is valid C++ syntax that is used during testing.
Board Class:
Note that there are no structural requirements for the Board class beyond the member functions called via the above psuedo-main program. These include:
(1) The Board class shall be constructed given an unsigned integer parameter that defines the number of rows and columns, i.e., 'N' in the N by N board. Note that N must be odd. If N is given as even, students shall display a message stating "Board dimension must be an odd number!! Got {N} and adding 1 to equal {N+1}" (note that parameters within { } must be printed as their values) and shall add 1 to N to satisfy the requirement that N must be odd. Note that this message must be printed only to the console, i.e., should not be printed to the output file. (2) Gary shall move around the board when the move_gary(steps) function is called. Each step shall be one step of Langton's ant as defined above, i.e., change Gary's orientation based on the Cell input, change the cell color, and move Gary forward one unit. The board class shall print the state of the board at every step. See the below example with a boardSize input of 5 for 10 steps:
[Gary Location] {2, 2} [Gary Orientation] up [Row 0] 0 0 0 0 0 [Row 1] 0 0 0 0 0 [Row 2] 0 0 0 0 0 [Row 3] 0 0 0 0 0 [Row 4] 0 0 0 0 0
[Gary Location] {2, 3} [Gary Orientation] right [Row 0] 0 0 0 0 0 [Row 1] 0 0 0 0 0 [Row 2] 0 0 1 0 0 [Row 3] 0 0 0 0 0 [Row 4] 0 0 0 0 0
[Gary Location] {3, 3} [Gary Orientation] down [Row 0] 0 0 0 0 0 [Row 1] 0 0 0 0 0 [Row 2] 0 0 1 1 0 [Row 3] 0 0 0 0 0 [Row 4] 0 0 0 0 0
[Gary Location] {3, 2} [Gary Orientation] left [Row 0] 0 0 0 0 0 [Row 1] 0 0 0 0 0 [Row 2] 0 0 1 1 0 [Row 3] 0 0 0 1 0 [Row 4] 0 0 0 0 0
[Gary Location] {2, 2} [Gary Orientation] up [Row 0] 0 0 0 0 0 [Row 1] 0 0 0 0 0 [Row 2] 0 0 1 1 0 [Row 3] 0 0 1 1 0 [Row 4] 0 0 0 0 0
[Gary Location] {2, 1} [Gary Orientation] left [Row 0] 0 0 0 0 0 [Row 1] 0 0 0 0 0 [Row 2] 0 0 0 1 0 [Row 3] 0 0 1 1 0 [Row 4] 0 0 0 0 0
[Gary Location] {1, 1} [Gary Orientation] up [Row 0] 0 0 0 0 0 [Row 1] 0 0 0 0 0 [Row 2] 0 1 0 1 0 [Row 3] 0 0 1 1 0 [Row 4] 0 0 0 0 0
[Gary Location] {1, 2} [Gary Orientation] right [Row 0] 0 0 0 0 0 [Row 1] 0 1 0 0 0 [Row 2] 0 1 0 1 0 [Row 3] 0 0 1 1 0 [Row 4] 0 0 0 0 0
[Gary Location] {2, 2} [Gary Orientation] down [Row 0] 0 0 0 0 0 [Row 1] 0 1 1 0 0 [Row 2] 0 1 0 1 0 [Row 3] 0 0 1 1 0 [Row 4] 0 0 0 0 0
[Gary Location] {2, 1} [Gary Orientation] left [Row 0] 0 0 0 0 0 [Row 1] 0 1 1 0 0 [Row 2] 0 1 1 1 0 [Row 3] 0 0 1 1 0 [Row 4] 0 0 0 0 0
[Gary Location] {3, 1} [Gary Orientation] down [Row 0] 0 0 0 0 0 [Row 1] 0 1 1 0 0 [Row 2] 0 0 1 1 0 [Row 3] 0 0 1 1 0 [Row 4] 0 0 0 0 0
the format is given by [Gary Location] {(row), (col)} (orientation) [Row 0] (col 0 color) (col 1 color) ... (col N-1 color) [Row 1] ... [Row (N-1)] ... (col N-1 color) where values within ( ) are to be filled in with program values. (col i color) shall be either "0" for "white" or "1" for "black". Note that students may want to call Cell::get_color_string( ) to print this value (or just Cell::get_color() as pointed out by a student in office hours!). This output will either be to standard output, i.e., std::cout, if a filename command line argument is not provided or will be printed to the filename given in the argument (students should use the ofstream object for file output. Note that C's fprintf will also be okay). The filename shall be set with the setOutputFilename member function.
Students are free to impliment the remaining functionality of the Board class as desired. The class should store a representation of the actual grid of cells which define the environment for Langon's ant, i.e., the Cell class created in Part A (Hint: I utilized a vector of vectors where each element of the outer vector stores a "row" or the grid represented by a vector of class Cell). The board class must also store a variable of type Gary that "walks" about the board. (More information on Gary is given below) At each step in the Gary::move_gary(Cell*) function the Board must pass a pointer to the Cell that Gary currently occupies so that Gary can alter his orientaiton, flip the color of that cell, i.e., call the change_color member function, and change his position, i.e., "walk" (find a tutorial for pointers to objects here).
The Gary class is subject to C++ unit testing and therefore has stricter requirements for composition. Each required member function will be denoted. (
1) Gary shall be constructed with a parameterized constructor accepting an unsigned integer input parameter representing the size of the board (denote here as BoardSize). Assume that BoardSize is odd! Gary shall initialize his position to be the middle cell of the board, e.g., if the BoardSize is given as 5 Gary would be initialized at index (2,2).
(2) Gary shall contain public member functions which return an unsigned integer type and accept no input named Gary::get_row() and Gary::get_col() which return Gary's row and column position on the board respectively.
(3) Gary shall contain a public member function which returns type void and accepts a Cell pointer called Gary::move(Cell*) which shall (a) alter Gary's orientation based on the Cell's color (b) change the Cell's color (c) move Gary one unit forward in the new orientation
(4) Gary shall contain a public member function which returns type orientation (defined as an enumeration enum orientation {up, right, down, left};) and accepts no input parameters called Gary::get_orientation()
Summary for implemented code -
(1) The Board class shall be constructed given an unsigned integer parameter that defines the number of rows and columns, i.e., 'N' in the N by N board. Note that N must be odd. If N is given as even, students shall display a message stating "Board dimension must be an odd number!! Got {N} and adding 1 to equal {N+1}" (note that parameters within { } must be printed as their values) and shall add 1 to N to satisfy the requirement that N must be odd. Note that this message must be printed only to the console, i.e., should not be printed to the output file.
(2) Gary shall move around the board when the move_gary(steps) function is called. Each step shall be one step of Langton's ant as defined above, i.e., change Gary's orientation based on the Cell input, change the cell color, and move Gary forward one unit. The board class shall print the state of the board at every step.
(3) Gary shall be constructed with a parameterized constructor accepting an unsigned integer input parameter representing the size of the board (denote here as BoardSize). Assume that BoardSize is odd! Gary shall initialize his position to be the middle cell of the board, e.g., if the BoardSize is given as 5 Gary would be initialized at index (2,2).
#include "Gary.hpp"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main(int argc, char** argv) {
if (argc == 3) {
unsigned int boardSize =
(int)argv[0];
unsigned int numberSteps =
(int)argv[1];
std::string outputFilename =
argv[2];
Board
B(boardSize);
if (an output filename is given)
{
B.setOutputFilename(outputFilename);
}
if (boardSize % 2 == 0)
{
printf("Board
dimension must be an odd number!! .\n");
boardSize =
boardSize + 1;
}
B.move_gary(numberSteps);
}
return 0;
}
Gary::Gary(Board* b, int x, int y)
{
board = b;
xCoordinates = x;
yCoordinates = y;
direction = 1;
}
int Gary::get_row()
{
return xCoordinates;
}
int Gary::get_col()
{
return yCoordinates;
}
bool Gary::isWall(int x, int y)
{
if (x < 0)
return true;
//if x coord exceeds row size
if (x > rowSize - 1)
return true;
if (y < 0)
return true;
//if y coord exceeds column size
if (y > colSize - 1)
return true;
return false;
}
//DIRECTIONS: 1 = UP, 2 = DOWN, 3 = LEFT, 4 = RIGHT
void Gary::moveGary(int x, int y)
{
if (board->get_color(x, y) == ' ')
{
if (direction == 1)
direction =
4;
else if (direction == 2)
direction =
3;
else if (direction == 3)
direction =
1;
else if (direction == 4)
direction =
2;
}
else
{
if (direction == 1)
direction =
3;
else if (direction == 2)
direction =
4;
else if (direction == 3)
direction =
2;
else if (direction == 4)
direction =
1;
}
board->changeColor(x, y);
if (direction == 1)
xCoordinates = x - 1;
if (direction == 2)
xCoordinates = x + 1;
if (direction == 3)
yCoordinates = y - 1;
if (direction == 4)
yCoordinates = y + 1;
//if the Garys current Coordinatess are out of
bounds
if (board->isWall(xCoordinates,
yCoordinates))
{
//put it back on the board and move
it down 1 change its direction to down
if (direction == 1)
{
xCoordinates +=
2;
direction =
2;
}
//place it back on board and
move it up 1 change direction to up
else if (direction == 2)
{
xCoordinates -=
2;
direction =
1;
}
//place it back on board and
move it right 1 change diretion to right
else if (direction == 3)
{
yCoordinates +=
2;
direction =
4;
}
//place it back on board and
move left 1 change direction to left
else if (direction == 4)
{
yCoordinates -=
2;
direction =
3;
}
}
}