Conway's game of life algoritm is not working - c++

I'm trying to simulate conway's game of life. The algorithm I made is not working, but I can't figure out how.
If I have a situation like this:
|.........|
|....x....|
|....x....|
|....x....|
|.........|
a . is a dead cell, an x is an alive cell
It is expected that the vertical bar flips into a horizontal bar, but this doesn't happen.
Instead it only removes the bottom one, running it again again only removes the bottom so theres 1 left.
Clearly theres something wrong with the algorithm, but I can't figure out what.
I've been looking online but all problems other people have had, the solutions didn't work for me.
So what is the error in this algorithm?
This is my code:
void new_generation() {
// Create one new generation
// double for loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
// find the amount of living neighbours, stored in count
// dubbele for loop -> iterates every neighbour of the current cell
count = 0;
for (int y=0; y<2; y++) {
for (int x=0; x<2; x++){
if (i != 0 and j!= 0) { // the cell itself doesnt count
if (world[i+y][j+x]) count++;
}
}
}
if (world[i][j]) { // current cell is alive
if (count<2 or count>3) new_world[i][j] = false;
else new_world[i][j] = true;
}
else { // current cell is dead
if (count==3) new_world[i][j] = true;
else new_world[i][j] = false;
}
}
}
// copy every value from the newly generated world to the current
// double foor loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
world[i][j] = new_world[i][j];
}
}
worldHeight and worldWidth are ints denoting how big the world is.
world and new_world are 2-dimensional arrays containing booleans where true is a living cell and false is a dead cell

You count the neighbor cells wrong
Both x and y are runing from 0 to 2 not from -1 to 2. in
for (int y=0; y<2; y++) {//should be int y=-1; y<2; y++
for (int x=0; x<2; x++){//should be int x=-1; x<2; x++
if (i != 0 and j!= 0) { // shold be x!=0 or y!=0
if (world[i+y][j+x]) count++;
}
}
}
Also you have to check if world[i+y][j+x] is valid (coordinates are in teh 0,size range)
And the third problem is that when you want not to count in word[i][j] you check if (i!=0 and j!=0) not x!=0 or y!=0 i and j are the coordinates of the examined cell, x and y are the difference of the coordinates.

Related

Tetris shifting 2D array

I'm currently writing a tetris in C++ and I am at the last stage, I need to delete a row when it is full. Once a piece falls it is stored in a boolean array grid[20][10]. For example I check which row is full (or true), if it is I call a method deleteRow, where n is a number of row:
void Grid::deleteRow(int n)
{
for (j = 0; j < WIDTH; j++)
{
grid[n][j] = false;
}
}
Once the row is deleted I call a method moveRowDown:
void Grid::moveRowDown()
{
for (i = 0; i < HEIGHT; i++)
{
for (j = 0; j < WIDTH; j++)
{
grid[i+1][j]=grid[i][j];
}
}
}
So this method does not work, and all of the pieces disappear. I know I am missing the logic. Thanks for the help in advance!
They disappear because you copy 1st empty row to 2nd, then to 3rd and etc.
You need to rewrite your first loop in Grid::moveRowDown() to work from the bottom of a glass:
for (i = HEIGHT-2; i>=0; i--)

For loops are skipped, why?

