Neither look right to me. Using the 2:3 rules, you should end up with a lot of familiar shapes:
...and some others I can't be arsed to draw in ASCII.Code:**
**
**
* *
**
***
*
*
*
*** ***
*
*
*
Printable View
Neither look right to me. Using the 2:3 rules, you should end up with a lot of familiar shapes:
...and some others I can't be arsed to draw in ASCII.Code:**
**
**
* *
**
***
*
*
*
*** ***
*
*
*
well it doesnt necessarily come up with those patterns, depending on the rules, and given coordinates they differ.
here is what i came up with to make sure its not out of boundaries, but it still does not work properly...any suggestions?
Code:/***************************
Made by: Joshua R
Date Created:
Date Finished:
Lesson 18, LAB EXERCISE LIFE
***************************/
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
//array max needs to be one more
//row and column 0 won't be used
const int MAX = 20 + 1;
void fill (char [ MAX ][ MAX ]);
void getBacteria (char [ MAX ][ MAX ], int &);
void oneGeneration (char [ MAX ][ MAX ], int &);
bool alive (const char [ MAX ][ MAX ], int &, int &);
void neighbor (const char [ MAX ][ MAX ], int &, int &, int &);
void copy (char [ MAX ][ MAX ], char [ MAX ][ MAX ]);
void print (const char [ MAX ][ MAX ]);
main()
{
char table[ MAX ][ MAX ];
int total;
fill (table);
getBacteria (table, total);
print (table);
for (int generation = 4; generation < 5; generation++)
oneGeneration (table, total);
print (table);
cout<< endl << "Total Bacteria = " << total;
return 0;
}
/**** ARRAY MANIPULATION ****/
void fill (char table[ MAX ][ MAX ])
//fill the table with blank spaces
{
for (int row = 0; row < MAX; row++)
for (int col = 0; col < MAX; col++)
table[ row ][ col ] = ' ';
}
/**** ARRAY MANIPULATION ****/
void getBacteria (char table[ MAX ][ MAX ], int &total)
//get coordinates for bacteria from an external file
{
int num, x, y;
ifstream infile("Life100.txt");
//get total number of bacteria, the first integer
infile >> num;
total = num;
//get coordinates and fill location with "*"
while (!infile.eof())
{
infile >> x;
infile >> y;
table[ x ][ y ] = '*';
}
}
/**** ARRAY MANIPULATION ****/
void oneGeneration (char table[ MAX ][ MAX ], int &total)
//calculate each generation and assign new locations
{
char temp[ MAX ][ MAX ];
bool life;
fill (temp);
for (int row = 0; row < MAX; row++)
for (int col = 0; col < MAX; col++)
{
life = alive(table, row, col);
if (life)
temp[ row ][ col ] = '*';
}
copy (table, temp);
}
/**** BOOLEAN EVALUATION ****/
bool alive (const char table[ MAX ][ MAX ], int &x, int &y)
//calculate if the cell will live
{
int living = 0;
//get number of neighbors
neighbor (table, x, y, living);
//determine if current cell will live
if (table[ x ][ y ] == '*')
{
if ((living == 2) || (living == 3))
return true;
else
return false;
}
else
{
if (living == 3)
return true;
else
return false;
}
}
/****** INTEGER COUNT ******/
void neighbor (const char table[ MAX ][ MAX ], int &x, int &y, int &a)
//count number of surrounding neighbors
{
if ((x - 1) >= 0))
for (int row = y - 1; row <= y + 1; row++)
if ((row >= 0) && (row < MAX))
if (table[ row ][ x - 1 ] == '*')
a += 1;
if ((x + 1) < MAX)
for (int row = y - 1; row <= y + 1; row++)
if ((row >= 0) && (row < MAX))
if (table[ MAX ][ x + 1 ] == '*')
a += 1;
if ((y - 1) >= 0)
if (table[ y - 1 ][ x ] == '*')
a += 1;
if ((y + 1) < MAX)
if (table[ y + 1 ][ x ] == '*')
a += 1;
}
/******* COPY ARRAY ********/
void copy (char table[ MAX ][ MAX ], char temp[ MAX ][ MAX ])
//copy new "temp" table to old "table"
{
for (int row = 0; row < MAX; row++)
for (int col = 0; col < MAX; col++)
table[ row ][ col ] = temp[ row ][ col ];
}
/******* PRINT ARRAY *******/
void print (const char table[ MAX ][ MAX ])
//print full table with reference numbers
{
int horizontal = 1;
cout<< setw(10);
//prints horizontal reference numbers, x-axis
for (int ref = 1; ref < MAX; ref++)
{
cout<< horizontal;
horizontal++;
if (horizontal == 10) horizontal = 0;
}
cout<< endl << endl;
//prints verticle reference numbers, y-axis
for (int row = 1; row < MAX; row++)
{
cout<< setw(5) << row << setw(5);
for (int col = 1; col < MAX; col++)
cout<< table[ row ][ col ];
cout<< endl;
}
}
i'm piecing through this. One random style suggestion, is that you should really use 0-indexed lists. If you don't stick with the idiom, it gets confusing, as you always have to keep track of if code is using 1 or 0 based indexes.
Why not have the getBacteria function return the amount of cells, instead of using the reference?
because the assignment says to initialize a max array of 20 by 20, i used 21 so that i didnt have to use row and column 0.
but the file contains coordinates, none are 0.Quote:
Originally Posted by AH_Tze
does anyone have any suggestions??? i know there is something wrong with my code i just cant pinpoint it.
Not seeing it immediately. The alive() and neighbor() functions look error-prone.
If you want to find the error, I'd probably write a seperate driver program so you can test those two individually. You could write a test driver which has each function on a small array, with none of the other program logic obscuring things, and make it easy to watch as it steps through so you can spot the trouble spot.
Easiest way to spot the error is to render one frame and wait for a key. Then render another and so on. This way you can tell exactly what is going in inside of your code. I would say it is your alive and neighbor functions as well.
You must remember that just because you might 'get away' with overstepping your array bounds, does not mean it won't adversely affect your data, code, etc. You will frag the heap and/or stack depending on how you are allocating the array. This will result in perfectly good code executing incorrectly due to messed up memory.
So if you are getting weird stuff then that is probably what is happening.
To stop the overrun, just clamp on x and y.
This picks up all 8 neighbors and will wrap the effect at the boundaries of the array.Code:int x1=x-1
int y1=y-1
int x2=x+1
int y2=y+1
if (x1<0) x1=maxX;
if (y1<0) y1=maxY;
if (x2>maxX) x2=0;
if (y2>maxY) y2=0;
char n0,n1,n2,n3,n4,n5,n6,n7;
n0=n1=n2=n3=n4=n5=n6=n7=0;
n0=array[y1][x1];
n1=array[y1][x];
n2=array[y1][x2];
n3=array[y][x1];
n4=array[y][x2];
n5=array[y2][x1];
n6=array[y2][x];
n7=array[y2][x2];
...
But you would want something like that to count the number of alive and dead instead of retrieving the value. What I showed is more useful for filtering images. But it should get you on the right track.
Given any one location this is what that code will give:
Where ** is the current location you are checking.Code:n0,n1,n2
n3,**,n4
n5,n6,n7
if x1 or y1 is less than 0 it should yield 0 not max.Quote:
Code:if (x1<0) x1=maxX;
if (y1<0) y1=maxY;
if (x2>maxX) x2=0;
if (y2>maxY) y2=0;
this is the code i used, it works inside but not on the edges so for that im having dificulties.
Code:/**** BOOLEAN EVALUATION ****/
bool life (const char table[ MAX ][ MAX ], int &x, int &y)
//count number of surrounding neighbors
{
int x1=x-1; int y1=y-1;
int x2=x+1; int y2=y+1;
int a = 0;
if (x1<0) x1=0;
if (y1<0) y1=0;
if (x2>MAX) x2=MAX;
if (y2>MAX) y2=MAX;
char n0,n1,n2,n3,n4,n5,n6,n7;
n0=n1=n2=n3=n4=n5=n6=n7=0;
n0=table[y1][x1]; n1=table[y1][x]; n2=table[y1][x2];
n3=table[y][x1]; n4=table[y][x2]; n5=table[y2][x1];
n6=table[y2][x]; n7=table[y2][x2];
if (n0 == '*') a++; if (n1 == '*') a++; if (n2 == '*') a++;
if (n3 == '*') a++; if (n4 == '*') a++; if (n5 == '*') a++;
if (n6 == '*') a++; if (n7 == '*') a++;
if (table[ x ][ y ] == ' ')
{
if (a == 3)
return true;
else
return false;
}
if (table[ x ][ y ] == '*')
{
if ((a == 3) || (a == 2))
return true;
else
return false;
}
}
does anyone have any other ideas for setting boundaries? i dont need the code, just an idea
You can use modulus arithmetic and set it up to have no boundaries, that is, the sides would be connected. I have an example from my game of life implementation if you need to see it.
i am curious, could you just give me an example of how the modulus operator could be used?
Highly general example:Quote:
Originally Posted by JoshR
...will wrap i so that it is constantly within 20.Code:#define MAX 20
int main (void)
{
int i = 0;
while (1)
i++ %= MAX;
}
But you don't want to do that in the game of life (unless you want to implement a conceptual torus) - you should just ignore out of bounds values.
well i clamped down as hard as i could on the x and y values and made sure that they were only used if in parameters as follows below, but it still wont work, im lost...
Code:/**** BOOLEAN EVALUATION ****/
bool life (const char table[ MAX ][ MAX ], int &x, int &y)
//count number of surrounding neighbors
{
int x1=x-1; int y1=y-1;
int x2=x+1; int y2=y+1;
int a = 0;
char n0,n1,n2,n3,n4,n5,n6,n7;
n0=n1=n2=n3=n4=n5=n6=n7=0;
if ((y1 > 0) && (x1 > 0))
n0=table[y1][x1];
if (y1 > 0)
n1=table[y1][x];
if ((y1 > 0) && (x2 < MAX))
n2=table[y1][x2];
if (x1 > 0)
n3=table[y][x1];
if (x2 < MAX)
n4=table[y][x2];
if ((x1 > 0) && (y2 < MAX))
n5=table[y2][x1];
if (y2 < MAX)
n6=table[y2][x];
if ((y2 < MAX) && (x2 < MAX))
n7=table[y2][x2];
if (n0 == '*') a++; if (n1 == '*') a++; if (n2 == '*') a++;
if (n3 == '*') a++; if (n4 == '*') a++; if (n5 == '*') a++;
if (n6 == '*') a++; if (n7 == '*') a++;
if (table[ x ][ y ] == ' ')
{
if (a == 3)
return true;
else
return false;
}
if (table[ x ][ y ] == '*')
{
if ((a == 3) || (a == 2))
return true;
else
return false;
}
}