This is based on John Conways Game of Life, a simple yet awesome code that simulates life.
Rules are simple, if a cell has less then 1 or more then 4 living cells next to it, the cell dies.
An empty cell with exactly 3 living cells next to it becomes alive itself.
My code seems to murder the whole scene... I'm probably wrong somewhere in lines 49 to 70.

package igrazivota;

import java.util.Random;
import java.util.Scanner;

public class IgraZivota {

    public static void main(String[] args) {

        int iterationNumber;
        int chance;
        int limit;
        int counter = 0;
        int row = 10;
        int col = 10;
        boolean[][] matrix = new boolean[row][col];

        Random R = new Random();
        Scanner unos = new Scanner(System.in);

        System.out.println("Life factor: (0-many; 100-few)");
        limit = Integer.parseInt(unos.nextLine());

        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                chance = R.nextInt(100) + 1;
                if (chance > limit) {
                    matrix[i][j] = true;
                }
            }
        }

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (matrix[i][j] == false) {
                    System.out.print("_ ");
                } else if (matrix[i][j] == true) {
                    System.out.print("X ");
                }
            }
            System.out.println();
        }

        System.out.println("Number of iterations:");
        iterationNumber = Integer.parseInt(unos.nextLine());

        for (int o = 0; o < iterationNumber; o++) {

            for (int i = 1; i < row; i++) {
                for (int j = 1; j < col; j++) {

                    for (int ii = i - 1; ii < i + 1; ii++) {
                        for (int jj = j - 1; jj < j + 1; jj++) {
                            if (matrix[ii][jj] == true) {
                                counter++;                                
                            }
                        }
                    }
                    if (counter == 2 || counter == 3) {
                        matrix[i][j] = true;
                    }
                    if (counter <= 1 || counter >= 4) {
                        matrix[i][j] = false;
                    }
                    if (counter == 3) {
                        matrix[i][j] = true;
                    }
                    counter = 0;                    
                }
            }

            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if (matrix[i][j] == false) {
                        System.out.print("_ ");
                    } else if (matrix[i][j] == true) {
                        System.out.print("X ");
                    }
                }
                System.out.println();
            }
            System.out.println("///////////////////");
        }

    }

}

Recommended Answers

All 9 Replies

Line 54 you include the current cell in your counts, and also the cells diagonally above/left of the current cell. You don't seem to test the cells right/below the current one

ps if (someBoolean == true) is a redundant way to say if (someBoolean)

Thanks, didn't know about the if (someBoolean) part. :)

                    for (int ii = i - 1; ii < i + 1; ii++) {
                        for (int jj = j - 1; jj < j + 1; jj++) {
                            if (matrix[ii][jj] == true) {
                                counter++;                                
                            }
                        }
                    }

See, in this part, the ii and jj ints go from i-1 to i+1 and j-1 to j+1.
If you sketch up a table on a piece of paper, you'll see that this goes through all the adjacent cells. However, you're right about this including the current cell.
I'll fix that right away.

Also, the main problem still persists - the code automatically turns all cells into false (ie. dead). So I think I missed something in this part:

                    if (counter == 2 || counter == 3) {
                        matrix[i][j] = true;
                    }
                    if (counter <= 1 || counter >= 4) {
                        matrix[i][j] = false;
                    }
                    if (counter == 3) {
                        matrix[i][j] = true;
                    }
                    counter = 0;               

The position in the loops maybe?

I may be mistaken, but it looks like you are going left-to-right top-to-bottom updating each cell as you go. That's not how the game of life works. You are supposed to update all the cells at once. If you have two cells next to each other, call them A and B, then if the value of A needs to change, you must not change A until after you've decided if B needs to change, otherwise you might end up with the wrong value for B. Because of this, one usually wants two matrices, one to hold the current cells and one to hold the next cells. I notice that you only have one matrix.

commented: That's exactly how GoF works +12

See, in this part, the ii and jj ints go from i-1 to i+1 and j-1 to j+1.

No, they don't.

