game of life help!

hi, i'm really stuck with game of life coding section... i have no idea where to start and what to do... please help me out
---------------------------------------------------------------------------------------------------------
Your task is to write a program that plays the game of life. This game is a computer simulation of the life and death events in a population of single-cell organisms. Each position in a two-dimensional grid (Petri dish) can support one cell. The program determines whether each position will be able to support life in the next generation.

The grid of cells is represented by a boolMatrix object. The starting grid is generation 0 and is read from a supplied input file. Most positions in the grid have 8 neighbors like the center square in a tic-tac-toe game. The four corner positions have only 3 neighbors each. The remaining positions around the edge of the grid have 5 neighbors each. The rules for the state of each position in the next generation of the grid are as follows:

----------------------------------------------------------------------------
If the cell is currently empty:
If the cell has exactly three living neighbors, it will come to life in the next generation.
If the cell has any other number of living neighbors, it will remain empty.
If the cell is currently living:
If the cell has one or zero living neighbors, it will die of loneliness in the next generation.
If the cell has four or more living neighbors, it will die of overcrowding in the next generation.
If the cell has two or three neighbors, it will remain living.
All births and deaths occur simultaneously. This point is critical to the correct result.
------------------------------------------------------------------------------

The data file supplies the data for generation 0. Each line of data gives a pair of coordinates (row# column#) for a living cell in the original grid. Assume that every number in the text file is between 0 and 19. All other grid positions are empty. Please name your file "life.txt".

After your program has created the two-dimensional array that represents generation 0, your program must allow life to proceed for the number of generations specified by the user. Start with five generations. Your program should then display a grid on the screen to show the final results. Use a star (*) to represent a live cell and a space to represent a dead cell. After the grid, display the following statistical information:

The number of living cells in the entire board.
The number of living cells in row 10.
The number of living cells in column 10.


data
0 0
0 5
0 9
0 19
1 6
1 14
1 16
2 4
2 7
2 11
2 14
2 15
2 16
2 18
3 2
3 5
3 9
3 10
3 17
3 19
4 0
4 3
4 5
4 9
5 2
5 3
5 5
5 15
5 16
5 17
6 5
6 6
6 10
6 11
6 13
6 14
6 17
6 18
7 6
7 8
7 14
7 16
8 1
8 5
8 8
8 10
8 17
9 3
9 4
9 6
9 7
10 0
10 9
10 19
11 1
11 2
11 3
11 5
11 7
11 8
11 14
11 17
11 19
12 4
12 5
12 6
12 8
13 0
13 1
13 7
13 10
13 11
13 14
13 15
13 16
13 17
13 18
14 2
14 11
14 13
14 15
14 17
14 19
15 11
15 13
15 18
16 1
16 2
16 5
16 8
16 17
17 5
17 6
18 6
18 16
18 18
19 0
19 3
19 4
19 7
--------------------------------------------------------------------------------
output

01234567890123456789
0
1 * *
2 * * *** *
3 * **** *
4 * * * **
5 * * ***** *
6 ** * * *** *
7 * *** * *
8 ****
9 * ******
10* * *
11 * * ** *
12** **** ***
13 * *** ** *
14 * * * ***
15 ** *** ** **
16 * * **
17
18
19
Total alive in row 10 = 3
Total alive in col 10 = 1
Total alive = 95
--------------------------------------------------------------------------------
i am not quit sure how does that rules replies within outputs as well as what to fix with this sample code

Last edited on
sample code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
//A very simple C++ implementation of John Conway's Game of Life.
//This implementation uses several nested for loops as well as two-dimensional
//arrays to create a grid for the cells in the simulation to interact.
//The array that is displayed to the user is 50 x 100, but actual size
//of the array is 52 x 102.  The reason for this is to make the 
//calculations easier for the cells on the outermost "frame" of the grid.

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

//Copies one array to another.
void copy(int array1[52][102], int array2[52][102])
{
	for (int j = 0; j < 52; j++)
	{
		for (int i = 0; i < 102; i++)
			array2[j][i] = array1[j][i];
	}
}

//The life function is the most important function in the program.
//It counts the number of cells surrounding the center cell, and 
//determines whether it lives, dies, or stays the same.
void life(int array[52][102], char choice)
{
	//Copies the main array to a temp array so changes can be entered into a grid
	//without effecting the other cells and the calculations being performed on them.
	int temp[52][102];
	copy(array, temp);
	for (int j = 1; j < 51; j++)
	{
		for (int i = 1; i < 101; i++)
		{
			if (choice == 'm')
			{
				//The Moore neighborhood checks all 8 cells surrounding the current cell in the array.
				int count = 0;
				count = array[j - 1][i] +
					array[j - 1][i - 1] +
					array[j][i - 1] +
					array[j + 1][i - 1] +
					array[j + 1][i] +
					array[j + 1][i + 1] +
					array[j][i + 1] +
					array[j - 1][i + 1];
				//The cell dies.
				if (count < 2 || count > 3)
					temp[j][i] = 0;
				//The cell stays the same.
				if (count == 2)
					temp[j][i] = array[j][i];
				//The cell either stays alive, or is "born".
				if (count == 3)
					temp[j][i] = 1;
			}

			else if (choice == 'v')
			{
				//The Von Neumann neighborhood checks only the 4 surrounding cells in the array,
				//(N, S, E, and W).
				int count = 0;
				count = array[j - 1][i] +
					array[j][i - 1] +
					array[j + 1][i] +
					array[j][i + 1];
				//The cell dies.  
				if (count < 2 || count > 3)
					temp[j][i] = 0;
				//The cell stays the same.
				if (count == 2)
					temp[j][i] = array[j][i];
				//The cell either stays alive, or is "born".
				if (count == 3)
					temp[j][i] = 1;
			}
		}
	}
	//Copies the completed temp array back to the main array.
	copy(temp, array);
}

//Checks to see if two arrays are exactly the same. 
//This is used to end the simulation early, if it 
//becomes stable before the 100th generation. This
//occurs fairly often in the Von Neumann neighborhood,
//but almost never in the Moore neighborhood.
bool compare(int array1[52][102], int array2[52][102])
{
	int count = 0;
	for (int j = 0; j < 52; j++)
	{
		for (int i = 0; i < 102; i++)
		{
			if (array1[j][i] == array2[j][i])
				count++;
		}
	}
	//Since the count gets incremented every time the cells are exactly the same,
	//an easy way to check if the two arrays are equal is to compare the count to 
	//the dimensions of the array multiplied together.
	if (count == 52 * 102)
		return true;
	else
		return false;
}

//This function prints the 50 x 100 part of the array, since that's the only
//portion of the array that we're really interested in. A live cell is marked
//by a '*', and a dead or vacant cell by a ' '.
void print(int array[52][102])
{
	for (int j = 1; j < 51; j++)
	{
		for (int i = 1; i < 101; i++)
		{
			if (array[j][i] == 1)
				cout << '*';
			else
				cout << ' ';
		}
		cout << endl;
	}
}

int main()
{
	int gen0[52][102];
	int todo[52][102];
	int backup[52][102];
	char neighborhood;
	char again;
	char cont;
	bool comparison;
	string decoration;

	//Instructions on how the program is used, along with the rules of the game.
	cout << endl << "This program is a C++ implementation of John Conway's Game of Life."
		<< endl << "With it, you can simulate how \"cells\" interact with each other." << endl
		<< endl << "There are two types of neighborhoods you can choose, the"
		<< endl << "Moore, and the Von Neumann.  The Moore neighborhood checks"
		<< endl << "all 8 surrounding cells, whereas the Von Neumann checks"
		<< endl << "only the 4 cardinal directions: (N, S, E, and W)." << endl
		<< endl << "The rules of the \"Game of Life\" are as follows:" << endl
		<< endl << "1. Any live cell with fewer than two live neighbors dies, as if caused by under-population."
		<< endl << "2. Any live cell with two or three live neighbors lives on to the next generation."
		<< endl << "3. Any live cell with more than three live neighbors dies, as if by overcrowding."
		<< endl << "4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction." << endl
		<< endl << "The initial configuration (Generation 0) of the board is determined randomly."
		<< endl << "Every hundred Generations you will get the option to end or continue the simulation."
		<< endl << "If a system becomes \"stable\" (meaning the system does not change from one"
		<< endl << "generation to the next), the simulation will end automatically." << endl << endl;
	//Loop to check if user wants to keep simulating.
	do
	{
		//Loop to check for proper inputs.
		do
		{
			cout << "Which neighborhood would you like to use (m or v): ";
			cin >> neighborhood;
		} while (neighborhood != 'm' && neighborhood != 'v');
		//Clears the screen so the program can start fresh.
		system("clear");
		int i = 0;
		//Loop that does the bulk of the simulation.
		do
		{
			//Generates the initial random state of the game board.
			srand(time(NULL));
			//The actual array is 102 x 52, but it's easier to just leave the surrounding part of
			//the array blank so it doesn't effect the calculations in the life function above.
			for (int j = 1; j < 51; j++)
			{
				for (int i = 1; i < 101; i++)
					gen0[j][i] = rand() % 2;
			}
			//Determines how big the decoration should be.
			if (i < 10)
				decoration = "#############";
			else if (i >= 10 && i < 100)
				decoration = "##############";
			else if (i >= 100 && i < 1000)
				decoration = "###############";
			else if (i >= 1000 && i < 10000)
				decoration = "################";
			else
				decoration = "#################";
			//Prints the generation.  If i == 0, the gen0 array is copied to the 
			//todo array, and is printed before any functions act upon it.
			cout << decoration << endl << "Generation " << i
				<< ":" << endl << decoration << endl << endl;
			//Initializes the arrays by copying the gen0 array to the todo array.
			if (i == 0)
				copy(gen0, todo);
			copy(todo, backup);
			print(todo);
			life(todo, neighborhood);
			i++;
			//Pauses the system for 1/10 of a second in order to give the screen
			//time to refresh.
			system("sleep .1");
			//Checks whether the generation is a multiple of 100 to ask 
			//the user if they want to continue the simulation. If they
			//wish to end, the program breaks out of the loop to ask if
			//the user wishes to run another simulation.
			if (i % 100 == 1 && i != 1)
			{
				cout << endl;
				//Loop to check for proper inputs.
				do
				{
					cout << "Would you like to continue this simulation? (y/n): ";
					cin >> cont;
				} while (cont != 'y' && cont != 'n');
				if (cont == 'n')
					break;
			}
			//Compares the current generation with a backup generation.
			//If they aren't the same (they usually aren't) the system
			//clears the screen and repeats the process until they are
			//the same or the user chooses to quit.
			comparison = compare(todo, backup);
			if (comparison == false)
				system("clear");
			if (comparison == true)
				cout << endl;
		} while (comparison == false);
		//Loop to check for proper inputs.
		do
		{
			cout << "Would you like to run another simulation? (y/n): ";
			cin >> again;
		} while (again != 'y' && again != 'n');
	} while (again == 'y');
	return 0;
}
Last edited on
Hi dragonk, as far as I see, Your tasks are:
1) implement a boolMatrix class
2) fit your functions working with the boolMatrix class
3) write a reading-in for the life.txt file

