20×20 Game of Life in C 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 &lt;stdio.h&gt;
#include &lt;stdbool.h&gt;
#include &lt;string.h&gt;
#include &lt;time.h&gt;
#include &lt;stdlib.h&gt;
//#include &lt;Windows.h&gt;

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

    // fill the desired amount of entries with ones
    srand(time(0));
    for(size_t r = 1; r &lt; rows-1; ++r)
        for(size_t c = 1; c &lt; cols-1; ++c)
            if(rand() / (float)RAND_MAX &lt; 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, rows*cols*sizeof(bool));

    // apply update rules and set some entries to one
    for(size_t r = 1; r &lt; rows-1; ++r)
        for(size_t c = 1; c &lt; 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 &amp;&amp; field[entry])) 
                tmp[entry] = 1;
        }

    // update the actual field
    memcpy(field, tmp, rows*cols*sizeof(bool));
}

void printField(bool field[], const size_t rows, const size_t cols)
{
    for(size_t r = 0; r &lt; rows; ++r) {
        for(size_t c = 0; c &lt; cols; ++c)
            printf("%i", field[r*rows + c]);
        printf("\n");
    }
    printf("\n");
}

int main()
{
    // actual dimensions are (rows-1)*(cols-1), but for convenience
    // we are going to create a border around it filled with zeros
    const size_t rows = 21;
    const size_t cols = 21;
    bool field[rows * cols];

    // initialize the field with ~20% of entries set to 1
    initField(field, rows, cols, 0.2);

    // print and update the field for some iterations
    for(unsigned i = 0; i &lt; 100; ++i) {
        printField(field, rows, cols);
        updateField(field, rows, cols);
        //Sleep(500);
    }

    return 0;
}
//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 &lt; fill)


this:

for(size_t c = 0; c &lt; cols; ++c)


and this:

if(neighbors == 3 || (neighbors == 2 &amp;&amp; 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!