I have an assignment in which i have to create a console program in c++ that draws Hexagons in a given style. The problem i am having is; my For loops are never entered and i can't figure out why. here's the snippet of code I'm having trouble with.
void display()
{
int counter=0;//var that keeps track of the layer that is being drawn
for(int i=0;i>=size;i++)//spaces before first layer of hexagon
{
cout<<" ";
}
for (int k=0; k>size;k++)//top layer of hexagon
{
cout<<"_";
}
cout<<endl;//ends the first layer
for (counter; counter>=size-1;counter++)//outer loop for the top half that controls the size
{
for( int j=0;j>(size-counter);j++)//adds spaces before the shape
{
cout<<" ";
}
cout<<"/";
for( int p=0; p>(size+(counter*2));p++)//loop for the hexagon fill
{
cout<<fill;
}
cout<<"\\"<<endl;
}
for(counter;counter==0;counter--); //loop for bottom half of the hexagon
{
for( int j=0;j>(size-counter);j++)//adds spaces before the shape
{
cout<<" ";
}
cout<<"\\";
for( int p=0; p>(size+(counter*2));p++)//loop for the hexagon fill
{
cout<<fill;
}
cout<<"/"<<endl;
}
cout<<"\\";
for(int r=0; r>=size;r++){cout<<"_";}
cout<<"/"<<endl;
}
the 'Size' and 'fill' are selceted earlier in the program during my main()
I'm probably missing something very simple but I've been struggling with this for a while. Any help would be greatly appricated!
Your loops use > and start at 0. It seems you want < instead. For example
for(int i=0;i<size;i++)//spaces before first layer of hexagon
{
cout<<" ";
}
I am not sure what is the content of your size variable but it looks like you have got your loop conditions wrong:
for(int i=0;i>=size;i++)
probably should be:
for(int i=0;i<size;i++)
The same goes for other loops.
Assuming your size is a postive number, it works as per your condition.
Change the > conditojs to < in your conditions.
In your conditions, invert the > to <
< means inferior, you want to do a
for i = 0; if i < size; i++
You do
for i = 0 ; if i > size ; i ++
if size is superior to i (0) the loop will never trigger
Aren't all of your < and > reversed? Because
(int k=0; k>size;k++)
makes no sense to me.
for loops in C++ are while loops, not until loops.
C++ has only while loops (with the meaning of as long as):
for (int i=0; i<10; ++i)
....
int i=0;
while (i<10) {
....
++i;
}

Positive rows in a matrix

I have to do an exercise for University that asks me to check ( for k times ) if a matrix has positive rows ( i mean a row with all positive elements ) , i think there's something wrong with the indices of for loops but i cannot find the mistakes.
i tried to debug with a cout statement apply to the counter an it gives me "101" , so it seems like compiler assign "1" to the positive rows and "0" to the negative
This is the code i wrote:
#include <iostream>
using namespace std;
const int N = 3;
bool positive(int a[N][N], int row[N], int x) {
bool condition = false;
for(int i = 0; i < N; i++) {
row[i] = a[x][i];
}
int j = 0;
while(j < N) {
if(row[j] >= 0) {
condition = true;
} else {
condition = false;
}
j++;
}
return condition;
}
bool function (int a[N][N], int z, int j, int k) {
int b[N];
int c[N];
int count = 0;
if(positive(a, b, z) && positive(a, c, j)) {
count++;
}
if(count == k) {
return true;
} else {
return false;
}
}
int main() {
int a[N][N] = {
{
2, 8, 6
}, {
-1, - 3, - 5
}, {
6, 10, 9
}
};
int k = 2;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
if(function (a, i, j, k)) {
cout << "OK";
} else {
cout << "NO";
}
}
}
return 0;
}
You should probably take another look at this problem and restart with a different solution. The objective is pretty easy but your code is surprisingly complex and some of it doesn't really make sense.
For example, if you had a matrix like this:
1 2 4 --> matrix A
-1 8 -6
3 9 2
You have N=3 rows and columns. The only thing you have to to based on what you said is take the matrix, cycle through the N rows, and for each row, check it's N columns to see if anything is < 0.
Doing this K times, as you put it, makes no sense. The matrix will be the same every time you compare it since you're not changing it, why would you do it more than once? I think you should reread the assignment brief there.
As for the logic of finding which rows are positive or negative, just do something simple like this.
//Create array so we have one marker for each row to hold results.
bool rowPositiveFlags[N] = { true, true, true };
//Cycle through each row.
for (int row = 0; row < N; ++row)
//Cycle through every column in the current row.
for (int col = 0; col < N; ++col)
//If the column is negative, set the result for this row to false and break
//the column for loop as we don't need to check any more columns for this row.
if (A[row][col] < 0) {
rowPositiveFlags[row] = false;
break;
}
You should always name things so that you can read your code like a book. Your i's, j's, and k's just make something simple confusing. As for the problem, just plan out your solution.
Solve the problem by hand on paper, write the steps in comments in your code, and then write code below the comments so what you do definitely makes sense and isn't overkill.
And this is a great site, but next time, post a smaller piece of code that shows your problem. People shouldn't ever give you a full solution here for homework so don't look for one. Just find the spot where your indices are broken and paste that set of 5 lines or whatever else is wrong. People appreciate that and you'll get faster, better answers for showing the effort :)

I cannot get code to separate and compare array data correctly