Hints
1: Encapsulate the bool [][] array into your boolMatrix class, write proper constructors, getter and setter methods. Overload the operator == for comparing issues.

3: Write a matching function to reading in your file into an boolMatrix object. Hint: Overload the << operator for istreams *edited(std::istream& operator>>(std::istream&, BoolMatrix&)). I suggest to you writing also an print-out function by overloading the << operator
(std::ostream& operator<<(std::ostream&, BoolMatrix&)).

Good luck and feel free to ask if you're getting stuck :-)
Last edited on
ok, ty for help! so i tried to make a class of boolMatrix class and i'm stuck with what do i need to put with cpp file of boolMatrix

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//this is what i got so far
#include "boolMatrix.h"

boolMatrix::boolMatrix()
{
    //what do i need?
}

void boolMatrix::print()
{
	cout << "row: " << row << "and" << "col: " << col;
}

void boolMatrix::get(int inRow, int inCol);
{
    row = inRow;
    col = inCol;
}

int boolMatrix::rowCount (int inRow){
for(i=0; i>inRow; i++){
//when computer found '*' +result value
if (bollMatrix[inRow][inCol]=='*'){
    result++
}
return result
}
}

int boolMatrix::colCount (int inCol){
for(i=0; i>inCol; i++){
//when computer found '*' +result value
return result
}
}        
        
