From aa996700840636084a1911a5498d8c03734d050e Mon Sep 17 00:00:00 2001 From: "A.M. Rowsell" Date: Mon, 29 May 2023 05:49:14 -0400 Subject: [PATCH] Fully working 2 array version memcpy() sucks --- README.md | 14 ++++--- conway.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 105 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 4cb012e..164be3e 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,14 @@ later, and so here we are. Written in C because Python would probably have been too easy. Was considering doing it in C++ so I could take advantage of classes. -Going to try and figure out how to do the "modify in-place" algorithm instead -of the easy way using 2 arrays that you ping-pong between. Still unclear how -you can modify it in-place without destroying information you need when -processing cells further along... have to give it a good think. I mean, I -assume there's a way to do it because this programming website set it as -a challenge. +Currently it uses the 2 array algorithm, copying to a temporary array to process +and then copying back after. + +Going to try and figure out how to do the "modify in-place" algorithm instead. +Still unclear how you can modify it in-place without destroying information +you need whenprocessing cells further along... have to give it a good think. +I mean, I assume there's a way to do it because this programming website set +it as a challenge. Licensed under the Mozilla Public License v2.0 like pretty much all of my code is. Feel free to use it or study it for whatever purpose. \ No newline at end of file diff --git a/conway.c b/conway.c index 0e2f559..801d40b 100644 --- a/conway.c +++ b/conway.c @@ -1,14 +1,37 @@ -#include -#include +/** + * Yet another goddamn implementation of Conway's Game of Life. + * I'm under the impression that every programmer must do this at some point, + * and since I've been programming for a long time I guess I should get it out + * of the way... + * + * (c) 2023 A.M. Rowsell + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ +// so many damn includes #include #include #include #include #include +#include +#include +#include +#include -void printGrid(int gridX, int gridY, int** arr) -{ - // print the array for debugging +void printGrid(int gridX, int gridY, int **arr, int generation) { + char title[16]; + snprintf(title, 16, "Generation %d", generation); + int spaces = ((float)gridX / 2.0F) - (strlen(title) / 2.0); + if (spaces <= 0) { + wprintf(L"%s\n", title); + } else { + for(int i = 0; i < spaces; i++) { + wprintf(L" "); + } + wprintf(L"%s\n", title); + } wprintf(L"%lc", 0x2554UL); // prints ╔ for (int j = 0; j < gridX; j++) { wprintf(L"%lc", 0x2550UL); // prints ═ @@ -31,8 +54,57 @@ void printGrid(int gridX, int gridY, int** arr) return; } -int main(int argc, char* argv[]) -{ +void doGeneration(int gridX, int gridY, int **arr) { + // add up all live cells from [x-1][y-1] to [x+1][y+1] + // if total is 3, cell becomes alive + // if total is 4, cell retains state + // any other, cell dies + // also, all x/y are modulo gridX gridY so we get wraparound + + // temporary array to hold processed generation + int *tempArr[gridX]; + for(int i = 0; i < gridX; i++) { + tempArr[i] = (int *)malloc(sizeof(int)*gridY); + } + for(int i = 0; i < gridX; i++) { + for(int j = 0; j < gridY; j++) { + tempArr[i][j] = arr[i][j]; + } + } + // total keeps track of live neighbours + int total = 0; + for(int i = 0; i < gridY; i++) { + // start of a line + for(int j = 0; j < gridX; j++) { + total = 0; + // start of 9-cell eval + for(int k = -1; k < 2; k++) { + for(int l = -1; l < 2; l++) { + total += (arr[(j+k)%gridX][(i+l)%gridY] == 1) ? 1 : 0; + } + } + if(total == 3) { + tempArr[j][i] = 1; + } else if (total == 4) { + tempArr[j][i] = arr[j][i]; + } else { + tempArr[j][i] = 0; + } + } + } + for(int i = 0; i < gridX; i++) { + for(int j = 0; j < gridY; j++) { + arr[i][j] = tempArr[i][j]; + } + } + // free all that memory + for(int i = 0; i < gridX; i++) { + free(tempArr[i]); + } + return; +} + +int main(int argc, char *argv[]) { if (argc < 3) { printf("Usage: conway [seed]\n"); exit(255); @@ -59,7 +131,7 @@ int main(int argc, char* argv[]) srand(seed); } // dynamically allocate the 2D array, could be quite large! - int* arr[gridX]; + int *arr[gridX]; for (int i = 0; i < gridX; i++) { arr[i] = (int*)malloc(gridY * sizeof(int)); } @@ -69,7 +141,22 @@ int main(int argc, char* argv[]) arr[i][j] = (rand() % 2 == 0) ? 1 : 0; } } - printGrid(gridX, gridY, arr); - + // display initial grid + printGrid(gridX, gridY, arr, generation); + // loop doing gens until user decides to quit + char choice[] = "y"; + while(strcmp(choice, "y") == 0) { + wprintf(L"\n"); + generation++; + doGeneration(gridX, gridY, arr); + printGrid(gridX, gridY, arr, generation); + wprintf(L"\nDo another generation? [y/n]: "); + sprintf(choice, "%c", tolower(getchar())); + getchar(); // consome the newline + } + // clean up allocated memory + for(int i = 0; i < gridX; i++) { + free(arr[i]); + } return 0; }