diff --git a/README.md b/README.md index 543278579c668a73983898882148ead41c106d37..8cf845e4127a8f44d50bfbe3e44df968d7a6a96c 100644 --- a/README.md +++ b/README.md @@ -14,5 +14,4 @@ Le jeu se déroule sur une grille à deux dimensions dont les cases qu’on appe Le but de ce TP est de compléter le code fourni par le dépôt afin d'obtenir un simulateur de jeu de la vie. ## Membres du projet -- NOM, prénom, numéro de groupe, du premier participant -- NOM, prénom, numéro de groupe, du deuxième participant +- LABOUREL, Arnaud diff --git a/src/main/java/model/CellState.java b/src/main/java/model/CellState.java index bb1edb3c2058fb6c17d820a678b56da7e0fec39f..5ac0350b737cfeb4274279d0fe1625352bc157b0 100644 --- a/src/main/java/model/CellState.java +++ b/src/main/java/model/CellState.java @@ -3,10 +3,10 @@ package model; import javafx.scene.paint.Color; /** - * {@link CellState} instances represent the possible states of a {@link CellState}. + * Created by Arnaud Labourel on 2018-11-29. */ public enum CellState { - ALIVE(true, Color.RED), DEAD(false, Color.WHITE); + RED(true, Color.RED), BLUE(true, Color.BLUE), DEAD(false, Color.WHITE); public final boolean isAlive; public final Color color; @@ -15,4 +15,10 @@ public enum CellState { this.isAlive = isAlive; this.color = color; } + + static CellState majorityCellState(int redCount, int blueCount) { + if (redCount > blueCount) + return RED; + return BLUE; + } } diff --git a/src/main/java/model/Grid.java b/src/main/java/model/Grid.java index 0118e34dfb99646497c77c71cf93a10d2109d03f..24b36082e50245530e24eecaded76290c7120a07 100644 --- a/src/main/java/model/Grid.java +++ b/src/main/java/model/Grid.java @@ -1,12 +1,13 @@ package model; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Random; - +import java.util.function.Predicate; /** - * {@link Grid} instances represent the grid in <i>The Game of Life</i>. + * {@code Grid} instances represent the grid in <i>The Game of Life</i>. */ public class Grid implements Iterable<Cell> { @@ -28,12 +29,6 @@ public class Grid implements Iterable<Cell> { this.cells = createCells(); } - /** - * Returns an iterator over the cells in this {@code Grid}. - * - * @return an iterator over the cells in this {@code Grid} - */ - @Override public Iterator<Cell> iterator() { return new GridIterator(this); @@ -88,35 +83,6 @@ public class Grid implements Iterable<Cell> { return numberOfColumns; } - - // TODO: Écrire une version correcte de cette méthode. - public List<Cell> getNeighbours(int rowIndex, int columnIndex) { - return null; - } - - // TODO: Écrire une version correcte de cette méthode. - public int countAliveNeighbours(int rowIndex, int columnIndex) { - return 0; - } - - // TODO: Écrire une version correcte de cette méthode. - public CellState calculateNextState(int rowIndex, int columnIndex) { - return null; - } - - - - // TODO: Écrire une version correcte de cette méthode. - public CellState[][] calculateNextStates() { - CellState[][] nextCellState = new CellState[getNumberOfRows()][getNumberOfColumns()]; - return nextCellState; - } - - // TODO: Écrire une version correcte de cette méthode. - public void updateStates(CellState[][] nextState) { - - } - /** * Transitions all {@link Cell}s in this {@code Grid} to the next generation. * @@ -130,27 +96,113 @@ public class Grid implements Iterable<Cell> { * reproduction.</li> * </ul> */ - // TODO: Écrire une version correcte de cette méthode. void updateToNextGeneration() { + goToNextState(calculateNextState()); + } + private CellState[][] calculateNextState() { + CellState[][] nextCellState = new CellState[getNumberOfRows()][getNumberOfColumns()]; + for (int rowIndex = 0; rowIndex < getNumberOfRows(); rowIndex++) { + for (int columnIndex = 0; columnIndex < getNumberOfColumns(); columnIndex++) { + Cell cell = getCell(rowIndex, columnIndex); + nextCellState[rowIndex][columnIndex] = calculateNextState(rowIndex, columnIndex, cell); + } + } + return nextCellState; + } + + private CellState calculateNextState(int rowIndex, int columnIndex, Cell cell) { + int numberOfAliveNeighbours = countAliveNeighbors(rowIndex,columnIndex); + boolean isAliveInNextState = cellIsAliveInNextState(cell, numberOfAliveNeighbours); + int redNeighboursCount = countFilteredNeighbors(rowIndex, columnIndex, CellState.RED); + int blueNeighboursCount = countFilteredNeighbors(rowIndex, columnIndex, CellState.BLUE); + + if(!cell.isAlive() && isAliveInNextState) { + return CellState.majorityCellState(redNeighboursCount, blueNeighboursCount); + } + else{ + if(isAliveInNextState) + return cell.getState(); + else + return CellState.DEAD; + } + } + + private int countFilteredNeighbors(int rowIndex, int columnIndex, Predicate<CellState> filter) { + return (int) getNeighbors(rowIndex, columnIndex) + .stream() + .map(Cell::getState) + .filter(filter) + .count(); + } + + private int countFilteredNeighbors(int rowIndex, int columnIndex, CellState filteredState) { + return countFilteredNeighbors(rowIndex,columnIndex, (state)->state == filteredState); + } + + public int countAliveNeighbors(int rowIndex, int columnIndex) { + return countFilteredNeighbors(rowIndex,columnIndex,(state)->state.isAlive); + } + + + public List<Cell> getNeighbors(int rowIndex, int columnIndex) { + int north = rowIndex - 1; + int east = columnIndex + 1; + int south = rowIndex + 1; + int west = columnIndex - 1; + + return Arrays.asList( + getCell(north, west), + getCell(north, columnIndex), + getCell(north, east), + getCell(rowIndex, east), + getCell(south, east), + getCell(south, columnIndex), + getCell(south, west), + getCell(rowIndex, west) + ); + } + + private static boolean cellIsAliveInNextState(Cell cell, int numberOfAliveNeighbours) { + return (cell.isAlive() && numberOfAliveNeighbours == 2) || numberOfAliveNeighbours == 3; + } + + private void goToNextState(CellState[][] nextState) { + for (int rowIndex = 0; rowIndex < getNumberOfRows(); rowIndex++) { + for (int columnIndex = 0; columnIndex < getNumberOfColumns(); columnIndex++) { + getCell(rowIndex, columnIndex).setState(nextState[rowIndex][columnIndex]); + } + } } /** * Sets all {@link Cell}s in this {@code Grid} as dead. */ - // TODO: Écrire une version correcte de cette méthode. void clear() { - + for (Cell cell : this) { + cell.setState(CellState.DEAD); + } } /** - * Goes through each {@link Cell} in this {@code Grid} and randomly sets its state as ALIVE or DEAD. + * 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}. + * @param random {@link Random} instance used to decide if each {@link Cell} is red, blue or dead + * @throws NullPointerException if {@code random} is {@code null} */ - // TODO: Écrire une version correcte de cette méthode. void randomGeneration(Random random) { + for (Cell cell : this) { + if (random.nextBoolean()) + cell.setState(CellState.DEAD); + else + setCellToRandomAliveState(cell, random); + } + } + private void setCellToRandomAliveState(Cell cell, Random random) { + if (random.nextBoolean()) + cell.setState(CellState.BLUE); + else + cell.setState(CellState.RED); } -} +} \ No newline at end of file diff --git a/src/test/java/model/GridTest.java b/src/test/java/model/GridTest.java index a2956612e6cd8c13ead11e6e77623b957964c994..fb8eebf487b2c3989151f1ce48a85fab138a1c09 100644 --- a/src/test/java/model/GridTest.java +++ b/src/test/java/model/GridTest.java @@ -15,9 +15,9 @@ public class GridTest { @Test public void testGetNeighbours(){ - assertThat(grid.getNeighbours(1,1), is(notNullValue())); - assertThat(grid.getNeighbours(1,1), hasSize(equalTo(8))); - assertThat(grid.getNeighbours(1,1), + assertThat(grid.getNeighbors(1,1), is(notNullValue())); + assertThat(grid.getNeighbors(1,1), hasSize(equalTo(8))); + assertThat(grid.getNeighbors(1,1), containsInAnyOrder(grid.getCell(0,0), grid.getCell(0,1), grid.getCell(0,2), @@ -30,10 +30,10 @@ public class GridTest { @Test public void testCountAliveNeighbours(){ - assertThat(grid.countAliveNeighbours(1,1), is(equalTo(0))); - grid.getCell(2,2).setState(CellState.ALIVE); - grid.getCell(0,0).setState(CellState.ALIVE); - assertThat(grid.countAliveNeighbours(1,1), is(equalTo(2))); + assertThat(grid.countAliveNeighbors(1,1), is(equalTo(0))); + grid.getCell(2,2).setState(CellState.RED); + grid.getCell(0,0).setState(CellState.RED); + assertThat(grid.countAliveNeighbors(1,1), is(equalTo(2))); }