#include <iostream>
#include <ctime>
#include <unistd.h>
#include <cstdlib>
using namespace std;
main()
{
int x,y;
cout << "Choose grid dimensions (x,y):";
cin >> x >> y;
int current[x][y];
int next[x][y];
int neighbors;
srand((int)time(0));
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
{
current[i][j]=(rand()%2);
}
while (true)
{
for (int a = 0; a++ < 2*x + 5;)
cout << "X";
cout << endl;
for (int i=0;i<y;i++)
{
cout << "XX ";
for (int j = 0;j < x; j++)
{
current[i][j] ? cout << " " : cout << " ";
neighbors = 0;
for (int k = -1; k < 2; k++)
{
for (int l = -1; l++ < 2;)
{
if (k||l)
neighbors+=current[(i+l)%y][(j+k)%x];
}
}
if (current[i][j])
{
(neighbors == 2 || neighbors == 3) ? next[i][j] = 1 : next[i][j] = 0;
}
else
{
neighbors == 3 ? next[i][j] = 1 : next[i][j] = 0;
}
}
cout << "XX";
cout << endl;
}
for (int a = 0; a++ < 2*x + 5;)
cout << "X";
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
current[i][j] = next[i][j];
}
}
sleep(0.5);
system("cls");
}
}
Sometimes it allows impossible still lives like the Z pentomino to live close to the edge. How can I fix it?
EDIT: Great. Now it went haywire completely.
I was so socially awkward in the past and it will haunt me for the rest of my life.
rowett wrote: June 27th, 2020, 11:20 am
The % operator is not doing what you expect. When the value is negative it won't wrap it around. -1 % 20 is not 19, it's -1.
Apparently it's not even consistent. Boo. Try this:
rowett wrote: June 27th, 2020, 11:20 am
The % operator is not doing what you expect. When the value is negative it won't wrap it around. -1 % 20 is not 19, it's -1.
Apparently it's not even consistent. Boo. Try this:
int mod(int a, int b) {
int s {(a > 0) - (a < 0)};
a = ((s + 1) > 0) ? a : b + a;
return a % b;
}
(excuse the horrible mess of simplified code)
Actually I found a simpler way to do that, but was too lazy to implement it.
Just add 20 (if the grid's x size is 20 for example) to the x/y coordinates of the neighbors and then mod it.
for (init-statement; condition; iteration_expression)
The init-statement is always executed at the beginning.
The condition is evaluated before every loop. If the condition is non-zero then loop executes, otherwise the for loop ends.
The iteration_expression is evaluated at the end of every loop. (If the condition is 0 to begin with then the iteration_expression is never evaluated.)
Therefore in your original method the variable was being incremented before every loop but the second for is incrementing after every loop.
Off the top of my head I can't think any good examples where the condition statement would have a side effect such as incrementing a variable so I would avoid doing that kind of thing.
for (init-statement; condition; iteration_expression)
The init-statement is always executed at the beginning.
The condition is evaluated before every loop. If the condition is non-zero then loop executes, otherwise the for loop ends.
The iteration_expression is evaluated at the end of every loop. (If the condition is 0 to begin with then the iteration_expression is never evaluated.)
Therefore in your original method the variable was being incremented before every loop but the second for is incrementing after every loop.
Off the top of my head I can't think any good examples where the condition statement would have a side effect such as incrementing a variable so I would avoid doing that kind of thing.
Thanks for the explanation! But I still can't figure out how to make it work perfectly.
#include <iostream>
#include <ctime>
#include <unistd.h>
#include <cstdlib>
using namespace std;
main()
{
int x,y;
cout << "Choose grid dimensions (x,y):";
cin >> x >> y;
int current[x][y];
int next[x][y];
int neighbors;
srand((int)time(0));
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
current[i][j]=(rand()%2);
while (true)
{
for (int a = 0; a < 2*x + 5; a++)
cout << "X";
cout << endl;
for (int i = 0; i < y; i++)
{
cout << "XX";
for (int j = 0; j < x; j++)
{
current[i][j] ? cout << " 0" : cout << " ";
neighbors = 0;
for (int deltay = -1; deltay < 2; deltay++)
for (int deltax = -1; deltax < 2; deltax++)
if (deltax||deltay)
neighbors+=current[(i+deltax+x)%x][(j+deltay+y)%y];
if (current[i][j])
(neighbors == 2 || neighbors == 3) ? next[i][j] = 1 : next[i][j] = 0;
else
neighbors == 3 ? next[i][j] = 1 : next[i][j] = 0;
}
cout << " XX";
cout << endl;
}
for (int a = 0; a < 2*x + 5; a++)
cout << "X";
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
current[i][j] = next[i][j];
system("cls");
}
}
Ok I've changed all the loop conditions and it seems to work now.
But there still is a problem when inputting grid sizes with a height larger than the width. Sometimes it makes super tiny grids, sometimes it works normal, and sometimes it crashes. Why?
I was so socially awkward in the past and it will haunt me for the rest of my life.
gameoflifemaniac wrote: July 3rd, 2020, 4:20 pm
Ok I've changed all the loop conditions and it seems to work now.
But there still is a problem when inputting grid sizes with a height larger than the width. Sometimes it makes super tiny grids, sometimes it works normal, and sometimes it crashes. Why?
I think I see the reason. You define your arrays like:
Therefore you need to make sure that i runs between 0 and x-1, and that j runs between 0 and y-1. Looks like you have this the wrong way round so will only work currently if x and y happen to be the same.
gameoflifemaniac wrote: July 3rd, 2020, 4:20 pm
Ok I've changed all the loop conditions and it seems to work now.
But there still is a problem when inputting grid sizes with a height larger than the width. Sometimes it makes super tiny grids, sometimes it works normal, and sometimes it crashes. Why?
I think I see the reason. You define your arrays like:
Therefore you need to make sure that i runs between 0 and x-1, and that j runs between 0 and y-1. Looks like you have this the wrong way round so will only work currently if x and y happen to be the same.
#include <iostream>
#include <ctime>
#include <unistd.h>
#include <cstdlib>
using namespace std;
main()
{
int x,y;
cout << "Choose grid dimensions (x,y):";
cin >> x >> y;
int current[x][y];
int next[x][y];
int neighbors;
srand((int)time(0));
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
current[i][j]=(rand()%2);
while (true)
{
for (int a = 0; a < 2*y + 5; a++)
cout << "X";
cout << endl;
for (int i = 0; i < x; i++)
{
cout << "XX";
for (int j = 0; j < y; j++)
{
current[i][j] ? cout << " 0" : cout << " ";
neighbors = 0;
for (int deltay = -1; deltay < 2; deltay++)
for (int deltax = -1; deltax < 2; deltax++)
if (deltax||deltay)
neighbors+=current[(i+deltax+x)%x][(j+deltay+y)%y];
if (current[i][j])
(neighbors == 2 || neighbors == 3) ? next[i][j] = 1 : next[i][j] = 0;
else
neighbors == 3 ? next[i][j] = 1 : next[i][j] = 0;
}
cout << " XX";
cout << endl;
}
for (int a = 0; a < 2*y + 5; a++)
cout << "X";
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
current[i][j] = next[i][j];
system("cls");
}
}
I've switched x and y in the right places and it works perfectly. Thank you, bubblegum and rowett for your help!
I wanted to make this program to introduce myself into the programming language (it's only displayed in the console after all!). You taught me stuff I didn't learn from my online course, too.
I was so socially awkward in the past and it will haunt me for the rest of my life.