0

The following code is Conway's Game of Life in a terminal. What I would like to do here is to overwrite the current step into the next step. I have a temporary 2D array in the animateChanges() method. Also in the main method I am printing the animateChanges() three times, that's what I would like to change. Basically, I would like to overwrite the board instead of printing it three times because visually its quite ugly while looping.

public class GameOfLifeTerminal {
    private int WIDTH;
    private int HEIGHT;
    private int[][] board;
    private int aliveNeighbours = 0;


    public GameOfLifeTerminal(int width, int height) {
        this.WIDTH = width;
        this.HEIGHT = height;
        this.board = new int[width][height];
    }

    /*Getters & Setters*/
    public void setAlive(int x, int y) {
        this.board[x][y] = 1;
    } //true
    public void setDead(int x, int y) {
        this.board[x][y] = 0;
    } // false, currently not being used
    //get the rows in the y axis
    public int getRows(){ return board.length; }
    //get the columns in the x axis
    public int getColumns(){ return board[0].length; }

    /*Methods and functions*/
    public void printBoard() { //prints the board
        for (int y = 0; y < HEIGHT; y++) {
            String line = "";
            for (int x = 0; x < WIDTH; x++) {
                if (this.board[x][y] == 0) {
                    line += "·";
                } else {
                    line += "O";
                }
            }
            System.out.println(line);
        }
        System.out.println();
    }

    public int countAliveNeighbours(int x, int y) {    //count the number of alive neighbours
        int count = 0;
        /*
        for(int i = x-1; i < x+1; i++) {
            for (int j = y - 1; i < y + 1; j++) {
                if (getState(i, j) == 1) count++;
            }
        }
         if(getState(x, y) == 1) count--;
        */

        //checks each position one by one and calls the getState() method to be inside the bounds
        count += getState(x - 1, y - 1);
        count += getState(x, y - 1);
        count += getState(x + 1, y - 1);

        count += getState(x - 1, y);
        count += getState(x + 1, y);

        count += getState(x - 1, y + 1);
        count += getState(x, y + 1);
        count += getState(x + 1, y + 1);
        //System.out.println(count);
        return count;
    }

    public int getState(int x, int y) { //get state neighbours in case is out of bounds
        if (x < 0 || x >= WIDTH) return 0;
        if (y < 0 || y >= HEIGHT) return 0;
        return this.board[x][y];
    }

    public void animateChanges() { //applies the rules and then prints the board with current state of the cells
        //temporary board
        int[][] newBoard = new int[WIDTH][HEIGHT];
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                aliveNeighbours = countAliveNeighbours(x, y);
                //rules
                if (getState(x, y) == 1) { //if true
                    if (aliveNeighbours < 2) { // le ded
                        newBoard[x][y] = 0;
                    } else if (aliveNeighbours == 2 || aliveNeighbours == 3) { //alive
                        newBoard[x][y] = 1;
                    } else if (aliveNeighbours > 3) { // le ded
                        newBoard[x][y] = 0;
                    }
                } else {
                    if (aliveNeighbours == 3) { //create new cells
                        newBoard[x][y] = 1;
                    }
                }
            }
        }
        this.board = newBoard;
        
        //System.out.println("Alive cells " + aliveNeighbours);
        printBoard();
    }
    //main method
    public static void main(String[] args) {
        GameOfLifeTerminal simulation = new GameOfLifeTerminal(8, 5);
        simulation.setAlive(2, 2);
        simulation.setAlive(3, 2);
        simulation.setAlive(4, 2);

        simulation.animateChanges();
        simulation.animateChanges();
        simulation.animateChanges();
    }
}
  • @HovercraftFullOfEels I mean yeah, but in the end I would like to overwrite the step into the next step in a single board instead of printing it again to see the change. – noobieCoder Nov 16 '21 at 23:07
  • 1
    If you want to manipulate the console output, you'll need a console manipulation library like `curses` to do so. I don't know what Java uses natively to do it, but `System.out.println` isn't built to modify existing console text. – Silvio Mayolo Nov 16 '21 at 23:10

1 Answers1

2

You appear to already be "overwriting" the board inside your animateChanges() method with this call: this.board = newBoard; Why not simply remove the call to printBoard(); from the same animateChanges() method? Then you can call printBoard() when and how you want to do it.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I want to print it yes, but when I print it again I want to overwrite the last print with the current one. – noobieCoder Nov 16 '21 at 23:25
  • 1
    @noobieCoder: then you probably want to create a GUI version of this program, and display the changes in the GUI. The standard Java console doesn't allow deletion of text. – Hovercraft Full Of Eels Nov 16 '21 at 23:27
  • Yep, I did a more advanced GUI version but I am doing this version independently, that's why I was asking about overwriting when the board prints. Wouldn't this work? `Runtime.getRuntime().exec("cls");` – noobieCoder Nov 16 '21 at 23:32
  • 1
    @noobieCoder: well, what happens when you've tried this? – Hovercraft Full Of Eels Nov 16 '21 at 23:42
  • @noobieCoder `cls` is a Windows command, but for Linux / Unix / MacOS it would be the `clear` command. There is a JCurses library you could search for that would let you clear the screen for both Windows and Linux. – John Bayko Nov 16 '21 at 23:45
  • @HovercraftFullOfEels error as expected :D – noobieCoder Nov 16 '21 at 23:53