import java.util.Scanner;

public class GameOfLife
{
    public static void main(String[] args){
       boolean[][] world = genWorld(10,15);
       int generation = 0;
       show(world, generation);
       Scanner s = new Scanner(System.in);
       while( !quit(s) ){
           world = nextGen(world);
           generation++;
           show(world, generation);
        }
    }
    
    public static boolean quit(Scanner s){
        System.out.print("Enter Q to quit or anything else for the next generation: " );
        String response = s.nextLine();
        return response != null && response.length() > 0 
            && response.substring(0,1).equalsIgnoreCase("q");
    }
    
    public static boolean[][] genWorld( int rows, int cols ){
        boolean[][] world = new boolean[rows][cols];
        for(int r = 0; r < world.length; r++)
            for(int c = 0; c < world[r].length; c++)
                world[r][c] = Math.random() < 0.25;
        return world;
    }
    
    
    public static void show(boolean[][] world, int generation){
        System.out.println("\n\nGeneration number " + generation + ".");
        for(int r = 0; r < world.length; r++){
            for(int c = 0; c < world[r].length; c++){
                if( world[r][c] )
                    System.out.print("*");
                else
                    System.out.print(".");
            }
            System.out.println();
        }
    }
    

    public static boolean[][] nextGen(boolean[][] world){
        boolean[][] result = new boolean[world.length][world[0].length];
        // all elements of result are false
        
        int numNeigh;
        for(int r = 0; r < world.length; r++){
            for(int c = 0; c < world[r].length; c++){
                numNeigh = getNumNeighbors(r, c, world);
                // occupied in wolrd and survives
                if( world[r][c] && (numNeigh == 2 || numNeigh == 3) )
                    result[r][c] = true;
               // unoccupied in world and birth 
               else if( !world[r][c] && numNeigh == 3 )
                    result[r][c] = true;
           }
        }
        return result;
    }
    
    public static int getNumNeighbors(int r, int c, boolean[][] world){
        int num = 0;
        for(int row = r-1; row <= r + 1; row++){
            for(int col = c-1; col <= c+1; col++){
                if( inbounds(row, col, world) && world[row][col] )
                    num++;
            }
        }
        if( world[r][c] ) 
            num--;
        return num;
    }
    
    public static boolean inbounds(int r, int c, boolean[][] mat){
        return r >= 0 && r < mat.length && c >= 0 && c < mat[r].length;
    }
    
    
    
    
    
    
    
    
    

}
