i wrote this code for a simple life game loosely based on Conway's. I wrote an 40x40 integer matrix with random numbers and a 40x40 char matrix based on the previous one, where the numbers 0 to 3 generate an X (alive cell) and the numbers upper 4 generate an . (dead cell). There's two functions in the ´program, geracao (applys the conditions of life game) and imprimirmatriz (prints the new char matrix after applyed conditions). I'm having problems with implementation of the conditions of the game. I tryed to define the 8 possible neighbours of a cell but when trying to define the conditions the instructions it's been too long. Anyone suggest how to rewrite the red part with a not so messy code. Thanks.

``````#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
//Define the 8 possíbles neighbours of a cell
#define V1 (B[i-1][j])
#define V2 (B[i][j+1])
#define V3 (B[i+1][j])
#define V4 (B[i][j-1])
#define V5 (B[i-1][j-1])
#define V6 (B[i-1][j+1])
#define V7 (B[i+1][j-1])
#define V8 (B[i+1][j+1])

//Define conditions
//Condition 1: All neighbours are alive (X)
//Condição 2: Any three neighbours are alive (X)
//Condição 3: Two any neighbours are alive (X)

#define COND1 (V1==V2==V3==V4==V5==V6==V7==V8=='X')
#define COND2 (V1==V2==V3=='X') || (V1==V2==V4=='X') || (V1==V2==V5=='X') || (V1==V2==V6=='X') || (V1==V2==V7=='X') || (V1==V2==V8=='X') || (V2==V3==V4=='X') || (V2==V3==V5=='X') || (V2==V3==V6=='X') || (V2==V3==V7=='X') || (V2==V3==V8=='X') || (V3==V4==V1=='X') || (V3==V4==V5=='X') || (V3==V4==V6=='X') || (V3==V4==V7=='X') || (V3==V4==V8=='X') || (V3==V5==V1=='X')
#define COND3 (V1=='X' && V2=='X') || (V1=='X' && V3=='X') || (V1=='X' && V4=='X') || (V2 == 'X' && V3 == 'X') || (V2 == 'X' && V4 == 'X') || (V3 == 'X' && V4 == 'X')
#define COND4 (V1=='X' && V2=='X' && V3=='X' && V4=='X')

//Global variables
int i,j,match=0; // Initialize the variables i,j (row and column) and match
int A; // Define the 40x40 integer matrix
char B; // Define the 40x40 char matrix

int main()
{

printf("Este codigo trabalha apenas com matrizes LIFE quadradas de 40x40:\n");
//This code only works with square matrix dimension 40.

printf("\nMatriz LIFE:\n\n");
srand(time(NULL));  //Activate function srand
for(i = 0; i < 40; i++)  //loop - i to 40
{
for(j = 0; j < 40; j++) //loop - j to 40
{
A[i][j] = rand() % 10;  // Aij value is between 0 and 9
printf("%1d", A[i][j]);  // Print each Aij
if(j==39) printf("\n"); // Organize the matrix
}

}
printf("\n");
printf("\n");
for(i = 0; i < 40; i++)  //loop - i to 40
{
for(j = 0; j < 40; j++) //loop - j to 40
{
if (A[i][j]<=3) B[i][j] = 'X';   //X for alive cells
else B[i][j] = '.'; // . for dead cells
printf("%1c", B[i][j]); // Print . or X
if(j==39) printf("\n"); // Organize the matrix
}

}
printf("\n");

geracao();   //Calls function geracao
imprimirmatriz(); //Calls function imprimirmatriz
getch();

}

//Funçtion geração - apply the necessary conditions.
int geracao(void)
{
printf("A funcao geracao aplica as condicoes de sobrevivencia\n");

}

//Function imprimir matriz (print the matrix after the geracao function)
int imprimirmatriz(void)
{
printf("A funcao imprimirmatriz imprime a nova matriz B após a aplicação das condicoes da geracao\n");
printf("\n");
printf("\n");
for(i = 0; i < 40; i++)  //Loop - i to 40
{
for(j = 0; j < 40; j++) //Loop - j to 40
{
printf("%1c", B[i][j]);
if(j==39) printf("\n");
}
}
}``````

My suggestions:

1) change the value for alive or dead to 1 or 0. The printout can easily show a dot for 0, and 'X' for alive.

2) Delete the defines in red.

3) Instead of 'V1', etc., name your directions something you can intuitively associate with the 8 directions: maybe D1-D8, or D1, D3, ... D12. Indicating the approx. hour hand of the clock, (with you in the center), as it faces that direction.

Definitely, arrange your D's, so they work in order, from 12 or 1 o'clock to 10 or 12 o'clock, in a clockwise direction. Why clockwise? It's in ascending order, by hour. And I say so. ;)

4) I would prefer the D's was an array, rather than 8 different variables. Now you just count up the neighbors status, with a for loop:

``````for(i=0,alive=0;i<8;i++,D++) {
if(grid[D]])
alive++;  //alive is an int
}``````

Unfortunately, I don't know a clever way to make D increment to E (and thus become a new direction in a define statement), in C. Defines don't handle that in compiled languages, AFAIK.

So you're left with 8 if statements:

``````if(grid[D1] alive++;
if(grid[D2] alive++;
//...

if(alive>2)  //do something``````

Long involved defines are a witch to work with, down the road. Keep them short, direct, and clear.

Try to avoid being too clever. Whoever works on your program next, will have to be even more clever to extend or debug it, making it difficult indeed.