Skip to content

Instantly share code, notes, and snippets.

@ImSkully
Created November 7, 2019 21:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ImSkully/002f522af56e564dd490fdfd7d61954e to your computer and use it in GitHub Desktop.
Save ImSkully/002f522af56e564dd490fdfd7d61954e to your computer and use it in GitHub Desktop.
Conway's Game of Life
/**
Conway's Game of Life
Forked by Skully
Original Author: Huynh Quang Huy
TODO: Detect stale states.
TODO: Provide option to automatic generation stepper.
TODO: File output and input of patterns.
COMPILING WITH GCC:
> gcc -o gol gol.c
> gol [Height] [Width]
**/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
const int TRUE = 1;
const int FALSE = 0;
int WIDTH = 67;
int HEIGHT = 47;
void makeBoardLines(int board[HEIGHT][WIDTH])
{
int cols, rows;
for(cols = 0; cols < WIDTH; cols++)
{
board[0][cols] = '_';
board[HEIGHT - 1][cols] = '_';
}
for(rows = 1; rows < HEIGHT; rows++)
{
board[rows][0] = '|';
board[rows][WIDTH - 1] = '|';
}
}
void fillArray(int board[HEIGHT][WIDTH])
{
int i,j;
for(i = 1; i < HEIGHT - 1; i++)
for(j = 1; j < WIDTH - 1; j++)
board[i][j] = ' ';
}
void fillArrayRandomly(int board[HEIGHT][WIDTH])
{
int i, j, num;
srand((unsigned)time(NULL));
for(i = 1; i < HEIGHT -1; i++)
for(j = 1; j < WIDTH - 1; j++)
{
num = rand() % 11;
if (num == 1)
board[i][j] = 'O';
else board[i][j] = ' ';
}
}
void display2DArray(int board[HEIGHT][WIDTH])
{
int rows;
int cols;
for(rows = 0; rows < HEIGHT; rows++)
{
for(cols = 0; cols < WIDTH; cols++)
printf("%3c", board[rows][cols]);
printf("\n");
}
}
void countNeighbours(int board[HEIGHT][WIDTH])
{
int neighbors;
int rows;
int cols;
int a, b;
for(rows = 1; rows < HEIGHT; rows++)
{
for(cols = 1; cols < WIDTH; cols ++)
{
neighbors = 0;
if (board[rows][cols] == 'O')
{
for(a = -1; a < 2; a++)
{
for(b = -1; b < 2; b++)
if (((rows + a) == rows) && ((cols + b) == cols))
neighbors = neighbors;
else if ((board[rows + a][cols + b] == 'O') || (board[rows +a][cols +b] == 1) || (board[rows + a][cols + b] == 0))
neighbors++;
}
if ((neighbors == 2) || (neighbors == 3))
board[rows][cols] = 1; // Set alive.
else if ((neighbors < 2) || (neighbors >= 4))
board[rows][cols] = 0; // Set dead.
}
}
}
}
void checkNewborns(int board[HEIGHT][WIDTH])
{
int neighbors;
int rows;
int cols;
int a, b;
for(rows = 1; rows < HEIGHT - 1; rows++)
{
for(cols = 1; cols < WIDTH - 1; cols++)
{
neighbors = 0;
if (board[rows][cols] == ' ')
{
for(a = - 1; a < 2; a++)
{
for(b = - 1; b < 2; b++)
if (((rows + a) == rows) && ((cols +b) == cols))
neighbors = neighbors;
else if ((board[rows + a][cols + b] == 'O') || (board[rows + a][cols + b] == 1) || (board[rows + a][cols + b] == 0))
neighbors++;
}
if ((neighbors == 3))
board[rows][cols] = 2; // Newborn.
}
}
}
}
void newGeneration(int board[HEIGHT][WIDTH])
{
int rows;
int cols;
for(rows = 1; rows < HEIGHT -1; rows++)
{
for(cols = 1; cols < WIDTH - 1; cols++)
{
if (board[rows][cols] == 1)
board[rows][cols] = 'O';
else if (board[rows][cols] == 2)
board[rows][cols] = 'O';
else if (board[rows][cols] == 0)
board[rows][cols] = ' ';
}
}
}
int checkForExistance(int board[HEIGHT][WIDTH])
{
int rows;
int cols;
int creatures = 0;
for(rows = 1; rows < HEIGHT - 1; rows++)
{
for(cols = 1; cols < WIDTH - 1; cols++)
{
if (board[rows][cols] == 'O')
creatures++;
}
}
if (creatures == 0)
return TRUE; // All live forms dead.
else return FALSE; // There is still life existent.
}
void playGame(int board[HEIGHT][WIDTH], int numgeneration)
{
int i, c, check;
for(i = 1; (i <= numgeneration) && (c != 32); i++)
{
system("cls"); // Clear board.
countNeighbours(board);
checkNewborns(board);
newGeneration(board);
printf("Generation: %i\n", i);
printf("Press enter to move to the next generation.\n");
display2DArray(board);
getchar();
if(kbhit())
{
c = getch();
if(c == 32)
break;
}
check = checkForExistance(board);
if ((check = checkForExistance(board)) == TRUE)
{
printf("\nALL LIFE HAS DIED: GAME OVER!");
c = 32;
}
}
}
int returnNumber(int anumber)
{
if ((anumber > 50) || (anumber == 0))
{
printf("ERROR: The number must be between 1 and 50!\n");
printf("Please enter a valid number: ");
scanf("%i", &anumber);
returnNumber(anumber);
}
else return anumber;
}
void inputCoordinates(int board[HEIGHT][WIDTH])
{
int rows = 1;
int cols = 1;
while ((rows > 0) && (cols > 0))
{
printf("\nPlease enter x coordinate(a number from 1 to 30): ");
scanf("%i", &cols);
cols = returnNumber(cols);
if (cols > 0)
{
printf("Please enter Y coordinate (a number from 1 to 50): ");
scanf("%i", &rows);
rows = returnNumber(rows);
if ((rows > 0) && (cols > 0))
board[rows][cols] = 'O';
}
}
}
void createPatternTypes(int board[HEIGHT][WIDTH])
{
int type;
printf("\nType [1] to use the pattern 'BOX'");
printf("\nType [2] to use the pattern 'BEEHIVE'");
printf("\nType [3] to use the pattern 'TOAD'");
printf("\nType [4] to use the pattern 'SHIP'");
printf("\nType [5] to use the pattern 'GLIDER'");
printf("\nType [6] to use the pattern 'QUEEN BEE SHUTTLE'");
printf("\nType [7] to use the pattern 'PULSAR'");
printf("\nType [8] to use the pattern 'BLINKER'");
printf("\nType [9] to use the pattern 'PENTADECATHLON'\n");
scanf("%i", &type);
if (type == 1)
{
board[10][10] = 'O';
board[10][11] = 'O';
board[11][10] = 'O';
board[11][11] = 'O';
}
else if (type == 9)
{
board[15][10] = 'O';
board[15][11] = 'O';
board[15][12] = 'O';
board[15][13] = 'O';
board[15][14] = 'O';
board[15][15] = 'O';
board[15][16] = 'O';
board[15][17] = 'O';
board[15][18] = 'O';
board[15][19] = 'O';
}
else if (type == 5)
{
board[28][3] = 'O';
board[27][4] = 'O';
board[26][4] = 'O';
board[27][5] = 'O';
board[28][5] = 'O';
}
else if (type == 3)
{
board[18][12] = 'O';
board[18][13] = 'O';
board[18][14] = 'O';
board[19][11] = 'O';
board[19][12] = 'O';
board[19][13] = 'O';
}
else if (type == 6)
{
board[20][28] = 'O';
board[20][29] = 'O';
board[21][30] = 'O';
board[22][31] = 'O';
board[23][31] = 'O';
board[24][31] = 'O';
board[25][30] = 'O';
board[26][29] = 'O';
board[26][28] = 'O';
}
else if (type == 7)
{
board[12][14] = 'O';
board[13][13] = 'O';
board[13][14] = 'O';
board[13][15] = 'O';
board[14][13] = 'O';
board[14][15] = 'O';
board[15][13] = 'O';
board[15][14] = 'O';
board[15][15] = 'O';
board[16][14] = 'O';
}
else if (type == 8)
{
board[12][12] = 'O';
board[12][13] = 'O';
board[12][14] = 'O';
}
else if (type == 4)
{
board[12][12] = 'O';
board[12][13] = 'O';
board[13][12] = 'O';
board[14][13] = 'O';
board[14][14] = 'O';
board[13][14] = 'O';
}
else if (type ==2)
{
board[12][14] = 'O';
board[13][13] = 'O';
board[13][15] = 'O';
board[14][13] = 'O';
board[15][14] = 'O';
board[14][15] = 'O';
}
}
void userMode(int board[HEIGHT][WIDTH])
{
int i, generation, c, choice;
printf("\nDo you want to insert a particular pattern type? [1] for yes or [0] for no: ");
scanf("%i", &choice);
if (choice == 1)
{
createPatternTypes(board);
display2DArray(board);
}
else
{
inputCoordinates(board);
display2DArray(board);
}
printf("\nPlease input number of generations: ");
scanf("%i", &generation);
playGame(board, generation);
}
void automaticMode(int board[HEIGHT][WIDTH])
{
int i, generation, c;
fillArrayRandomly(board);
display2DArray(board);
printf("\nPlease input number of generations: ");
scanf("%i", &generation);
playGame(board, generation);
}
void hybridMode(int board[HEIGHT][WIDTH])
{
int i, generation, c;
fillArrayRandomly(board);
display2DArray(board);
inputCoordinates(board);
system("cls"); // Clear console.
display2DArray(board);
printf("\nPlease input number of generations: ");
scanf("%i", &generation);
playGame(board, generation);
}
// Main function.
int main(int argc, char *argv[])
{
printf("\nCONWAY'S GAME OF LIFE\n\n");
int h = atoi(argv[1]);
int w = atoi(argv[2]);
if (h) HEIGHT = h;
if (w) WIDTH = w;
printf("Height: %i\nWidth: %i\n\n", HEIGHT, WIDTH);
int board[HEIGHT][WIDTH], mode;
makeBoardLines(board);
fillArray(board);
printf("Please press CTRL+C to terminate the program, press enter to move to the next generation.\n");
printf("Type [1] for User Mode, [2] for Automatic Mode and [3] for Hybrid Mode: ");
scanf("%i", &mode);
if (mode == 1)
userMode(board);
else if (mode == 2)
automaticMode(board);
else if (mode == 3)
hybridMode(board);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment