QuestionQuestion

Transcribed TextTranscribed Text

Overview: Now that we have gone through the trouble of discussing the “theory” of arrays, we might as well put them to good use in what I hope will be an interesting assignment. Implement the game of Life, which should give you the opportunity to work on a nontrivial program and have some fun at the same time. The game of Life was designed in the 1970s by the mathematician J.H. Conway. The game gained popularity after appearing in a Scientific American article, and took the computing world by storm. The game is a simulation that models the life cycle of bacteria, providing entertainment wrapped up in what some would call mathematical elegance. (For some history on the game, as well as the rise of computing in general, I highly recommend the book Hackers, by S. Levy.) The game itself is played on a two-dimensional grid. Each grid location is either empty or occupied by a single cell (X). A location’s neighbors are any of the cells in the surrounding eight adjacent locations. (At this point you should be thinking about 2-d arrays.) Rules of the Game: The simulation starts with an initial pattern of cells and computes successive generations according to the following rules: 1. A location that has one or fewer neighbors will be empty in the next generation. If a cell was in that location, it dies of loneliness. (The fate of many a computer scientist…) 2. A location with two neighbors remains stable. If there was a cell, there’s still a cell. If it was empty, it’s still empty. 3. A location with three neighbors will contain a cell in the next generation. If it currently has a cell, the cell lives on. If it’s empty, a new cell is born. 4. A location with four or more neighbors will be empty in the next generation due to overcrowding. 5. The births and deaths that take one generation to the next must all take place simultaneously. When computing a new generation, the births and deaths in that generation can not affect other births and deaths in that generation. Not adhering to this guideline will really mess up your simulation, so be careful. An easy way to get around this is to have 2 versions of the grid. One is for the current generation, and the other is for computing the next generation (based on the current generation) without side effects. When you are done computing the next generation you can either copy it into the current generation grid, or just switch a reference. (In the database community, this little hack is called shadow paging.) Boundary Conditions: One of the gray areas of the program is how to calculate neighbors for cells on the grid boundaries. To make things interesting, at startup your program will ask the user which of the following 2 modes they want to run the simulation in, and calculate accordingly: Classic mode: All locations off the grid are considered to be empty. Doughnut mode: The grid is wrapped around itself horizontally and vertically, resulting in a torus (doughnut) shape. In this mode, any reference off the right-hand-side is wrapped around to the left-most column of the same row and vice-versa. Any reference off the top wraps to the bottom in the same column. Corners are best illustrated with an example: n n n n n n n n In the above, the shaded square has 8 possible neighbors (depending if the cells are occupied), marked with an ‘n’. Mirror Mode: References off the grid are bounced back as though the wall were a mirror. This means the reflection of a cell could count as its own neighbor. For a corner cell, if it was occupied, its reflection would count as 3 neighbors…1 for the vertical reflection, l for the horizontal reflection, and 1 for the diagonal reflection. As an example of mirror mode: x x x x x x x The “x” stands for an occupied cell. If the shaded cell were empty, then it would have 4 neighbors. If it were occupied, it would have 5 neighbors, since the neighbor directly above the shaded square is a reflection of the shaded square itself. The Program: When the program starts, you should ask the user if they wish to provide a map file of the world in which the simulation will be carried out, or if they would like a random assignment. If they want a random assignment, prompt for the dimensions of the world. Then prompt for a decimal value (greater than 0 and less than or equal to 1) representing the initial population density of the world. Randomly generate the initial cell configuration using the dimension and density inputs. If the user wants to provide a map file, then prompt for the file path. The file should be a text file with the following configuration: 5 7 ---X--X -X--X-- -----XX X-X-X-- -----XX The first line is height of the grid (number of rows) and the second is the width of the grid (number of columns). The following lines represent rows of the grid. An X stands for an occupied cell. A dash (-) represents an empty cell. Once a generation is calculated you will output it to standard out as a text grid. (Again, a “-”represents an empty grid and a “X” represents an occupied grid.) Before each grid, you should output the generation number, starting with 0 for the initial configuration. It is EXTREMELY important that you follow this convention or there will be issues with the automated test scripts I use for grading. In order to make it easy for the user to see what is going on in the program, you should ask the user at the beginning of the program if they want a brief pause between generations (see the system(“pause”) function), if they want to have to press “Enter” to display the next generation, or if they want to output everything to a file in which case they should be prompted for a file name. To summarize, when the program is run it should: 1. Ask the user if they wish to start with a random configuration, or specify a flatfile configuration. Prompt appropriately depending on the response. 2. Ask the user what kind of boundary mode to run in. 3. Ask the user if they want a brief pause between generations, if they want to have to press the “enter” key, or if they want to output to a file. 4. Carry out the simulation 5. If the simulation is infinite, just keep running. But if the world becomes empty or stabilizes, the simulation should halt and ask the user to press “enter” to exit the program.

