HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

20×20 Game of Life in C

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
lifegamestackoverflow

Problem

I am new to C, but have experience with Python and R. The following code implements the Game of Life and represents my first finger exercise in C. I would like to have some feedback regarding the coding style and conventions in the C community. (I commented out the two Windows specific lines, in case someone wants to run it on another operating system)

```
//gcc -Wextra -Wall -Werror -O3 -march=native -std=c99 -o test.exe gameOfLife.c

#include
#include
#include
#include
#include
//#include

void initField(bool field[],
const size_t rows,
const size_t cols,
const float fill)
{
// fill everything with zeros
memset(field, 0, rowscolssizeof(bool));

// fill the desired amount of entries with ones
srand(time(0));
for(size_t r = 1; r < rows-1; ++r)
for(size_t c = 1; c < cols-1; ++c)
if(rand() / (float)RAND_MAX < fill)
field[r*rows + c] = 1;
}

unsigned countNeighbors(bool field[], const size_t rows, const size_t entry)
{
return field[entry-rows-1] + field[entry-rows] + field[entry-rows+1] +
field[entry-1] + field[entry+1] +
field[entry+rows-1] + field[entry+rows] + field[entry+rows+1];
}

void updateField(bool field[], const size_t rows, const size_t cols)
{
// create a new field filled with zeros
bool tmp[rows * cols];
memset(tmp, 0, rowscolssizeof(bool));

// apply update rules and set some entries to one
for(size_t r = 1; r < rows-1; ++r)
for(size_t c = 1; c < cols-1; ++c) {
size_t entry = r*rows + c;
unsigned neighbors = countNeighbors(field, rows, entry);
// update entry based on neighbors
if(neighbors == 3 || (neighbors == 2 && field[entry]))
tmp[entry] = 1;
}

// update the actual field
memcpy(field, tmp, rowscolssizeof(bool));
}

void printField(bool field[], const size_t rows, const size_t co

Solution

//gcc -Wextra -Wall -Werror -O3 -march=native -std=c99 -o test.exe gameOfLife.c


This should probably be put into some Makefile (well... the Makefile can be written more idiomatically, but I'm not the person to really ask about Makefiles...)

srand(time(0));


There may be better alternatives to this as a random number generator. This answer seems to suggest that Mersenne Twisters produce higher quality pseudo random numbers and that it is faster. However, informally speaking Mersenne Twisters are no longer consider "high quality enough".

To clarify, I am suggesting the alternative not so much because the output is a "higher quality" random number, but because of speed concerns.

This:

if(rand() / (float)RAND_MAX < fill)


this:

for(size_t c = 0; c < cols; ++c)


and this:

if(neighbors == 3 || (neighbors == 2 && field[entry]))


They all don't use braces. Please use braces. To put this in to context, there was a OpenSSL bug in Mac OSX. IF they had used braces, the double goto fail would not have mattered*. It caused a lot of issues. So I would advise at the very least you put the statements on the same line if you don't use brackets.

* Well, it could have mattered, but autocompletion of brackets in an IDE would mitigate the chances. Better safe than sorry!

Code Snippets

//gcc -Wextra -Wall -Werror -O3 -march=native -std=c99 -o test.exe gameOfLife.c
srand(time(0));
if(rand() / (float)RAND_MAX < fill)
for(size_t c = 0; c < cols; ++c)
if(neighbors == 3 || (neighbors == 2 && field[entry]))

Context

StackExchange Code Review Q#145894, answer score: 2

Revisions (0)

No revisions yet.