Skip to content

Instantly share code, notes, and snippets.

@mtao
Created October 29, 2017 17:57
Show Gist options
  • Save mtao/ffa645c9ec15e2be8da9708473a253a3 to your computer and use it in GitHub Desktop.
Save mtao/ffa645c9ec15e2be8da9708473a253a3 to your computer and use it in GitHub Desktop.
game of life / langdon's ant code i wrote to help someone learning first year C
#include <stdio.h>
#include <unistd.h>
#define NUM_ROWS 50
#define NUM_COLS 50
int wrap(int i, int max) {
return ((i) % max + max) % max;
}
int row_wrap(int i) {
return wrap(i,NUM_ROWS);
}
int col_wrap(int j) {
return wrap(j,NUM_COLS);
}
void copy(int from[NUM_ROWS][NUM_COLS], int to[NUM_ROWS][NUM_COLS])
{
for(int i = 0; i < NUM_ROWS; ++i) {
for(int j = 0; j < NUM_COLS; ++j) {
to[i][j] = from[i][j];
}
}
}
void swap(int g1[NUM_ROWS][NUM_COLS], int g2[NUM_ROWS][NUM_COLS])
{
for(int i = 0; i < NUM_ROWS; ++i) {
for(int j = 0; j < NUM_COLS; ++j) {
int tmp = g1[i][j];
g1[i][j] = g2[i][j];
g2[i][j] = tmp;
}
}
}
void clear(int g[NUM_ROWS][NUM_COLS])
{
for(int i = 0; i < NUM_ROWS; ++i) {
for(int j = 0; j < NUM_COLS; ++j) {
g[i][j] = 0;
}
}
}
void print(int g[NUM_ROWS][NUM_COLS])
{
for(int j = 0; j < NUM_COLS; ++j) {
printf("=");
}
printf("\n");
for(int i = 0; i < NUM_ROWS; ++i) {
for(int j = 0; j < NUM_COLS; ++j) {
if(g[i][j] != 0) {
printf("o");
} else {
printf(".");
}
}
printf("\n");
}
for(int j = 0; j < NUM_COLS; ++j) {
printf("=");
}
printf("\n\n");
}
int alive_neighbors(int grid[NUM_ROWS][NUM_COLS], int i, int j)
{
int alive = 0;
for(int l = -1; l < 2; ++l) {
for(int m = -1; m < 2; ++m) {
if((l != 0) || (m != 0)) {
int ri = wrap(i+l,NUM_ROWS);
int rj = wrap(j+m,NUM_COLS);
if(grid[ri][rj] != 0) {
alive++;
}
}
}
}
return alive;
}
void gol_step(int grid[NUM_ROWS][NUM_COLS])
{
int tmpgrid[NUM_ROWS][NUM_COLS];
copy(grid,tmpgrid);
clear(grid);
for(int i = 0; i < NUM_ROWS; ++i) {
for(int j = 0; j < NUM_COLS; ++j) {
int alive_nbrs = alive_neighbors(tmpgrid,i,j);
int alive = tmpgrid[i][j];
if(alive != 0) {
if(alive_nbrs < 2 || alive_nbrs > 3) {
alive = 0;
} else {
alive = 1;
}
} else {
if(alive_nbrs == 3) {
alive = 1;
}
}
grid[i][j] = alive;
}
}
}
void set(int grid[NUM_ROWS][NUM_COLS], int i, int j, int val)
{
int ri = wrap(i,NUM_ROWS);
int rj = wrap(j,NUM_COLS);
grid[ri][rj] = val;
}
void toad(int grid[NUM_ROWS][NUM_COLS], int i, int j)
{
set(grid,i+0,j+0,1);
set(grid,i+0,j+1,1);
set(grid,i+0,j+2,1);
set(grid,i+1,j+1,1);
set(grid,i+1,j+2,1);
set(grid,i+1,j+3,1);
}
void glider(int grid[NUM_ROWS][NUM_COLS], int i, int j)
{
set(grid,i+0,j+1,1);
set(grid,i+1,j+0,1);
set(grid,i+2,j+0,1);
set(grid,i+2,j+1,1);
set(grid,i+2,j+2,1);
}
void beacon(int grid[NUM_ROWS][NUM_COLS], int i, int j)
{
set(grid,i+0,j+0,1);
set(grid,i+1,j+0,1);
set(grid,i+0,j+1,1);
set(grid,i+1,j+1,1);
set(grid,i+2,j+2,1);
set(grid,i+3,j+2,1);
set(grid,i+2,j+3,1);
set(grid,i+3,j+3,1);
}
int value(int grid[NUM_ROWS][NUM_COLS], int i, int j) {
return grid[row_wrap(i)][row_wrap(j)];
}
//0 = north
//1 = east
//2 = south
//3 = west
int left(int dir) {
return wrap(dir-1,4);
}
int right(int dir) {
return wrap(dir+1,4);
}
int xoff(int dir) {
switch(dir) {
case 0: return 0;
case 1: return 1;
case 2: return 0;
case 3: return -1;
}
return 0;
}
int yoff(int dir) {
switch(dir) {
case 0: return 1;
case 1: return 0;
case 2: return -1;
case 3: return 0;
}
return 0;
}
void langdon_ant_step(int grid[NUM_ROWS][NUM_COLS], int* x_ptr, int* y_ptr, int* dir_ptr)
{
int x = *x_ptr;
int y = *y_ptr;
int dir = *dir_ptr;
if(value(grid,x,y) == 0) {//black
dir = right(dir);
} else {
dir = left(dir);
}
grid[x][y] = grid[x][y]==0?1:0;
x = row_wrap(x + xoff(dir));
y = col_wrap(y + yoff(dir));
*x_ptr = x;
*y_ptr = y;
*dir_ptr = dir;
}
void gol(int grid[NUM_ROWS][NUM_COLS]) {
//for(int i = 0; i < 1000; ++i) {
while(1) {
print(grid);
gol_step(grid);
usleep(16000);
}
}
void langdon_ant(int grid[NUM_ROWS][NUM_COLS])
{
int x = NUM_ROWS/2;
int y = NUM_COLS/2;
int dir = 0;
while(1) {
print(grid);
langdon_ant_step(grid,&x,&y,&dir);
usleep(16000);
}
}
void double_step(int grid[NUM_ROWS][NUM_COLS])
{
int x = NUM_ROWS/2;
int y = NUM_COLS/2;
int dir = 0;
while(1) {
gol_step(grid);
for(int i = 0; i < 20; ++i) {
langdon_ant_step(grid,&x,&y,&dir);
usleep(1600);
print(grid);
}
}
}
int main() {
int grid[NUM_ROWS][NUM_COLS];
for(int i = 0; i < NUM_ROWS; ++i) {
for(int j = 0; j < NUM_COLS; ++j) {
if(grid[i][j] != 0) {
grid[i][j] = 1;
}
}
}
//clear(grid);
toad(grid,5,6);
glider(grid,20,1);
beacon(grid,2,30);
double_step(grid);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment