Question

Now having corrected all of the errors thrown up by GCC, the output is different than before, but still only changes once.

OUTPUT:

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 1 0 0 0

0 0 0 0 0 0 0 1 1 0

0 0 0 0 0 0 0 0 0 1

It stays like this for 40 passes, which it shouldn't

THE NEW (WARNING FREE) CODE:

signed char board [10][10]; //the board
int evaluate_cell (int i, int a);
int evaltheboard(void){
    //loops through the array, and stops to check if there is a living cell. leiving cells are represented by a 1.
    int i,a;
    signed char cell_to_check [1][1];
    for (a=0;a<=9;a++){
        for (i=0;i<=9;i++){
            cell_to_check[0][0] = board[i][a];
            if (cell_to_check[0][0] != 0){
                evaluate_cell(i,a);
            }
        }
    }
    return 0;
}

int evaluate_cell(int i,int a){
    // checks near by cells to see if there are any living and chooses whether the cell should live based off of it's living neighbors.
    signed char live_n_cells = 0, empty_x_mod, empty_y_mod;
    signed char x_inc [8] = {0,1,1,1,0,-1,-1,-1}, y_inc [8]={-1,-1,0,1,1,1,0,-1};
    int z, x, y;
    x=y=0;
    //printf("evaling cell\n");
    //printf ("co-ords being checked [%d][%d]", i,a);
    for (z=0;z<=7;z++){
        if (board[(i+(x_inc[x]))][(a+(y_inc[y]))] != 0){
        ++live_n_cells;
    }
        else if(board[(i+(x_inc[x]))][(a+(y_inc[y]))] == 0){
            empty_x_mod = i-(x_inc[x]) ;
            empty_y_mod = a-(y_inc[y]);
        }
        y++;
        x++;
    }
    //printf("%d = z, %d = y, %d = x\n", z, y, x);//debug 
    //printf("|close living cells = %d\n", live_n_cells); // debug
    //printf("|empty mods are %d %d\n", empty_x_mod, empty_y_mod); //debug
    if (live_n_cells >= 3){
        board[i][a] = 0;
    }
    else if (live_n_cells == 0){
    board[i][a] = 0;
    }
    else if (live_n_cells == 1 || 2){
        board[empty_x_mod][empty_y_mod] = 1;
    }
    return 0;

}

int print_array(void){
    //prints array
    int i,a;
    for (a=0;a<=9;a++){
        for (i=0;i<=9;i++){
            printf(" %d", board[i][a]);
            //printf("%d", i);
        }

        printf("\n");
    }
    printf("----------\n");

    return 0;
}

int main(void){
    int x;
    //runs the damned thing
    board[5][5] = 1; //DEBUG
    board[5][6] = 1; //DEBUG
    board[6][5] = 1; //DEBUG
    for (x=0;x<40;x++){
        evaltheboard();
        print_array();
    }
    return 0;

}

OLD QUESTION:

Like the title says, i am having some unexpectedly stagnant output. The program should function like Conway's Game of Life. When i run this version, it changes the 'board' array once and doesn't seem to do it again. the out put ends up looking like this (0 = empty cell, 1 = living cell):

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 1 0 0 0 0

0 0 0 0 0 1 0 1 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 1 0 0

0 0 0 0 0 0 0 0 0 0

So in theory, the two adjacent ones should have re-populated and the isolated ones should have died off, but they didn't. Any help into why this would be would be met with thanks.

Please don't be too harsh, this is my first actually project in c that I have written from the ground up. Any feed back on my general form of code would be appericieated

THE CODE:

signed char board [10][10]; //the board
int evaltheboard(void){
    //loops through the array, and stops to check if there is a living cell. living cells are represented by a 1.
    int i,a;
    signed char cell_to_check [1][1] = {0};
    for (a=0;a<=9;a++){
        for (i=0;i<=9;i++){
            cell_to_check[0][0] = board[i][a];
            if (cell_to_check[0][0] != 0){
                evaluate_cell(i,a);
            }
        }
    }
    return 0;
}

int evaluate_cell(int i,int a){
    // checks near by cells to see if there are any living and chooses whether the cell should live based off of it's living neighbors.
    signed char live_n_cells = 0, empty_x_mod, empty_y_mod;
    signed char x_inc [8] = {0,1,1,1,0,-1,-1,-1}, y_inc [8]={-1,-1,0,1,1,1,0,-1};
    int z, x, y;
    x=y=0;
    //printf("evaling cell\n");
    //printf ("co-ords being checked [%d][%d]", i,a);
    for (z=0;z<=7;z++){
        if (board[(i+(x_inc[x]))][(a+(y_inc[y]))] != 0){
        ++live_n_cells;
    }
        else(board[(i+(x_inc[x]))][(a+(y_inc[y]))] == 0);{
             empty_x_mod = i-(x_inc[x]) ;
             empty_y_mod = a-(y_inc[y]);
        y++;
        x++;
        }
    }
    //printf("%d = z, %d = y, %d = x\n", z, y, x);//debug 
    //printf("|close living cells = %d\n", live_n_cells); // debug
    //printf("|empty mods are %d %d\n", empty_x_mod, empty_y_mod); //debug
    if (live_n_cells >= 3){
        board[i][a] = 0;
    }
    else if (live_n_cells = 0){
    board[i][a] = 0;
    }
    else(live_n_cells = 1 || 2);{
        board[empty_x_mod][empty_y_mod] = 1;
    }
    return 0;

}