for (int ii = i - 1; ii < i + 1; ii++) { // this does not do what you say it should

put a print statement in your loops and see what values of ii and jj you are actually getting.

@bguild
You're right, I do need another matrix. However, I don't know how to analyze the whole initial matrix before generating a second matrix. What I'm thinking is simply adding a second matrix into the mix, generating second matrix based on the first, copying the second matrix into the first one, and then emptying the second one (so that I may iterate the whole sequence again).

@JamesCherrill
Would this correction fix it?

for (int ii = i - 1; ii <= i + 1; ii++) // '<=' instead of '='

Would this correction fix it?

You should really try that (with the print I previously suggested), then you would know for certain. But, just this once... yes.

Re two matrixes: you look at the values in one matrix, and set the values in the second matrix. Then when you've finished you copy the second matrix over the first (or use the 2 matrices in a flip-flop way, jus swapping the references over after each pass - which saves the copy)

Thanks to you guys, it works. :)
Also spammed it with comments to help rookies like me understand what happens where.

package igrazivota;

import java.util.Random;
import java.util.Scanner;

public class IgraZivota {

    public static void main(String[] args) {

        // Declaration of variables.
        int iterationNumber;
        int chance;
        int limit;
        int counter = 0;
        int row = 10;
        int col = 10;
        boolean[][] matrix = new boolean[row][col];
        boolean[][] matrix2 = new boolean[row][col];

        Random R = new Random();
        Scanner unos = new Scanner(System.in);

        System.out.println("Life factor: (0 - 100 (many - few)");
        limit = Integer.parseInt(unos.nextLine());

        // Seeding life in first matrix.
        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                chance = R.nextInt(100) + 1;
                if (chance > limit) {
                    matrix[i][j] = true;
                }
            }
        }

        // Printing first matrix.
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < col - 1; j++) {
                if (matrix[i][j] == false) {
                    System.out.print("_ ");
                } else if (matrix[i][j] == true) {
                    System.out.print("X ");
                }
            }
            System.out.println();
        }

        System.out.println("Number of iterations:");
        iterationNumber = Integer.parseInt(unos.nextLine());
        System.out.println("///////////////");

        for (int o = 0; o < iterationNumber; o++) {
            // Going from cell to cell
            for (int i = 1; i < row - 1; i++) {
                for (int j = 1; j < col - 1; j++) {
                    // Probing for life in all adjacent cells of current cell.
                    for (int ii = i - 1; ii <= i + 1; ii++) {
                        for (int jj = j - 1; jj <= j + 1; jj++) {
                            if (matrix[ii][jj] == true) {
                                counter++;
                            }
                        }
                    }
                    // Generate layout of second matrix based on conditions.
                    counter = counter - 1; // Counter-- because of current cell.
                    if ((counter == 2 || counter == 3) && matrix[i][j] == true) {
                        matrix2[i][j] = true;
                    }
                    if ((counter <= 1 || counter >= 4) && matrix[i][j] == true) {
                        matrix2[i][j] = false;
                    }
                    if (counter == 3 && matrix[i][j] == false) {
                        matrix2[i][j] = true;
                    }
                    counter = 0; // Reset counter for next iteration.
                }
            }
            // Copied from matrix2 to initial matrix.
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    matrix[i][j] = matrix2[i][j];
                }
            }
            // Printing initial matrix's new layout.
            for (int i = 1; i < row - 1; i++) {
                for (int j = 1; j < col - 1; j++) {
                    if (matrix[i][j] == false) {
                        System.out.print("_ ");
                    } else if (matrix[i][j] == true) {
                        System.out.print("X ");
                    }
                }
                System.out.println();
            }
            // Clearing matrix2.
            for (int i = 1; i < row - 1; i++) {
                for (int j = 1; j < col - 1; j++) {
                    matrix2[i][j] = false;
                }
            }
            // I like it tidy.
            System.out.println("");
            System.out.println("///////////////");
        }

    }
}

You may still have a bug.
On line 65 you fudge your counter to allow for the current cell being counted. This correction is OK if the current cell was true, but is wrong if the current cell was false. So the test on line 73 isn't going to work as you intended.

Have you tested your program with any of the simple known patterns (blinker, glider etc) to see if it's working properly? If not then you really haven't finished this project yet.

You're right.

                    if (matrix[i][j] == true){
                        counter = counter - 1;
                    }

This solves it.
I wanted a random seed of alive cells (but still based on a factor).
Given that, I don't want to input patterns myself. However, after a few runs the pattern asumes some of known shapes.

For example:
_ _ _ _ _ _
_ _ X X _ _
_ X _ _ X _
_ _ X X _ _
_ _ _ _ _ _

Again, thank you for your help. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.