https://tkkrlab.nl/w/index.php?title=Game_of_Lifeish,_on_a_lcd&feed=atom&action=historyGame of Lifeish, on a lcd - Revision history2020-09-12T12:02:53ZRevision history for this page on the wikiMediaWiki 1.24.6https://tkkrlab.nl/w/index.php?title=Game_of_Lifeish,_on_a_lcd&diff=3303&oldid=prevDuality: /* Arduino Code */2012-06-05T20:07:19Z<p><span dir="auto"><span class="autocomment">Arduino Code</span></span></p>
<p><b>New page</b></p><div>Hi I am Duality, and I made a version of game of life that works on a 20x4 lcd,<br><br />
I've found it really frustrating at times, <br><br />
But I now got a working piece of code, with hardware. for the arduino!<br><br />
<br />
==Requirements==<br />
You need,<br />
* A arduino<br />
* A Lcd (I used 4x20)<br />
* Some programming experience, and be a little bit crazy, if your not, this will make you a little bit crazy.<br />
<br />
==Hardware/software I used:==<br />
I used a Arduino uno, And arduino IDE 0023 <br><br />
My lcd was driven with IOlcd: <br><br />
http://tkkrlab.nl/wiki/Lcd_through_IOexpander<br><br />
(also a project of mine) <br><br />
<br />
==Data: ==<br />
<br />
The rules of the Game of life Are:<br />
1. Each cell with one or no neighbors dies, as if by loneliness.<br />
2. Each cell with four or more neighbors dies, as if by overpopulation.<br />
3. Each cel with tow or three neighbors survives.<br />
4. Each dead cell or empty block with three neighbors becomes populated, as if by reproduction.<br />
<br />
We can set SurviveAbility in the code below, this wil set the amount of cells around the cell<br />
that are needed to survive. if set to 2 (normal surcumstance) then cells with 2 or 3 neighbors<br />
survives.<br />
<br />
we can also set reproductiveNumber in the code below,<br />
This will set the number of cells needed around a dead cell/block<br />
to make it alive.<br />
<br />
playing around with these numbers is fun, and i recommend it.<br />
<br />
---------------------------------------------------------------------------------<br />
<br />
Because of the nature of the my lcd it being 20x4, it will someTime's reach a stable<br />
form that does not look like anny stable for fromt he real game of life by John Conway.<br />
to test if this shape is a real stable form, I went to this website:<br />
http://www.bitstorm.org/gameoflife/<br />
I've put in the shape's here That are stable on my lcd, and if they end up in a stable form,<br />
they must be obeying the rules of the game of life.<br />
This is actually how I tested if my rules were correct.<br />
<br />
A little Technical not on the LCD:<br />
because of the way the boundary checks are performed, and the lcd is addresed<br />
shapes might look mishaped,<br />
<br />
Lcd:<br />
______________________________________<br />
|if start is here 1|<br />
|234 then new line starts here after |<br />
_________________________________________<br />
<br />
so shapes that would go of the side boundary's like:<br />
_____________________________________________________<br />
|--------------------------------------------------X|<br />
|X------------------------------------------------X-|<br />
|-X------------------------------------------------X|<br />
|X--------------------------------------------------|<br />
_____________________________________________________<br />
<br />
for a shape that looks like XX<br />
X X<br />
XX<br />
<br />
This however does not meen that the end of the fourth line is connected to the beginning,<br />
of the first line, they're not connect. this only works for the last three lines.<br />
----------------------------------------------------------------------------------------------<br />
Stabel shapes(on the lcd) that i've found to be complex structers when put in: http://www.bitstorm.org/gameoflife/<br />
<br />
in this case # represents a living cells, and - represents dead cells.<br />
<br />
1. ----#####----<br />
----#---#----<br />
------#------ <br />
-----###-----<br />
<br />
2. ----#######---<br />
----#-----#---<br />
------#-#-----<br />
-----##-##----<br />
<br />
3. ----##-##----- <br />
---#-#-#------<br />
-#--#----#-##-<br />
-###----##-##-<br />
<br />
==Arduino Code==<br />
The code below is most recent, and now is the fully functioning code, that works! and apply's the game of life rules, by John Conway.<br />
<syntaxhighlight lang="c">/*<br />
The rules of the Game of life Are:<br />
1. Each cell with one or no neighbors dies, as if by loneliness.<br />
2. Each cell with four or more neighbors dies, as if by overpopulation.<br />
3. Each cel with tow or three neighbors survives.<br />
4. Each dead cell or empty block with three neighbors becomes populated, as if by reproduction.<br />
<br />
We can set SurviveAbility in the code below, this wil set the amount of cells around the cell<br />
that are needed to survive. if set to 2 (normal surcumstance) then cells with 2 or 3 neighbors<br />
survives.<br />
<br />
we can also set reproductiveNumber in the code below,<br />
This will set the number of cells needed around a dead cell/block<br />
to make it alive.<br />
<br />
playing around with these numbers is fun, and i recommend it.<br />
<br />
---------------------------------------------------------------------------------<br />
<br />
Because of the nature of the my lcd it being 20x4, it will someTime's reach a stable<br />
form that does not look like anny stable for fromt he real game of life by John Conway.<br />
to test if this shape is a real stable form, I went to this website:<br />
http://www.bitstorm.org/gameoflife/<br />
I've put in the shape's here That are stable on my lcd, and if they end up in a stable form,<br />
they must be obeying the rules of the game of life.<br />
This is actually how I tested if my rules were correct.<br />
<br />
A little Technical not on the LCD:<br />
because of the way the boundary checks are performed, and the lcd is addresed<br />
shapes might look mishaped,<br />
<br />
Lcd:<br />
______________________________________<br />
|if start is here 1|<br />
|234 then new line starts here after |<br />
_________________________________________<br />
<br />
so shapes that would go of the side boundary's like:<br />
_____________________________________________________<br />
|--------------------------------------------------X|<br />
|X------------------------------------------------X-|<br />
|-X------------------------------------------------X|<br />
|X--------------------------------------------------|<br />
_____________________________________________________<br />
<br />
for a shape that looks like XX<br />
X X<br />
XX<br />
<br />
This however does not meen that the end of the fourth line is connected to the beginning,<br />
of the first line, they're not connect. this only works for the last three lines.<br />
----------------------------------------------------------------------------------------------<br />
Stabel shapes(on the lcd) that i've found to be complex structers when put in: http://www.bitstorm.org/gameoflife/<br />
<br />
in this case # represents a living cells, and - represents dead cells.<br />
<br />
1. ----#####----<br />
----#---#----<br />
------#------ <br />
-----###-----<br />
<br />
2. ----#######---<br />
----#-----#---<br />
------#-#-----<br />
-----##-##----<br />
<br />
3. ----##-##----- <br />
---#-#-#------<br />
-#--#----#-##-<br />
-###----##-##-<br />
*/<br />
<br />
#include <TrueRandom.h><br />
//includeing files and setting up the lcd and TrueRandom.<br />
#include <IOlcd.h><br />
#include <Wire.h><br />
<br />
IOlcd lcd;<br />
<br />
//the higher this number less chance of surviving.<br />
//since this number determines what amount of cells next to a cell it takes to stay<br />
//alife. 8 is max<br />
#define surviveAbility 2<br />
//the higher this number, the less chance for reproduction.<br />
//since this number determines how many cells it takes to turn a dead cell alife.<br />
//9 is max<br />
#define reproductiveNumber 3<br />
//the normal numbers for rules, just like John Conway's Game of life, <br />
//are 2 for surviveAbility.<br />
//and 3 for reproductiveNumber.<br />
<br />
//the higher this number, the slower the screen will be printed(in effect slow the program<br />
#define delayVal 0<br />
<br />
//setting up the field.<br />
#define fieldWidth 20<br />
#define fieldHeigth 4<br />
#define fieldSize fieldWidth*fieldHeigth<br />
#define byte_type uint8_t<br />
byte_type field[fieldSize+1]={0};<br />
<br />
<br />
//keeping track of what your checking in a buffer.<br />
int Position = 0;<br />
<br />
//Timer for checkin once in while, if field is empty.<br />
unsigned long previousTimer = 0;<br />
unsigned long currentTimer = 0;<br />
int interval = 1000;<br />
<br />
//fill the field with random starting places<br />
void fillField(int Min, int Max){<br />
int i=0;<br />
while(i<fieldSize){<br />
field[i]=TrueRandom.random(Min,Max);<br />
i++;<br />
}<br />
}<br />
//these are boundary checks, and also for checking,<br />
//where around a cell a living cell is.<br />
int checkUpper(){<br />
if(Position-20>0){<br />
if(field[Position-20]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
<br />
int checkLower(){<br />
if(Position+20<80){<br />
if(field[Position+20]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
<br />
int checkLeft(){<br />
if(Position-1>0){<br />
if(field[Position-1]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
<br />
int checkRight(){<br />
if(Position+1<80){<br />
if(field[Position+1]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
<br />
int checkUpperLeft(){<br />
if(Position-21>0){<br />
if(field[Position-21]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
<br />
int checkUpperRight(){<br />
if(Position-19>0){<br />
if(field[Position-19]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
<br />
int checkLowerLeft(){<br />
if(Position+19<80){<br />
if(field[Position+19]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
<br />
int checkLowerRight(){<br />
if(Position+21<80){<br />
if(field[Position+21]){<br />
return 1;<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
else{<br />
return 0;<br />
}<br />
}<br />
//used to display everything onto the display in the right order, on the right lines.<br />
void displayField(int Position){<br />
if(field[Position]){<br />
lcd.write(1);<br />
}<br />
else{<br />
lcd.write(0);<br />
}<br />
switch(Position){<br />
case 20:<br />
lcd.setCursor(0,1);<br />
break;<br />
case 40:<br />
lcd.setCursor(0,2);<br />
break;<br />
case 60:<br />
lcd.setCursor(0,3);<br />
break;<br />
case 80:<br />
lcd.setCursor(0,0);<br />
break;<br />
}<br />
}<br />
<br />
//here we create the characters to be displayed, when alive or dead.<br />
byte alife[8] ={<br />
B01010,<br />
B01010,<br />
B10101,<br />
B10101,<br />
B01110,<br />
B01010,<br />
B01010,<br />
};<br />
<br />
byte death[8] ={<br />
B10101,<br />
B11111,<br />
B10101,<br />
B11111,<br />
B10101,<br />
B11111,<br />
B10101,<br />
};<br />
<br />
//here I check how many alive cels there are around a given position in the field.<br />
int totalAround(){<br />
int around = checkUpper()+checkLower()+checkLeft()+checkRight()+checkUpperLeft()+checkUpperRight()+checkLowerLeft()+checkLowerRight();<br />
return around;<br />
}<br />
//this is for checking if a field is empty<br />
int checkOneBits(){<br />
int onebits = 0;<br />
for(int i=0;i<fieldSize;i++){<br />
onebits |= field[i];<br />
}<br />
return onebits;<br />
}<br />
//this is for displaying the field fully once, needed for when the lcd is empty, but you just<br />
//filled the field with random 1's and 0's.<br />
void displayFieldOnce(){<br />
for(int i=0;i<fieldSize;i++){<br />
displayField(i);<br />
}<br />
}<br />
<br />
void setup(){<br />
delay(1000);<br />
//setup display workings.<br />
lcd.init(0x20,MCP23016);<br />
lcd.begin(20,4);<br />
//setup costum chars.<br />
lcd.createChar(0,death);<br />
lcd.createChar(1,alife);<br />
lcd.home();<br />
lcd.clear();<br />
<br />
<br />
fillField(0,2);<br />
//have to show the field once, or else starting screen empty.<br />
displayFieldOnce();<br />
}<br />
<br />
void loop(){<br />
currentTimer = millis();<br />
//I look if in the current position is a living cell, if not I check<br />
//how many cells are around the dead space/blok/cell.<br />
//basicly we aply the game rules here.<br />
if(field[Position]){<br />
if(totalAround()==surviveAbility){<br />
field[Position]=1;<br />
}<br />
else if(totalAround()==surviveAbility+1){<br />
field[Position]=1;<br />
}<br />
else{<br />
field[Position]=0;<br />
}<br />
}<br />
else{<br />
if(totalAround()==reproductiveNumber){<br />
field[Position]=1;<br />
}<br />
}<br />
// we display the contents of the field.<br />
displayField(Position);<br />
Position++;<br />
if(Position==80){<br />
Position=0;<br />
}<br />
//once a second I check if the field is empty.<br />
//this is done this way, to prevent speed los due to <br />
//the loop in checkOneBits();<br />
if(currentTimer - previousTimer > interval){<br />
previousTimer = currentTimer;<br />
if(!checkOneBits()){<br />
fillField(0,2);<br />
displayFieldOnce();<br />
}<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
==Gallery/Pictures==<br />
http://www.flickr.com/photos/72811375@N07/7272593340/<br />
<br />
==Video of it in action and working!==<br />
{{#ev:youtube|o2YsDi5sIbc|500}}<br><br />
<br><br />
<br><br />
<br><br />
<br><br />
<br><br />
=Related Videos=<br />
{{#ev:youtube|kkffoMvTin0|500}}{{#ev:youtube|Sw933sg2Q_E|500}}<br />
{{#ev:youtube|Ir1XvgdrxpU|500}}</div>Duality