Solution PreviewSolution Preview

These solutions may offer step-by-step problem-solving explanations or good writing examples that include modern styles of formatting and construction of bibliographies out of text citations and references. Students may use these solutions for personal skill-building and practice. Unethical use is strictly forbidden.

#include "GameOfLife.h"


Game::Game(int row, int col) {
this->row = row;
this->col = col;
this->grid = new int*[row];
this->lastGrid = new int*[row];

for (int i=0; i<row; i++) {
       this->grid[i] = new int[col];
       this->lastGrid[i] = new int[col];
       memset(grid[i], false, col*sizeof(int));
       memset(lastGrid[i], false, col*sizeof(int));
    }

    this->pause = 0;
    this->fileOutput = 0;
    this->gen_number = 0;
}

void Game::setFlat(int f) {
this->flat = f;
}

void Game::set(int i, int j, int value) {
this->grid[i][j] = value;
}

void Game::initialize() {
float fraction = 0;
while (1) {
cout << "Enter an initial population density (decimal value within 0-1): " << endl;
cin >> fraction;
if (fraction >= 0 && fraction <= 1) {

int numPositions = fraction*(this->row*this->col);
int count = 0;

while (count < numPositions) {
int r = rand() % this->row;
int c = rand() % this->col;
if (this->grid[r][c] == 0) {
this->grid[r][c] = 1;
count++;
}
}

break;
} else {
cout << "Invalid configuration. It should be within 0 to 1." << endl;
}
}
}

void Game::userInputs () {
int mode = 0;
while (1) {
cout << "Please provide boundary mode." << endl;
cout << "0. Classic Mode" << endl;
cout << "1. Doughnut Mode" << endl;
cout << "2. Mirror Mode" << endl;
cout << "Enter your choice: ";
cin >> mode;
if (mode >= 0 && mode <= 2) {
break;
} else {
cout << "Wrong choice! Please provide 0, 1 or 2." << endl;
}
}
this->mode = mode;

char pause;
char fileOutput;
cout << "Do you want a brief pause between generations (y or n)? ";
cin >> pause;
if (pause == 'y' || pause == 'Y') {
this->pause = 1;
} else {
cout << "Do you want output to a file (y or n)? ";
cin >> fileOutput;
if (fileOutput == 'y' || fileOutput == 'Y') {
this->fileOutput = 1;
cout << "Please enter output file name: ";
cin >> this->fileOutputName;
} else {
this->fileOutput...

By purchasing this solution you'll be able to access the following files:
Solution.zip.

$45.00
for this solution

or FREE if you
register a new account!

PayPal, G Pay, ApplePay, Amazon Pay, and all major credit cards accepted.

Find A Tutor

View available Data Structures and Algorithms Tutors

Get College Homework Help.

Are you sure you don't want to upload any files?

Fast tutor response requires as much info as possible.

Decision:
Upload a file
Continue without uploading

SUBMIT YOUR HOMEWORK
We couldn't find that subject.
Please select the best match from the list below.

We'll send you an email right away. If it's not in your inbox, check your spam folder.

  • 1
  • 2
  • 3
Live Chats