Hi there
I programmed Conways game of life on the LOLshield.
Now the game seems to work, I can tell by the following situation:
Sometimes you end up by a static block of 4 or an oscillating row of 3 led's. This is OK by the rules, and tells me that the rules themselves should be ok.
However: I have strange things happening on the edges of the screen. Oftentimes I end up with 2 neighboring LED's on the screens edge that stay on.
By the rules, if one cell has only one neighbor, as it is the case when only 2 led's are shining, they both should die.
Now the strange thing is, if I have just 2 led's in the middle of the screen turned on, they die off correctly.
Now below, I post the code.
I am aware that I have no code to account for the screen edges. Meaning if a cell is at position 14, it will look at the non-existing position 15 for a neighbor, instead of going back to position 1 to look there.
I will write that part later (because I haven't figured it out yet). Still, if, like in my code, the neighbor-check looks into non-existent cells, neighbors shouldn't be counted up, because those cells don't exist as they are out of bound).
Now I'll be pleased with both answers:
- If you have a suggestion how to improve my neighbor-check, so that it works on the edges as if the screen was wrapped, I'd be VERY pleased.
- If anyone knows why I even end up in that strange situation and can explain this, I might be able to figure the rest out myself.
So here it is:
#include <Charliplexing.h>
#include <Figure.h>
#include <Font.h>
const byte SIZEX = 14;
const byte SIZEY = 9;
byte grid[SIZEX][SIZEY];
byte nextGrid[SIZEX][SIZEY];
byte neighbors;
void setup(){
Serial.begin(9600);
LedSign::Init(); //Initialize LOLShield
LedSign::SetBrightness(40);
randomSeed(analogRead(0)); //Initialize Random Number
clearScreen();
initialize();
delay(200);
}
void loop(){
clearScreen();
gamelogic();
showGame();
fillnextgrid();
delay(200);
}
//Empty Screen
void clearScreen(){
LedSign::Clear();
}
//Initializes the very first screen with random cells
void initialize(){
for(int x = 0; x < SIZEX;x++){
for(int y = 0; y < SIZEY;y++){
grid[x][y] = random(2);
LedSign::Set(x,y,grid[x][y]);
}
}
}
//Needs logic for edge boundaries!!
void gamelogic(){
for(int x = 0; x < SIZEX; x++){
for(int y = 0; y < SIZEY; y++){
//Count all the neighboring cells
neighbors = 0;
if(grid[x-1][y-1] == 1) neighbors++; //Nowthwest
if(grid[x][y-1] == 1) neighbors++; //north
if(grid[x+1][y-1] == 1) neighbors++; //northeast
if(grid[x-1][y] == 1) neighbors++; //west
if(grid[x+1][y] == 1) neighbors++; //east
if(grid[x-1][y+1] == 1) neighbors++; //southwest
if(grid[x][y+1] == 1) neighbors++; //south
if(grid[x+1][y+1] == 1) neighbors++; //southeast
// The gamerules
// born
if(grid[x][y] == 0 && neighbors == 3) nextGrid[x][y] = 1;
// Alive and stay alive
if(grid[x][y] == 1 && neighbors == 2) nextGrid[x][y] = 1;
if(grid[x][y] == 1 && neighbors == 3) nextGrid[x][y] = 1;
// Alive and die
if(grid[x][y] == 1 && neighbors < 2) nextGrid[x][y] = 0;
if(grid[x][y] == 1 && neighbors > 3) nextGrid[x][y] = 0;
//Debugging the neighbor count
Serial.println(neighbors);
//delay(10);
}
}
}
//Writes back all the values that gamelogic() calculated into temporary nextGrid to grid
void fillnextgrid(){
for(int x = 0; x < SIZEX; x++){
for(int y = 0; y < SIZEY; y++){
grid[x][y] = nextGrid[x][y];
}
}
}
//Shows the gamescreen
void showGame(){
for(int x = 0; x < SIZEX; x++){
for(int y = 0; y < SIZEY; y++){
LedSign::Set(x,y,grid[x][y]);
}
}
}