I've got an fstream input file that has [N] lines or items. I've written code to decide which items are triangles and which are rectangles and which are circles. I've got to isolate just the triangle items and then compare them to see if they are equal to +/- 0.1 the area of all the other triangle items. Then I have to cout the equal pairs of items as uppercase char letters.
Here's my code so far but it's not working correctly. It's outputting L&L, which is incorrect. It should say E&L because the two identical triangles in my array are on lines 5&12, Not 12&12. How do I fix this?
int ItmM = 0;
ItmN = 0;
int j = 0;
for (int i=0; i<M; i++)
{
if (btype[i] == Triangles)
{
TA[i] = (0.5 * (D[i] * E[i]));
for (int j=0; j<i; j++)
{
if (TA[i] - 0.1 < TA[j] && TA[j] < TA[i] + 0.1)
{
TA[j] = TA[i];
ItmM = i;
ItmN = j;
cout << "4. Triangular blocks that are the same size = "
<< (char)('A' + ItmM) << "&" << (char)('A' + ItmM)
<< endl;
}
}
}
}
I've edited the above code twice. It's still outputting L&L. Should be E&L, (5&12)
When you do TriangleAreaE = TrangleArea[j], and as j is always0, you are comparing every triangle with the first one. The 5th and 12th never get compared.
You should use a nested loop to compare every pair of triangles:
for (int i=0; i<M; i++)
{
if ( /*...*/ )
{
/*...*/
for (int j=0; j<i; j++)
{
// compare TriangleArea[i] with TriangleArea[j], if j is a triangle
}
}
}
You can fill in the detail, as this seems to be a homework problem.
And you should edit your existing posts instead of posting a new one.
The value of j never changes in the code you posted. You just compare the area of each triangle with the first one in the list. If I understand what you are trying to do correctly, you should be able to make it work with a nested for loop:
TriangleArea[0]= whatever
for(j=0; j<M; j++)
{
for(i=j+1;i<m;i++)
{
// rest of your code
In your code you never modify j, so you are always comparing with the first triangle (triangle A), so it's not really a suprise that it is equal to itself. What you need to do is loop over all already processed triangles and compare, so basically
for (int i=0; i<M; i++)
{
if (btype[i] == Triangles) //btype[i] declared earlier in larger code
{
TriangleArea[i] = (0.5 * (D[i] * E[i]));
for(int j = 0; j < i; ++j)
{
//Insert the comparison here
}
}
}
Of course your positioning of the cout will only print the last pair of equal sized pair, so judging from the text in your question, you might want to put the cout inside your loops.
(char)('A' + ItemNumberM) << "&" << (char)('A' + ItemNumberM)
This line prints the same item number twice. Is one of those supposed to be ItemNumberN?

For loop for reading strings from a file into a 3D array

I'm having a problem with one of my functions, I'm working on a simple tile map editor, and I'm trying to implement a 3D array to keep track of tiles (x,y, layer). Before this I had a 1D array where all the tiles were just listed sequencially:
bool Map::OnLoad(char* File) {
TileList.clear();
FILE* FileHandle = fopen(File, "r");
if(FileHandle == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList.push_back(tempTile);
}
fscanf(FileHandle, "\n");
}
fclose(FileHandle);
return true;
}
This basically read strings from the file which looked like:
2:1 1:0 3:2...
Where the first number states the tileID and the second one states the Tile passability. The above function works. My 3D arrays are also correctly constructed, I tested them with simple assignments and calling values out of it. The function that gives me problems is the following (please note that the number 2 i.e. OnLoad2() was added so I can keep the old variables and the function untouched until the prototype is working):
bool Map::OnLoad2(char* File) {
TileList2.clear();
FILE* FileHandle2 = fopen(File, "r");
if(FileHandle2 == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle2, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList2[X][Y][0] = tempTile;
}
fscanf(FileHandle2, "\n");
}
fclose(FileHandle2);
return true;
}
While this function doesn't trigger the compiler to report any errors, as soon as the application starts, it freezes up and crashes. For additional information MAP_WIDTH and MAP_HEIGHT are set to 40 each and the 3D array was constructed like this:
TileList2.resize(MAP_HEIGHT);
for (int i = 0; i < MAP_HEIGHT; ++i) {
TileList2[i].resize(MAP_WIDTH);
for (int j = 0; j < MAP_WIDTH; ++j)
TileList2[i][j].resize(3);
}
I would appreciate it if you could point me out what do I need to fix, as far as I know I must have messed up the for loop structure, as the 3D array initializes and works properly. Thank you for your help!
TileList2.clear();
This line reinitializes TileList2, so it is back to a zero-length vector. Delete that line, and you will probably be okay.