int print_array(void){
    //prints array
    int i,a;
    for (a=0;a<=9;a++){
        for (i=0;i<=9;i++){
            printf(" %d", board[i][a]);
            //printf("%d", i);
        }

        printf("\n");
    }
    printf("----------\n");

    return 0;
}

int main(void){
    int x;
    //runs the damned thing
    board[5][5] = 1; //DEBUG
    board[5][6] = 1; //DEBUG
    board[6][5] = 1; //DEBUG
    for (x=0;x<40;x++){
        evaltheboard();
        print_array();
    }
    return 0;

}

note: the printf's with //'s in front of them are for debugging only, and the forloop in main is only temporary. i plan to do a while that checks if any thing is still alive later. if it says //DEBUG afterwards, it is also temporary.

anyway, Thanks!

Was it helpful?

Solution

There are a few things you need to look at in your code. The best thing you could do is enable compiler warnings, if you are using gcc add the -Wall (warn all) flag to the compile line, so to compile use:

gcc -Wall source.c -o Program

Most compilers support some sort of warning flag/option. When I compiled your code with this flag I got the following output (trimmed a bit):

7:5: warning: missing braces around initializer [-Wmissing-braces]
     signed char cell_to_check [1][1] = {0};

31:13: warning: statement with no effect [-Wunused-value]
         else(board[(i+(x_inc[x]))][(a+(y_inc[y]))] == 0);{

44:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     else if (live_n_cells = 0){

12:17: warning: implicit declaration of function ‘evaluate_cell’ [-Wimplicit-function-declaration]
             evaluate_cell(i,a);

When I went through and fixed these issues, the compiler provided more issues, but eventually you should have a nice warning free program (suggesting that your code might be correct).

The first warning above is because you are trying to assign an array with one element to a variable which expects an array of and array with one element.

The second warning above is because you are missing an if after your else, so this should be else if (...), however something else you should note is that you have a ; before the curly brackets, this probably shouldn't be there at all, you should go through your code an make sure you don't have extra ;s before curlly brackets.

The third warning is probably because you are making an assignment live_n_cells = 0 instead of checking live_n_cells == 0. If you actually meant to make the assignment, then write (live_n_cells = 0). A good way to avoid every accidently making assignments is to use 0 == live_n_cells, this way if you forget the second equals sign you never make an assignment.

The fourth warning is about a missing declaration of your function. to resolve this, you can add something like int evaluate_cell(int i,int a); to the top of your source file.

Try these things and then post an update to your question (these tips may even help to solve your problem).

EDIT:

A few more tips:

Functions can be declared as void, which means that they don't return a value. This could be useful in your program since evaluate_cell currently returns 0, which you simply ignore. You could instead write void evaluate_cell(int i, int j), but remember to change the declaration at the top of your source file too.

I went over your reproduction code, it doesn't seem to contain all the Game of Life operations (at least according to the Wikipedia page http://en.wikipedia.org/wiki/Conway's_Game_of_Life), try the following:

if (live_n_cells == 3 && board[i][a] == 0) {  // production
    temp_board[i][a] = 1;
} else if (live_n_cells > 3) {                // over population
    temp_board[i][a] = 0;
} else if (live_n_cells < 2) {                // under population
    temp_board[i][a] = 0;
} else {                                      // reproduction
    temp_board[i][a] = board[i][a];
}

And also call your evaluate cell routine for all cells, not just the currently alive cells. You also probably notice the use of the variable temp_board in the above code. This is related to the comment posted by aschepler on your question. I also changed the definition of the board to the following, the +2 is padding to make sure you never try to access elements outside the array.

#define WIDTH 10
#define HEIGHT 10

signed char board [HEIGHT+2][WIDTH+2];      ///< the board
signed char temp_board [HEIGHT+2][WIDTH+2]; ///< temporary board

Finally, I changed the code in evaluateboard to:

int i, j;     ///< loop counters

// Evaluate each cell in array
for (j=1; j<=HEIGHT; j++) {
    for (i=1; i<=WIDTH; i++) {
        evaluate_cell(j,i);
    }
}

// copy temp_board into board
for (j=1; j<=HEIGHT; ++j) {
    for (i=1; i<=WIDTH; ++i) {
        board[j][i] = temp_board[j][i];
    }
}

Using most of your code, with the above few tweaks, I managed to get Conway's Game of Life running with the expected results.

One final tip, it is usually the convention in C/C++ to use i, j, k, l, m, n (often in that order) as your loop counting variables.

Good luck. :)

OTHER TIPS

There are some bugs in evaluate_cell.

First, when you check around a cell on the border, you access areas outside the board. You need to check if a surrounding cell is outside the board!

Second, you use assignment instead of comparison in your if statements. You probably mean:

else if (live_n_cells == 0){  // = is assignment, == is equality

The else should probably be:

else {  // Only way to get here is if live_n_cells is 1 or 2, so no need for a condition.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top