Skip to content

Instantly share code, notes, and snippets.

@PhirePhly
Created September 24, 2009 22:09
Show Gist options
  • Save PhirePhly/193087 to your computer and use it in GitHub Desktop.
Save PhirePhly/193087 to your computer and use it in GitHub Desktop.
/*
The Game of Life displayed on an
HD44780 LCD from an Arduino
*/
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers
// of the interface pins
LiquidCrystal lcd(2,3,4,5,6,7);
#define WORLDMAXX 19
#define WORLDMAXY 15
byte world[WORLDMAXX+1][WORLDMAXY+1];
// check this for stable states every 6
byte oldworld[WORLDMAXX+1][WORLDMAXY+1];
int stepcount;
void initworld();
void isalive(int x, int y);
int countneighbor(int x, int y);
void generatechars();
void printworld();
void setup() {
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
randomSeed(analogRead(0));
lcd.setCursor(4, 0);
lcd.print(" Conway's");
lcd.setCursor(4, 1);
lcd.print("Game of Life");
initworld();
}
void loop() {
int i, j;
generatechars();
printworld();
for (i = 0; i<= WORLDMAXX; i++) {
for (j = 0; j<= WORLDMAXY; j++) {
isalive(i,j);
}
}
for (i = 0; i<= WORLDMAXX; i++) {
for (j = 0; j<= WORLDMAXY; j++) {
world[i][j] = world[i][j] >> 1;
}
}
// Every 6 steps, check to see if the
// world is in a stable state
if (stepcount) {
delay(300);
} else {
int diffflag = 0;
for (i = 0; i<= WORLDMAXX; i++) {
for (j = 0; j<= WORLDMAXY; j++) {
if (world[i][j] != oldworld[i][j]) {
// they're still different
diffflag = 1;
}
}
}
if (diffflag == 0) { // we're in steady state
initworld();
} else { // save the new world for later
for (i = 0; i<= WORLDMAXX; i++) {
for (j = 0; j<= WORLDMAXY; j++) {
oldworld[i][j] = world[i][j];
}
}
}
delay (297); // It takes about 3ms to check...
}
stepcount = (stepcount + 1) % 6;
}
void initworld() {
int i, j;
for (i=0; i<=WORLDMAXX; i++) {
for (j=0; j<=WORLDMAXY; j++) {
world[i][j] = !random(4);
}
}
stepcount = 0;
return;
}
// Calculate the next state for the square
void isalive(int x, int y) {
int count = countneighbor(x, y);
if (count == 2) { // 2 neighbors, stay the same
world[x][y] += world[x][y] << 1;
}
if (count == 3) { // 3 neighbors, must be alive
world[x][y] += 2;
}
// any other number of neighbors, must be dead
return;
}
int countneighbor(int x, int y) {
int count = 0;
if (x > 0) {
count += world[x-1][y] & 1;
if (y > 0) {
count += world[x-1][y-1] & 1;
}
if (y < WORLDMAXY) {
count += world[x-1][y+1] & 1;
}
}
if (x < WORLDMAXX) {
count += world[x+1][y] & 1;
if (y > 0) {
count += world[x+1][y-1] & 1;
}
if (y < WORLDMAXY) {
count += world[x+1][y+1] & 1;
}
}
if (y > 0) {
count += world[x][y-1] & 1;
}
if (y < WORLDMAXY) {
count += world[x][y+1] & 1;
}
return count;
}
// pack world[][] into the required byte[8]
// arrays to be passed to the LCD
void generatechars() {
byte tempchar[8];
int i, j, k, l;
for (i = 0; i<2; i+=1) { // y poss / 8
for (j = 0; j<4; j+=1) { // x poss / 5
for (k = 0; k < 8; k+=1) {
tempchar[k] = 0;
for (l = 0; l<5; l+=1) {
tempchar[k] += (world[j*5 + l][i * 8 + k] & 1) << (4 - l);
}
} // done building this char
lcd.createChar(i*4 + j, tempchar);
}
}
return;
}
void printworld() {
int i, j;
for (i=0; i<2; i+=1) {
lcd.setCursor(0, i);
for (j=0; j<4; j+=1) {
lcd.write(i*4 + j);
}
}
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment