Search code examples
javaalgorithmlogicconways-game-of-life

Java Game of life not giving desired output?


Im trying to create conway's game of life in Java, but for some reason, the cells are not coming to life and dying as they should? Im wondering if my comparison algorithm is incorrect? Also after asking to run the evolve function several times, it just prints the same thing over and over again....

Project 4:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

public class Project4 {

    private static void printGame() {
        for (char[] row : GameOfLife.grid) {
            for (char c : row) {
                System.out.print(c);
            }
            System.out.println();
        }
    }

    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in); // Created a scanner
        System.out.println("Enter the file name you would like to use");
        File file = new File(input.nextLine()); // Takes file name to find file
        BufferedReader br = null;
        String line;
        int i = 0;

        try {
            br = new BufferedReader(new FileReader(file));
            while ((line = br.readLine()) != null) {
                for (int col = 0; col < line.length(); col++) {
                    GameOfLife.grid[i][col] = line.charAt(col);
                }
                i++;
                if (i == 25) {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                br.close();
            }
        }

        // Prints the initial environment
        System.out.println("Initial set: ");
        printGame();

        while (true) {
            System.out.println("Do you want to see the next generation? Y/N?");
            String q = input.nextLine();
            if (q.equalsIgnoreCase("y")) {
                GameOfLife.evolve();
                printGame();
            } else {
                System.exit(0);
            }
        }
    }
}

GameOfLife:

import java.util.Arrays;

public class GameOfLife {

    static final int m = 25; // number of rows
    static final int n = 75; // number of columns
    static char[][] grid = new char[m][n]; // Creates an empty (no dots or
                                            // X's)grid of rows and columns.

    static int count_neighbors(int i, int j) {
        int nn = 0; // number of neighbors of cell(i,j)

        if (i > 0 && j > 0 && grid[i - 1][j - 1] == 'X') {
            nn++;
        }
        ;
        if (i > 0 && grid[i - 1][j] == 'X') {
            nn++;
        }
        ;
        if (i > 0 && j < 72 && grid[i - 1][j + 1] == 'X') {
            nn++;
        }
        ;
        if (j > 0 && grid[i][j - 1] == 'X') {
            nn++;
        }
        ;
        if (j < 72 && grid[i][j + 1] == 'X') {
            nn++;
        }
        ;
        if (j > 0 && i < 22 && grid[i + 1][j - 1] == 'X') {
            nn++;
        }
        ;
        if (i < 22 && grid[i + 1][j] == 'X') {
            nn++;
        }
        ;
        if (i < 22 && j < 72 && grid[i + 1][j + 1] == 'X') {
            nn++;
        }

        return nn;
    }

    static void evolve() {
        for (int i = 0; i <= 25 - 1; i++) {
            for (int j = 0; j <= 75 - 1; j++) {
                int s = count_neighbors(i, j);
                if (s < 2 || s > 3) {
                    grid[i][j] = '.';
                }
                if ((s == 2 || s == 3) && grid[i][j] == 'X') {
                    grid[i][j] = 'X';
                }
                if (s == 3 && grid[i][j] == '.') {
                    grid[i][j] = 'X';
                }
            }

        }

    }

}

Solution

  • When I implemented this, I had a condition that checked if the current cell had a value... can't remember the exact rules, but here is my version using the "snapshot" that @janos mentions.

    static void evolve() {
    
        char[][] temp = new char[m][n];
        for (int r = 0; r < m; r++) {
            for (int c = 0; c < n; c++) {
                int neighbors = count_neighbors(r, c);
                boolean occupied = grid[r][c] == 'X';
                if (occupied && neighbors < 2) {
                    temp[r][c] = '.';
                } else if (occupied && neighbors > 3) {
                    temp[r][c] = '.';
                } else if (occupied && (neighbors == 2 || neighbors == 3)) {
                    temp[r][c] = 'X';
                } else if (!occupied && neighbors == 3) {
                    temp[r][c] = 'X';
                } else {
                    temp[r][c] = '.';
                }
            }
        }
        grid = temp.clone();
    }