int boolMatrix::totalCount (){
//return all the number that is true value in array
return result
}

int boolMatrix::neighborCount (int row, int col){
// row +-1 bool if '*' is there
// add up with same thing with col
//i am not even sure what to do with this neighbor function...
}
Last edited on
ok, so far i worked with the class boolMatrix so how can i plug data with this class? is this the write and what do i need to do next with setting those rules?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <cassert>
using namespace std;
class boolMatrix {
public:
    static const int NUM_ROWS = 20;
    static const int NUM_COLS = 20;
    boolMatrix();
    bool get(int row, int col) const;
    void set(int row, int col, bool value);
    int rowCount(int row) const;
    int colCount(int col) const;
    int totalCount() const;
    void print() const;
    int neighborCount(int row, int col) const;
private:
    bool array[NUM_ROWS][NUM_COLS];
};
bool boolMatrix::get(int row, int col) const
{
    assert(row >= 0 && row < NUM_ROWS);
    assert(col >= 0 && col < NUM_COLS);
    return array[row][col];
}
boolMatrix::boolMatrix()
{
    for (int row = 0; row < NUM_ROWS; row++){
        for (int col = 0; col < NUM_COLS; col++){
            array[row][col] = false;
        }
    }
}
void boolMatrix::set(int row, int col, bool value)
{
    assert(row >= 0 && row < NUM_ROWS );
    assert(col >= 0 && col < NUM_COLS );
    array[row][col] = value;
}
int boolMatrix::rowCount(int row) const
{
    assert(row >= 0 && row < NUM_ROWS);
    int rowtotal = 0;
    for (int col = 0; col < NUM_COLS; col++){
        if (array[row][col] == true){
            rowtotal++;
        }
    }
    return rowtotal;
}
int boolMatrix::colCount(int col) const
{
    assert(col >= 0 && col < NUM_COLS - 1);
    int coltotal = 0;
    for (int row = 0; row < NUM_ROWS; row++){
        if (array[row][col] == true){
            coltotal++;
        }
    }
    return coltotal;
}
int boolMatrix::totalCount() const
{
    int total = 0;
    for (int row = 0; row < NUM_ROWS; row++){
        for (int col = 0; col < NUM_COLS; col++){
            if (array[row][col] == true){
                total++;
            }
        }
    }
    return total;
}
void boolMatrix::print() const
{
    cout << "  ";
    for (int col = 0; col < NUM_COLS; col++)
    {
        cout << col % 10;
    }
    cout << endl;
    for (int row = 0; row < NUM_ROWS; row++)
    {
        cout << "  " << row % 100;
        for (int col = 0; col < NUM_COLS; col++){
            if ( array[row][col] == true ){
                cout << "*";
            } else if ( array[row][col] == false ){
                cout << " ";
            }
        }
        cout << endl;
    }
}
int boolMatrix::neighborCount(int row, int col) const
{
    int total = 0;
    int row_start = row - 1;
    if(row_start <= 0)
        row_start = 0;
    int row_end = row + 1;
    if(row_end <= 0)
        row_end = 0;
    int col_start = 0;
    if(col_start <= 0)
        col_start = 0;
    int col_end = col + 1;
    if(col_end <= 0)
        col_end = 0;
    for (int i = row_start; i <= row_end; i++){
        for (int j = col_start; j <= col_end; j++){
            if(i == row && j == col)
                continue;
            if (get(row, col) == true)
                total++;
            }
        }
    return total;
}
// so here we go plugging in data table from above section
#include <iostream>
using namespace std;
int main() {
    boolMatrix matrix1;
matrix1.set(0, 0, true);
matrix1.set(0, 5, true);
matrix1.set(0, 9, true);
matrix1.set(0, 19, true);
// and so on.. i'm wondering if there is some way to read from text file so i dont have to //copy and paste all these matrix1.set
}
Last edited on
I have made some annotations and modifications to your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//this is what i got so far
#include "BoolMatrix.h"
#include <iostream>
#include <fstream>

