Skip to content
Snippets Groups Projects
Select Git revision
  • 1639f1ea093d66db2270b3766af7e28fdfe6df5f
  • main default protected
  • variant
3 results

BoardFireFighterBehavior.java

Blame
  • Forked from COUETOUX Basile / FirefighterStarter
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Grid.java 6.83 KiB
    import java.util.*;
    
    /**
     * {@code Grid} instances represent the grid in <i>The Game of Life</i>.
     */
    public class Grid implements Iterable<Cell> {
    
        private final int numberOfRows;
        private final int numberOfColumns;
        private final Cell[][] cells;
    
        /**
         * Creates a new {@code Grid} instance given the number of rows and columns.
         *
         * @param numberOfRows    the number of rows
         * @param numberOfColumns the number of columns
         * @throws IllegalArgumentException if {@code numberOfRows} or {@code numberOfColumns} are
         *                                  less than or equal to 0
         */
        public Grid(int numberOfRows, int numberOfColumns) {
            this.numberOfRows = numberOfRows;
            this.numberOfColumns = numberOfColumns;
            this.cells = createCells();
        }
    
        @Override
        public Iterator<Cell> iterator() {
            return new GridIterator(this);
        }
    
        private Cell[][] createCells() {
            Cell[][] cells = new Cell[getNumberOfRows()][getNumberOfColumns()];
            for (int rowIndex = 0; rowIndex < getNumberOfRows(); rowIndex++) {
                for (int columnIndex = 0; columnIndex < getNumberOfColumns(); columnIndex++) {
                    cells[rowIndex][columnIndex] = new Cell();
                }
            }
            return cells;
        }
    
        /**
         * Returns the {@link Cell} at the given index.
         *
         * <p>Note that the index is wrapped around so that a {@link Cell} is always returned.
         *
         * @param rowIndex    the row index of the {@link Cell}
         * @param columnIndex the column index of the {@link Cell}
         * @return the {@link Cell} at the given row and column index
         */
        public Cell getCell(int rowIndex, int columnIndex) {
            return cells[getWrappedRowIndex(rowIndex)][getWrappedColumnIndex(columnIndex)];
        }
    
        private int getWrappedRowIndex(int rowIndex) {
            return (rowIndex + getNumberOfRows()) % getNumberOfRows();
        }
    
        private int getWrappedColumnIndex(int columnIndex) {
            return (columnIndex + getNumberOfColumns()) % getNumberOfColumns();
        }
    
        /**
         * Returns the number of rows in this {@code Grid}.
         *
         * @return the number of rows in this {@code Grid}
         */
        public int getNumberOfRows() {
            return numberOfRows;
        }
    
        /**
         * Returns the number of columns in this {@code Grid}.
         *
         * @return the number of columns in this {@code Grid}
         */
        public int getNumberOfColumns() {
            return numberOfColumns;
        }
    
        /**
         * Transitions all {@link Cell}s in this {@code Grid} to the next generation.
         *
         * <p>The following rules are applied:
         * <ul>
         * <li>Any live {@link Cell} with fewer than two live neighbours dies, i.e. underpopulation.</li>
         * <li>Any live {@link Cell} with two or three live neighbours lives on to the next
         * generation.</li>
         * <li>Any live {@link Cell} with more than three live neighbours dies, i.e. overpopulation.</li>
         * <li>Any dead {@link Cell} with exactly three live neighbours becomes a live cell, i.e.
         * reproduction.</li>
         * </ul>
         */
        void nextGeneration() {
            goToNextState(calculateNextStates());
        }
    
        private boolean[][] calculateNextStates() {
            boolean[][] nextState = new boolean[this.getNumberOfRows()][this.getNumberOfColumns()];
            for(int i = 0; i < this.getNumberOfRows(); i++){
                for(int j = 0; j < this.getNumberOfColumns(); j++){
                    nextState[i][j] = calculateNextState(i,j,this.getCell(i,j));
                }
            }
    
            return nextState;
        }
        private char getAverageNeighboursColor(int rowIndex,int columnIndex)
        {
            int redCount=0;
            int blueCount=0;
    
            List<Cell> neighbours = this.getNeighbours(rowIndex,columnIndex);
    
            for(Cell currentCell : neighbours)
            {
                if(currentCell.isAlive())
                {
                    if(currentCell.getColor()=='R'){redCount++;}
                    else{blueCount++;}
                }
            }
    
            if(blueCount>redCount)
            {
                return 'B';
            }
    
            return 'R';
        }
    
        private boolean calculateNextState(int rowIndex, int columnIndex, Cell cell) {
            int neighbours = this.countAliveNeighbours(rowIndex,columnIndex);
            if(cell.isAlive()){
                if(neighbours == 2 || neighbours == 3){
                    return true;
                }
    
            }
            else{
                if(neighbours == 3){
                    cell.setColor(this.getAverageNeighboursColor(rowIndex,columnIndex));
                    return true;
                }
            }
            return false;
        }
    
        private int countAliveNeighbours(int rowIndex, int columnIndex) {
            int count = 0;
            List<Cell> Neighbours = this.getNeighbours(rowIndex, columnIndex);
            for(Cell cell : Neighbours){
                if(cell.isAlive()){
                    count++;
                }
            }
            return count;
        }
    
    
        private List<Cell> getNeighbours(int rowIndex, int columnIndex) {
            List<Cell> Neighbours= new ArrayList<Cell>();
            for(int i = rowIndex -1; i <= rowIndex + 1; i++) {
                for (int j = columnIndex-1; j <= columnIndex + 1; j++) {
                    if(i != rowIndex || j != columnIndex){
                        Neighbours.add(this.getCell(i,j));
                    }
                }
            }
                return Neighbours;
        }
    
        private void goToNextState(boolean[][] nextState) {
            for(int i = 0; i < this.getNumberOfRows(); i++){
                for(int j = 0; j < this.getNumberOfColumns(); j++){
                    if(nextState[i][j]){
                        this.getCell(i,j).setAlive();
                    }
                    else{
                        this.getCell(i,j).setDead();
                    }
                }
            }
        }
    
        /**
         * Sets all {@link Cell}s in this {@code Grid} as dead.
         */
        void clear() {
            for(int i = 0; i < this.getNumberOfRows(); i++){
                for(int j = 0; j < this.getNumberOfColumns(); j++){
                    this.getCell(i,j).setDead();
                }
            }
        }
    
        /**
         * Goes through each {@link Cell} in this {@code Grid} and randomly sets it as alive or dead.
         *
         * @param random {@link Random} instance used to decide if each {@link Cell} is alive or dead
         * @throws NullPointerException if {@code random} is {@code null}
         */
    
        void randomGeneration(Random random) {
            for(int i = 0; i < this.getNumberOfRows(); i++){
                for(int j = 0; j < this.getNumberOfColumns(); j++){
                    if(random.nextBoolean()){
                        if(random.nextBoolean()){
                            this.getCell(i,j).setColor('r');
                        }
                        else{
                            this.getCell(i,j).setColor('b');
                        }
                        this.getCell(i,j).setAlive();
                    }
                    else{
                        this.getCell(i,j).setDead();
                    }
                }
            }
        }
    
    }