From 1d8b83da2a84a464e581a50c097f29e98b4622e1 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Thu, 3 Nov 2016 21:42:59 +0100 Subject: gameOfLife --- Makefile | 7 ++- gameOfLife.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 gameOfLife.c diff --git a/Makefile b/Makefile index 378a202..6aeb578 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,11 @@ PREFIX = /usr/local .PHONY: all install -all: temperaturUmrechner matrixMult findMaxOfFloats +all: temperaturUmrechner matrixMult findMaxOfFloats gameOfLife install: mkdir -p $(PREFIX)/bin - install -m 0755 -t $(PREFIX)/bin temperaturUmrechner matrixMult findMaxOfFloats + install -m 0755 -t $(PREFIX)/bin temperaturUmrechner matrixMult findMaxOfFloats gameOfLife mkdir -p $(PREFIX)/share install -m 0644 -t $(PREFIX)/share floats.txt @@ -21,3 +21,6 @@ matrixMult: findMaxOfFloats: $(CC) $(INCLUDES) $(CCFLAGS) -o findMaxOfFloats findMaxOfFloats.c + +gameOfLife: + $(CC) $(INCLUDES) $(CCFLAGS) -o gameOfLife gameOfLife.c diff --git a/gameOfLife.c b/gameOfLife.c new file mode 100644 index 0000000..e016993 --- /dev/null +++ b/gameOfLife.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include + +#define RANDOM_SEED time(NULL) + +typedef enum CellState { DEAD, ALIVE } CellState; + +void printUsage() +{ + printf("usage: gameOfLife [-x ] [-y ] [-d ] [-s ]\n" + " -d sets density of life cells at game start\n" + " -s time to sleep between rounds\n" + ); +} + +void initBoard(CellState* board, unsigned int x, unsigned int y, float density) +{ + float roll; + + srand(RANDOM_SEED); + for (int i = 0; i < x * y; i++) + { + roll = (float)rand()/(float)RAND_MAX; + if (roll <= density) + board[i] = ALIVE; + else + board[i] = DEAD; + } +} + +int boardEq(CellState* a, CellState* b, unsigned int x, unsigned int y) +{ + for (int i = 0; i < x * y; i++) + { + if (a[i] != b[i]) + return 0; + } + + return 1; +} + +void evolve(CellState* board, CellState* newBoard, unsigned int width, unsigned int height) +{ + int liveNeighbours; + CellState* focus; + CellState* newFocus; + + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + { + focus = &(board[y * width + x]); + newFocus = &(newBoard[y * width + x]); + liveNeighbours = 0; + + for (int n = (y <= 0) ? 0 : -1; n <= ((y + 1) >= height ? 0 : 1); n++) + for (int m = (x <= 0) ? 0 : -1; m <= ((x + 1) >= width ? 0 : 1); m++) + { + // fprintf(stderr, "(%d, %d) + (%d, %d)\n", x, y, m, n); // DEBUG + if (board[(y + n) * width + (x + m)] == ALIVE && !(n == 0 && m == 0)) + liveNeighbours++; + } + + if (liveNeighbours == 3) + *newFocus = ALIVE; + else if (*focus == ALIVE && liveNeighbours == 2) + *newFocus = ALIVE; + else + *newFocus = DEAD; + } +} + +void printBoard(CellState* board, unsigned int width, unsigned int height) +{ + void drawHoriz() { + printf("+"); + for (int x = 0; x < width; x++) + printf("-"); + printf("+\n"); + } + + drawHoriz(); + + for (int y = 0; y < height; y++) + { + printf("|"); + for (int x = 0; x < width; x++) + if (board[y * width + x] == ALIVE) + { + printf("X"); + } + else + { + printf(" "); + } + printf("|"); + printf("\n"); + } + + drawHoriz(); +} + +void main(int argc, char* argv[]) +{ + unsigned int x = 16; + unsigned int y = 16; + float d = 0; + float s = 1; + + CellState* board; + CellState* newBoard; + + int c; + + while ((c = getopt(argc, argv, "x:y:d:s:h?")) != -1) + { + switch (c) + { + case 'x': + sscanf(optarg, "%d", &x); + break; + case 'y': + sscanf(optarg, "%d", &y); + break; + case 'd': + sscanf(optarg, "%f", &d); + break; + case 's': + sscanf(optarg, "%f", &s); + break; + case 'h': + case '?': + printUsage(); + exit(EXIT_SUCCESS); + default: + printUsage(); + exit(2); + } + } + + if (d < 0 || d > 1) + { + fprintf(stderr, "Densitiy needs to be in [0;1]\n"); + exit(2); + } + + if (s <= 0) + { + fprintf(stderr, "Sleep interval needs to be greater 0\n"); + exit(2); + } + + board = malloc(sizeof(CellState) * x * y); + newBoard = malloc(sizeof(CellState) * x * y); + + memset(board, DEAD, sizeof(CellState) * x * y); + initBoard(newBoard, x, y, d); + + while (! boardEq(board, newBoard, x, y)) + { + printBoard(newBoard, x, y); + + usleep((int)(s * 1e6)); + + memcpy(board, newBoard, sizeof(CellState) * x * y); + evolve(board, newBoard, x, y); + } + + free(board); + exit(EXIT_SUCCESS); +} -- cgit v1.2.3