Related
I have a text file that contains numbers like below:
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
23,10,5,7,8,9,10,1,2,5
I am trying to read all those values into a two-dimensional array using the C programming language. The first line reads into the array successfully, but the rest of the values are 0s.
How can I debug where the problem is?
Below is the code I am using:
#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int main() {
//create a new file pointer
FILE* myfile = fopen("matrixA.csv", "r");
//define the dimensions of our multidimensional array
const int ROWS = 10;
const int COLS = 10;
//allocate memory to our array
int array[ROWS][COLS];
//intialize all members of the array to zero
memset(array, 0, sizeof(array));
//check if the file is null
if (myfile == NULL) {
printf("%s", "The file does not exist");
//return an exit code to the operating system
return EXIT_FAILURE;
}
//the file is real, read from it and enter its values into the matrix
//array
for (int row = 0;row < ROWS;row++) {
for (int col = 0;col < COLS;col++) {
if (fscanf(myfile,"%d,", &array[row][col]) != 1) {
//return an exit code to the operating system
printf("%s\n", "The scan of some components of this file was unsuccessful");
return EXIT_FAILURE;
}
}
//for every member of this array, print them out
for (int i = 0;i < ROWS;i++) {
for (int j = 0;j < COLS;j++) {
printf("%d ", array[i][j]);
}
//break a row when a row is complete
printf("\n");
}
return 0;
}
}
The output I am getting when I run my code on the terminal is like below after printing out the elements of the array which is incorrect.
23 10 5 7 8 9 10 1 2 5
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 0 0 0 0
0 0 0 0 0 0 0 0 0 0
How do I make my code read all the values of the file into the two-dimensional array successfully?
Firstly, please close your file.
Secondly, the fscanf() does not read consecutive lines as expected. Finding more information in this: https://learn.microsoft.com/vi-VN/troubleshoot/developer/visualstudio/cpp/libraries/fscanf-does-not-read-consecutive-line
Somehow, you've moved output statements into reading loops. Moving them out should fix it.
//the file is real, read from it and enter its values into the matrix
//array
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (fscanf (myfile, "%d,", &array[row][col]) != 1) {
//return an exit code to the operating system
printf ("%s\n", "The scan of some components of this file was unsuccessful");
return EXIT_FAILURE;
}
}
}
//for every member of this array, print them out
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++)
printf ("%d ", array[i][j]);
//break a row when a row is complete
printf ("\n");
}
return 0;
Also, you're mixing C++ with C:
#include <stdio.h>
#include <stdlib.h> // <cstdlib>
#include <string.h>
//#include <iostream>
//using namespace std;
There is no need to memset()
//memset (array, 0, sizeof (array));
As already pointed out, it's better to read the whole line from input file and extract matrix elements from it. This gives you more control to validate input file for erroneous data.
there was text data instead of numbers
insufficient/excess columns/fields specified on a line
I allocated matrix like this :
prevMatrix = (int**)malloc(sizeof(int) * arraySize[0]);
for (int i = 0; i < arraySize[0]; i++) {
prevMatrix[i] = (int*)malloc(sizeof(int) * arraySize[1]);
}
I checked arraySize[] has normal value. arraySize[0] means row, and arraySize[1] means column.
and I handed over the matrix like this :
void getInputMatrix(FILE* input, int column, int** matrix)
getInputMatrix(input, arraySize[1], prevMatrix);
and then function's body is this :
void getInputMatrix(FILE* input, int column, int** matrix) {
int i = 0, j = 0, c = 0;
while (!feof(input)) {
if (j == column) {
j = 0;
i++;
}
c = fgetc(input);
if (c != EOF && c != 32 && c != 10 && c != 13) {
matrix[i][j] = c - 48;
j++;
}
}
}
this is the example of matrix file:
1 0 0 0 0 0 0
0 1 0 1 0 0 0
0 1 0 0 1 1 0
0 1 1 1 0 0 0
0 0 0 0 1 0 0
0 1 0 0 0 1 0
1 0 1 1 0 0 0
0 1 0 0 0 0 1
It works very well in VS 2019, but it cause segmentation fault in Linux system(Ubuntu).
This program works well in Linux till the column is 6 or 7, but it occurs corrupted size vs. prev_size error or segmentation faultwhen the column overs that number.
Is it a problem of allocation? or fgetc()?
How can I fix it?
For starters, your first level allocation should be using the size of an int pointer rather than an int:
int **prevMatrix = malloc(sizeof(int*) * arraySize[0]);
If those types are different sizes, your original code could have a problem.
And, just as an aside, you should not cast the malloc return value in C, it can cause subtle problems.
My input looks like this :
15 5
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
0 1 0 1 0
0 0 1 0 0
0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
1 0 0 0 1
0 0 1 0 0
0 0 0 1 0
The first row contains the number of rows and columns of my array. And basically I want to find out where these 1s are in the array.
So in the first 3 rows i want to get 3, in the 7th 1, and in the 8th, i want to get 2 3 etc..
My code looks like this so far
#include <stdio.h>
int main() {
int row, column;
FILE* input;
FILE* output;
input = fopen("input.txt", "r");
if (input == 0) {
printf("ERROR couldn't open input.txt");
return 1;
}
if (! fscanf(input, "%d %d", &row, &column)) {
printf("ERROR not recognised value");
fclose(input);
return 2;
}
output = fopen("output.txt", "w");
int meteor[row][column];
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
fscanf(input, "%d", &meteor[i][j]);
}
}
int sum;
int loc[row];
for (int i = 0; i < row; i++) {
sum = 0;
for (int j = 0; j < column; j++) {
sum += meteor[i][j];
if (meteor[i][j] == 1) {
loc[i] = (j + 1);
}
}
printf("%d %d\n", loc[i], sum);
}
fclose(input);
fclose(output);
return 0;
}
My output is this :
3 1
3 1
3 1
0 0
-1 0
1 1
4 2
3 1
5 1
0 0
4214921 0
2 1
5 2
3 1
4 1
The first column shows some of the locations, the second shows how many 1s are in the row, but it all fails when there are only 0s in the row or there is more than one 1. And also I would like to store these values.
You need to initialize loc[].. If you look carefully at your code, you only populate it on the condition of if (meteor[i][j] == 1)... but you print it for every index of i. which would print uninitialized memory (i.e. unknown).
To answer the second part of your question, if you want to store the "sum". Simply make loc[] a 2d array just like meteor, but with 2 columns (row and sum). i.e. int loc[row][2].. making sure to initialize both columns of course :)
I am trying to write a function which gets a matrix 9x9 and updates it accordingly to user's input with the following rules:
Valid number is between 1 and 9 (zero is invalid).
I have to use scanf until I get EOF.
Input has digits and symbols. valid input is a pair of two digits following with a symbol or EOF or space. string with more than two digits is invalid. for example (123% isn't valid but 12% is valid).
Example:
Input: 10 33%55^21 $123%
Output:
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
0 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 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
Explanation: 10 and 123 are invalid. 33, 55 and 21 are valid so we will put 1 in 22, 44 and 10.
What I tried to do:
void updateMarix(int matrix[][9]) {
int digits = 0, one_previous, two_previous;
char input;
while (scanf("%c", &input) != EOF) {
if(isValidDigit(input)) {
digits++;
if(digits == 1) {
two_previous = input - '0' - 1;
continue;
} else if(digits == 2){
one_previous = input - '0' -1;
continue;
}
} else if(digits == 2) {
matrix[two_previous][one_previous]++;
}
digits = 0; // reset
}
}
most tests are end with success, but some of them are fail. I think that is because I don't handle with the last input (if for example it ends with 22 it won't update it because with my implementation, the update is in the next iteration when other symbol got as input).
Is there a better implementation for this? My code became messy and not clean.
*Edit: It should ignore invalid input and a3b doesn't counts, a03b also doesn't counts but a13b does counts as 13 meaning we should increase the number in matrix[0][2].
Edit 2: #JonathanLeffler menationed FSM so I tried to create one:
Although it doesn't handles the case of 1234 (invalid number) or 123 (also invalid). The most similar thing was to create an arrow from second number to symbol (but it isn't quite true because in 1234%12 only 12 is valid.
I think your FSM needs 4 states plus the end state:
Zero digits read (D0).
One digit read (D1).
Two digits read (D2).
Digits are invalid but no more error reporting needed (DI).
There are 4 different inputs, too:
Digit 1-9.
Digit 0.
Other.
EOF.
I've used a switch on state and if/else code in each state, but it leads to somewhat verbose code. OTOH, I believe it handles inputs correctly.
/*
** FSM
** States: 0 digits (D0), 1 digit (D1), 2 digits (D2), digits invalid (DI)
** Inputs: digit 1-9 (D), digit 0 (0), other (O), EOF.
** Action: S - save, E - error, I - ignore, P - print
** Body of FSM encodes "action;state"
**
** State D0 D1 D2 DI
** Input
** D S;D1 S;D2 E;D2 I;DI
** O I;D0 E;D0 P;D0 I;D0
** 0 E;D2 E;D2 E;D2 I;DI
** EOF I;end E;end P;end I;end
*/
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
enum State { D0, D1, D2, DI };
enum Input { Digit, Zero, Other, End };
static int debug = 0;
static enum Input input(int *rv)
{
int c = getchar();
if (debug)
printf("Input: %c\n", (c == EOF) ? 'X' : c);
*rv = c;
if (c == EOF)
return End;
if (isdigit(c))
{
*rv = c - '0';
return (c == '0') ? Zero : Digit;
}
return Other;
}
static void updateMatrix(int matrix[9][9])
{
char pair[2] = { 0, 0 };
enum State state = D0;
int c;
enum Input value;
while ((value = input(&c)) != End)
{
switch (state)
{
case D0:
if (value == Digit)
{
pair[0] = c;
state = D1;
}
else if (value == Zero)
{
fprintf(stderr, "Received zero digit - invalid\n");
state = DI;
}
else
{
assert(value == Other);
}
break;
case D1:
if (value == Digit)
{
pair[1] = c;
state = D2;
}
else if (value == Zero)
{
fprintf(stderr, "Received zero digit - invalid\n");
state = DI;
}
else
{
assert(value == Other);
fprintf(stderr, "Received one digit where two expected\n");
state = D0;
}
break;
case D2:
if (value == Digit)
{
fprintf(stderr, "Received more than two digits where two were expected\n");
state = DI;
}
else if (value == Zero)
{
fprintf(stderr, "Received zero digit - invalid\n");
state = DI;
}
else
{
assert(value == Other);
printf("Valid number %d%d\n", pair[0], pair[1]);
matrix[pair[0]-1][pair[1]-1] = 1;
state = D0;
}
break;
case DI:
if (value == Other)
state = D0;
break;
}
}
if (state == D2)
{
printf("Valid number %d%d\n", pair[0], pair[1]);
matrix[pair[0]-1][pair[1]-1] = 1;
}
else if (state == D1)
fprintf(stderr, "Received one digit where two expected\n");
}
static void dump_matrix(const char *tag, int matrix[9][9])
{
printf("%s:\n", tag);
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
printf("%4d", matrix[i][j]);
putchar('\n');
}
}
int main(void)
{
int matrix[9][9] = { 0 };
updateMatrix(matrix);
dump_matrix("After input", matrix);
return 0;
}
On your test input, it produces the output:
Received zero digit - invalid
Valid number 33
Valid number 55
Valid number 21
Received more than two digits where two were expected
After input:
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
0 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 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
On the mostly-invalid input file:
123345132
bbbb12cccc1dddd011dd
it produces the output:
Received more than two digits where two were expected
Valid number 12
Received one digit where two expected
Received zero digit - invalid
After input:
0 1 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 0 0 0
You can argue (easily) that the error messages could be more informative (identifying the erroneous character, and possibly the prior valid digits), but it only produces one error message for each invalid sequence, which is beneficial.
You could use a combination of fgets(), sscanf() and strpbrk() for this.
The input line is read into a character array str and a pointer ptr pointing to the part of the string in str being processed is maintained.
First, set up a loop to read input line by line. fgets() will return NULL on EOF.
for(; fgets(str, sizeof(str), stdin); )
{
...
...
...
}
fgets() will read in the trailing newline as well. You could remove it like
str[strlen(str)-1]='\0';
Now inside the above loop, use another loop to process the input line in str like
for(ptr=str; (ptr=strpbrk(ptr, "0123456789"))!=NULL; ptr+=len)
{
sscanf(ptr, "%d%n", &n, &len);
if(n>10 && n<100)
{
//accepted
printf("\n%d", n);
arr[n/10][n%10]=1;
}
//else discarded
}
strpbrk()'s prototype is
char *strpbrk(const char *s1, const char *s2);
and it returns a pointer to the first character in s1 which is a character in the string s2. If there is no match, NULL is returned.
So we are looking to see the first digit part in str that remains to be processed with strpbrk(ptr, "0123456789").
This number part is read into n via sscanf(). If this number is in the range you need, you may accept it.
The %n format specifier is used to find out the number of characters which has been scanned with the sscanf() inorder to find the value by which ptr must be updated. See this post.
The digit in the ones place will be n%10 and that in the tens place will be n/10 as the number you need is a 2-digit number.
You may set your array representing the matrix like
arr[n/10][n%10]=1;
So the whole thing could look something like
char *ptr, str[50];
for(; fgets(str, sizeof(str), stdin); )
{
for(ptr=str, str[strlen(str)-1]=0; (ptr=strpbrk(ptr, "0123456789"))!=NULL; ptr+=len)
{
sscanf(ptr, "%d%n", &n, &len);
if(n>10 && n<100)
{
printf("\n%d", n);
arr[n/10][n%10]=1;
}
}
}
And for your input 10 33%55^21 $123%, the output would be
33
55
21
as 10 and 123 will be discarded.
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!
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. :)
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.