Fully working 2 array version

memcpy() sucks
This commit is contained in:
A.M. Rowsell 2023-05-29 05:49:14 -04:00
commit aa99670084
Signed by: amr
GPG key ID: 0B6E2D8375CF79A9
2 changed files with 105 additions and 16 deletions

View file

@ -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.

107
conway.c
View file

@ -1,14 +1,37 @@
#include <locale.h>
#include <math.h>
/**
* 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <wchar.h>
#include <locale.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
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 <xsize> <ysize> [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;
}