boolMatrix::boolMatrix( const int rows, const int columns)
: m_height(rows), m_width(colums)
{
    //what do i need?
    m_array = bool [rows][columns];
}

/* void BoolMatrix::print()
{
	cout << "row: " << row << "and" << "col: " << col;
}
*/
// Substitute this by overloading the << operator and you can use it like:
// std::cout << my_matrix;
std::ostream& operator<<( std::ostream & ostr, const BoolMatrix& matrix)
{
      for (int row =0; row < matrix.height(); ++row) {
          for (int col = 0; col < matrix.width(); ++col) {
               if (matrix.get( row, col) == false) {
                   ostr << ' ';
               } else { ostr << '*'; }
         }
         ostr << '\n';   // line break after row's end
    }
    return ostr;

// Here the >> operator overloading, so you can read in a Matrix object from your istream-file.
// like: std::cin >> my_matrix;
// This function must be coded in such manner so that it fits to your data.txt format.
// ! -Sorry, in my previous post i have used the wrong return type!
std::istream & operator>> (std::istream & istr, BoolMatrix & matrix)
{
    int row, col;
    while (istr >> row >> col) {  // while there is data to read
        matrix.set(row, col);
    }
    return istr;
}

bool BoolMatrix::get(const int inRow, const int inCol);
{
     return m_array[inRow][inCol];
}


int BoolMatrix::rowCount (const int inRow){
for(i=0; i>inRow; i++){
//when computer found 'true' +result value
if (m_array[inRow][inCol]== true){
    result++
}
return result
}
}

int BoolMatrix::colCount (const int inCol){
for(i=0; i>inCol; i++){
//when computer found 'true' +result value
return result
}
}        
        
int BoolMatrix::totalCount (){
//return all the number that is true value in array
// use colCount() or rowCount() doing this
return result
}

int BoolMatrix::neighborCount (int row, int col){
// row +-1 bool if '*' is there
// add up with same thing with col

//i am not even sure what to do with this neighbor function...
//  use: if (my_matrix.get( ++row, --col) == true) or similar, ++nighbor_count..
}


Open your data file to an input file stream via:
std::ifstream ifs("data.txt"); and then you can use your overloaded >> operator for reading in your matrix object: ifs >> my_matrix;

I suggest that your class names are beginning with an uppercase, so you couldn't get confused with var-names.
Last edited on
Oh, our posts have overlapped :-)
Your last draft looks good.
I suggest adding getters for returning width and height of the matrix.
Also it would be good style if colCount(), totalCount() and neighborCount() will be implemented as seperate functions and not as member functions of the matrix.
For data handling look at my previous post.
Topic archived. No new replies allowed.