C program

smbee

Recruit
Hi.. I need two suggestion for this code. This is based on the famous game of life. I want to add two things in this code:

1) I want to get the matrix size in the command line.
2) The program will stop if two generation will yield the same result.

I have tried. But could not introduce these two in the code.

Thanks!
Code:
#include <stdio.h>
#define HEIGHT 5
#define WIDTH 5
#define ALIVE 1
#define DEAD 0

typedef int TableType[HEIGHT][WIDTH];

void printTable(TableType table) {
        int height, width;

        for (height = 0; height < HEIGHT; height++) {
                for (width = 0; width < WIDTH; width++) {
                        if (table[height][width] == ALIVE) {
                                printf(" X ");
                        } else {
                                printf(" 0 ");
                        }
                }
                printf("\n");
        }
        printf("\n");
}

//to clear up everything

void clearTable(TableType table) {
        int height, width;
        for (height = 0; height < HEIGHT; height++) {
                for (width = 0; width < WIDTH; width++) {
                        table[height][width] = DEAD;
                }
        }
}

void askUser(TableType tableA) {
        int i;
        int n;
        int height, width;

        printf("Enter the amount of initial organisms: ");
        scanf("%d", &n);
        for (i = 0; i < n; i++) {
                printf("Enter dimensions (x y) where organism %d will live: ", i + 1);
                scanf("%d %d", &height, &width);
                tableA[height][width] = ALIVE;
        }
        
        printTable(tableA);
        printf("Generation 0");
}
int getNeighborValue(TableType table, int row, int col) {
        if (row < 0 || row >= HEIGHT 
                || col < 0 || col >= WIDTH
                || table[row][col] != ALIVE )
        { 
                return 0;
        } else {
                return 1;
        }
}
int getNeighborCount(TableType table, int row, int col) {
        int neighbor = 0;

        neighbor += getNeighborValue(table, row - 1, col - 1);  //top left
        neighbor += getNeighborValue(table, row - 1, col);  //top
        neighbor += getNeighborValue(table, row - 1, col + 1);  //top right
        neighbor += getNeighborValue(table, row, col - 1);  //left
        neighbor += getNeighborValue(table, row, col + 1);  //right
        neighbor += getNeighborValue(table, row + 1, col - 1);  //below left
        neighbor += getNeighborValue(table, row + 1, col);   // below
        neighbor += getNeighborValue(table, row + 1, col + 1);  //below right
        
        return neighbor;
}

void calculate(TableType tableA) {
        TableType tableB;
        int neighbor, height, width;

        for (height = 0; height < HEIGHT; height++) {
                for (width = 0; width < WIDTH; width++) {
                        neighbor = getNeighborCount(tableA, height, width);
                        if (neighbor==3) {
                                tableB[height][width] = ALIVE;
                        } else if (neighbor == 2 && tableA[height][width] == ALIVE) {
                                tableB[height][width] = ALIVE;
                        } else {
                                tableB[height][width] = DEAD;
                        }
                }
        }

        for (height = 0; height < HEIGHT; height++) {
                for (width = 0; width < WIDTH; width++) {
                        tableA[height][width] = tableB[height][width];
                }
        }
}

// user entry is a pain for testing
// here's some code to load test data
void loadTestData(TableType table) {
        
        table[1][2] = ALIVE;
        table[1][3] = ALIVE;
        table[2][2] = ALIVE;
        table[2][4] = ALIVE;
        table[3][1] = ALIVE;
        table[3][4] = ALIVE;
        //table[11][6] = LIFE_YES;
        //table[12][5] = LIFE_YES;
}

int main(void) {
        TableType table;
        int generation = 0;
        int maxgen,i;
        clearTable(table);
        // askUser(table);
        loadTestData(table);
        printTable(table);
        
        printf("The no. of generations to be calculated: ");
        scanf("%d", &maxgen);
        
        for (i=0; i<maxgen; i++)
        {
                calculate(table);
                printTable(table);
                printf("Generation %d\n", ++generation);
        } 
        return 0;
}
 
To get the matrix size in command line, you will need to use scanf() in main()
judging by the code, you can do it yourself.

Now since the matrix size is not known before compilation, you need to use dynamic memory allocation for storing the matrix data.

instead of
Code:
typedef int TableType[HEIGHT][WIDTH];
you need to use
Code:
int *table;
table = (int *)malloc(cmdlineWidth*cmdlineHeight*sizeof(int));
where cmdlineWidth and cmdlineHeight are inputs from the command line.

now instead of a 2D array, you have a 1D array which requires change in adressing.

eg.

instead of
Code:
void clearTable(TableType table) {
        int height, width;
        for (height = 0; height < HEIGHT; height++) {
                for (width = 0; width < WIDTH; width++) {
                        table[height][width] = DEAD;
                }
        }
}

you need to use
Code:
void clearTable(int *table, int cmdlineHeight, int cmdlineWidth) {
        int height, width;
        for (height = 0; height < cmdlineHeight; height++) {
                for (width = 0; width < cmdlineWidth; width++) {
                        [B]table[cmdlineHeight*height + width] = DEAD;
                        //or
                        //*table++ = DEAD;[/B]
                }
        }
}

you can use any one of the lines in bold but not both.
try and understand how the *table based 1D array is adressed as a 2D array using cmdlineHeight*height + width
use these changes everywhere your 2D TableType is accessed.

To stop the program if two generations yield the same result is very easy in your code.
You are already making a copy of the next generation before replacing the current generation in void calculate() function.
you just need to compare each value of tableA against tableB before the last copying for-loop.
As pointed above, you will need to use dynamic-memory allocation for tableB too.
 
Back
Top