#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); }