aboutsummaryrefslogtreecommitdiffstats
path: root/avr-test2/src/gameoflife.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'avr-test2/src/gameoflife.cpp')
-rw-r--r--avr-test2/src/gameoflife.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/avr-test2/src/gameoflife.cpp b/avr-test2/src/gameoflife.cpp
new file mode 100644
index 0000000..0a3683a
--- /dev/null
+++ b/avr-test2/src/gameoflife.cpp
@@ -0,0 +1,135 @@
+#include <avr/io.h>
+#include "gameoflife.h"
+#include "cube.h"
+#include "draw.h"
+
+// Game of Life for the 4x4x4 and 8x8x8 led cube
+
+#define GOL_CREATE_MIN 3
+#define GOL_CREATE_MAX 3
+
+#define GOL_TERMINATE_LONELY 1
+#define GOL_TERMINATE_CROWDED 4
+
+#define GOL_X 8
+#define GOL_Y 8
+#define GOL_Z 8
+
+#define GOL_WRAP 0x01
+
+
+
+void gol_play (int iterations, uint16_t delay)
+{
+ int i;
+
+ for (i = 0; i < iterations; i++)
+ {
+ LED_PORT ^= LED_GREEN;
+
+ gol_nextgen();
+
+ if (gol_count_changes() == 0)
+ return;
+
+ tmp2cube();
+
+ delay_ms(delay);
+
+ //led_red(1);
+ }
+}
+
+void gol_nextgen (void)
+{
+ int x,y,z;
+ unsigned char neigh;
+
+ tmpfill(0x00);
+
+ for (x = 0; x < GOL_X; x++)
+ {
+ for (y = 0; y < GOL_Y; y++)
+ {
+ for (z = 0; z < GOL_Z; z++)
+ {
+ neigh = gol_count_neighbors(x, y, z);
+
+ // Current voxel is alive.
+ if (getvoxel(x,y,z) == 0x01)
+ {
+ if (neigh <= GOL_TERMINATE_LONELY)
+ {
+ tmpclrvoxel(x,y,z);
+ } else if(neigh >= GOL_TERMINATE_CROWDED)
+ {
+ tmpclrvoxel(x,y,z);
+ } else
+ {
+ tmpsetvoxel(x,y,z);
+ }
+ // Current voxel is dead.
+ } else
+ {
+ if (neigh >= GOL_CREATE_MIN && neigh <= GOL_CREATE_MAX)
+ tmpsetvoxel(x,y,z);
+ }
+ }
+ }
+ }
+}
+
+unsigned char gol_count_neighbors (int x, int y, int z)
+{
+ int ix, iy, iz; // offset 1 in each direction in each dimension
+ int nx, ny, nz; // neighbours address.
+
+ unsigned char neigh = 0; // number of alive neighbours.
+
+ for (ix = -1; ix < 2; ix++)
+ {
+ for (iy = -1; iy < 2; iy++)
+ {
+ for (iz = -1; iz < 2; iz++)
+ {
+ // Your not your own neighbour, exclude 0,0,0, offset.
+ if ( !(ix == 0 && iy == 0 && iz == 0) )
+ {
+ if (GOL_WRAP == 0x01)
+ {
+ nx = (x+ix)%GOL_X;
+ ny = (y+iy)%GOL_Y;
+ nz = (z+iz)%GOL_Z;
+ } else
+ {
+ nx = x+ix;
+ ny = y+iy;
+ nz = z+iz;
+ }
+
+ if ( getvoxel(nx, ny, nz) )
+ neigh++;
+ }
+ }
+ }
+ }
+ return neigh;
+}
+
+int gol_count_changes (void)
+{
+ int x,y;
+ int i = 0;
+
+ for (x = 0; x < GOL_X; x++)
+ {
+ for (y = 0; y < GOL_Y; y++)
+ {
+ if (fb[x][y] != cube[x][y])
+ i++;
+ }
+ }
+
+ return i;
+}
+