Fully working 2 array version
memcpy() sucks
This commit is contained in:
parent
9d170ee969
commit
aa99670084
2 changed files with 105 additions and 16 deletions
14
README.md
14
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.
|
107
conway.c
107
conway.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue