diff --git a/src/main/java/SimulatorApplication.java b/src/main/java/SimulatorApplication.java index 7e2a01d75586b977138a32a64624b3c4879f71a6..2046705331f1294ce3d0b166ba8d35b3f38d7d11 100644 --- a/src/main/java/SimulatorApplication.java +++ b/src/main/java/SimulatorApplication.java @@ -36,10 +36,10 @@ public class SimulatorApplication extends Application { */ public SimulatorApplication() { this.simulation = - new CellularAutomatonSimulation<>( - new GameOfLifeAutomaton(NUMBER_OF_COLUMNS,NUMBER_OF_ROWS), - GENERATOR - ); + new CellularAutomatonSimulation<>( + new GameOfLifeAutomaton(NUMBER_OF_COLUMNS,NUMBER_OF_ROWS), + GENERATOR + ); } @@ -75,3 +75,4 @@ public class SimulatorApplication extends Application { } } + diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 01dae37f19b1102256c299687b836feaa1a22775..5d97e9eef3744c4d7074110a7dd5f888fcaea15d 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -124,3 +124,4 @@ public class Controller { timeline.pause(); } } + diff --git a/src/main/java/matrix/Coordinate.java b/src/main/java/matrix/Coordinate.java index 8bd880244e858907285df5203cea6de4385e4a04..e600ef64695fb7b158200c9c2ac2b2e35fdad0dc 100644 --- a/src/main/java/matrix/Coordinate.java +++ b/src/main/java/matrix/Coordinate.java @@ -33,7 +33,7 @@ public record Coordinate(int x, int y) { * @return The right adjacent {@link Coordinate}. */ public Coordinate right() { - return new Coordinate(x+1, y); + return new Coordinate(x+1,y); } /** @@ -42,7 +42,7 @@ public record Coordinate(int x, int y) { * @return The above adjacent {@link Coordinate}. */ public Coordinate above() { - return new Coordinate(x, y+1); + return new Coordinate(x,y+1); } /** @@ -51,7 +51,7 @@ public record Coordinate(int x, int y) { * @return The below adjacent {@link Coordinate}. */ public Coordinate below() { - return new Coordinate(x, y-1); + return new Coordinate(x,y-1); } /** @@ -68,7 +68,7 @@ public record Coordinate(int x, int y) { * @return A list of orthogonal neighboring {@link Coordinate}s. */ public List<Coordinate> orthogonalNeighbours() { - return List.of(left(),right(), above(), below()); + return List.of(above(),right(),left(),below()); } /** @@ -86,10 +86,7 @@ public record Coordinate(int x, int y) { * @return A list of diagonal neighboring {@link Coordinate}s. */ public List<Coordinate> diagonalNeighbours() { - return List.of(new Coordinate(x-1, y-1), - new Coordinate(x-1, y+1), - new Coordinate(x+1, y-1), - new Coordinate(x+1, y+1)); + return List.of(new Coordinate(x-1,y-1),new Coordinate(x-1,y+1),new Coordinate(x+1,y-1),new Coordinate(x+1,y+1)); } /** @@ -107,10 +104,7 @@ public record Coordinate(int x, int y) { * @return A list of all neighboring {@link Coordinate}s. */ public List<Coordinate> orthodiagonalNeighbours() { - return List.of(left(),right(), above(), below(), new Coordinate(x-1, y-1), - new Coordinate(x-1, y+1), - new Coordinate(x+1, y-1), - new Coordinate(x+1, y+1)); + return List.of(above(),right(),left(),below(),new Coordinate(x-1,y-1),new Coordinate(x-1,y+1),new Coordinate(x+1,y-1),new Coordinate(x+1,y+1)); } @Override @@ -118,11 +112,11 @@ public record Coordinate(int x, int y) { return "(" + this.x + "," + this.y + ")"; } - public Coordinate minus(Coordinate corner) { - return new Coordinate(this.x - corner.x, this.y - corner.y); - } + public Coordinate minus(Coordinate corner) { + return new Coordinate(this.x - corner.x, this.y - corner.y); + } - public Coordinate plus(Coordinate corner) { - return new Coordinate(this.x + corner.x, this.y + corner.y); - } -} \ No newline at end of file + public Coordinate plus(Coordinate corner) { + return new Coordinate(this.x + corner.x, this.y + corner.y); + } +} diff --git a/src/main/java/matrix/CoordinateIterator.java b/src/main/java/matrix/CoordinateIterator.java index c74cff9dbf6ebd9b91147a1867c9409483672852..a9b8d5f4dc731cffb83f751edaf4cb1498709c0e 100644 --- a/src/main/java/matrix/CoordinateIterator.java +++ b/src/main/java/matrix/CoordinateIterator.java @@ -8,9 +8,10 @@ import java.util.NoSuchElementException; * height range. */ class CoordinateIterator implements Iterator<Coordinate> { - private final int width ; - private final int height ; - private Coordinate current = new Coordinate(0,0) ; + private final int width; + private final int height; + private Coordinate current = new Coordinate(0, 0); + /** * Creates a new {@link CoordinateIterator} with the specified width and height. * @@ -18,8 +19,8 @@ class CoordinateIterator implements Iterator<Coordinate> { * @param height The height of the coordinate range. */ public CoordinateIterator(int width, int height) { - this.width = width ; - this.height = height ; + this.width = width; + this.height = height; } /** @@ -29,7 +30,7 @@ class CoordinateIterator implements Iterator<Coordinate> { */ @Override public boolean hasNext() { - return current.y()<height; + return current.y() < height; } /** @@ -41,16 +42,10 @@ class CoordinateIterator implements Iterator<Coordinate> { @Override public Coordinate next() { if (!hasNext()) throw new NoSuchElementException(); - Coordinate next = current; - // on crée un méthode update - update(); - return next; - } - - private void update(){ current = current.right(); - if (current.x() == width) - current = new Coordinate(0, current.y()+1); + if (current.x() == width) current = new Coordinate(0, current.y() + 1); + + return next; } } diff --git a/src/main/java/matrix/ListMatrix.java b/src/main/java/matrix/ListMatrix.java index 0e9bf482389a0ec273d8a72262ceb6e879b7805a..27fbd83090d553fe8e9203d3d79e45216dff828d 100644 --- a/src/main/java/matrix/ListMatrix.java +++ b/src/main/java/matrix/ListMatrix.java @@ -27,7 +27,7 @@ public class ListMatrix<T> implements Matrix<T> { this.width = width; this.height = height; this.matrix = new ArrayList<>(width); - this.initializeWith(initializer); // fills the matrix using initializer + this.initializeWith(initializer); } public ListMatrix(int width, int height, T constant) { @@ -37,7 +37,8 @@ public class ListMatrix<T> implements Matrix<T> { private void initializeWith(MatrixInitializer<T> initializer) { for (int x=0; x<width; x++) { List<T> column = new ArrayList<>(height); - for (int y=0; y<height; y++) { + + for (int y = 0; y < height; y++) { column.add(initializer.initialValueAt(new Coordinate(x, y))); } matrix.add(column); @@ -45,6 +46,7 @@ public class ListMatrix<T> implements Matrix<T> { } + public int width() { return width; } @@ -54,7 +56,8 @@ public class ListMatrix<T> implements Matrix<T> { } @Override - public T get(int x, int y) { // une liste de listes + public T get(int x, int y) { + return matrix.get(x).get(y); } @@ -65,3 +68,4 @@ public class ListMatrix<T> implements Matrix<T> { } } + diff --git a/src/main/java/model/CellularAutomatonSimulation.java b/src/main/java/model/CellularAutomatonSimulation.java index 302fe7dd4a22ce84189f9c1926b3477ad5e9c534..0d72f9c11c977d5b32fa6e19d24a3c4536b41b96 100644 --- a/src/main/java/model/CellularAutomatonSimulation.java +++ b/src/main/java/model/CellularAutomatonSimulation.java @@ -4,19 +4,19 @@ import controller.Simulation; import matrix.Coordinate; import matrix.ListMatrix; import javafx.scene.paint.Color; +import model.*; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.Random; - - /** * {@link CellularAutomatonSimulation} instances run <i>The Game of Life</i>. * - * @param <S> The type of state used in the simulation. + * @param <S> The type of state used in the simulation. */ -public class CellularAutomatonSimulation<S extends State<S>> - implements Simulation { +public class CellularAutomatonSimulation<S extends State<S>> implements Simulation { private final ListMatrix<Cell<S>> grid; private final Cell<Integer> generationNumber = new Cell<>(0); @@ -39,15 +39,14 @@ public class CellularAutomatonSimulation<S extends State<S>> this.generator = generator; } - @Override public int numberOfColumns() { - return numberOfColumns(); + return this.grid.width(); } @Override public int numberOfRows() { - return numberOfRows(); + return this.grid.height(); } /** @@ -57,37 +56,86 @@ public class CellularAutomatonSimulation<S extends State<S>> * @return The cell at the specified coordinate. */ public Cell<S> at(Coordinate coordinate) { - return null; + return this.grid.get(coordinate.x(), coordinate.y()); } @Override public void updateToNextGeneration() { - //TODO: à compléter, en utilisant nextGenerationMatrix() + ListMatrix<Cell<S>> nextMatrix = nextGenerationMatrix(); + for (Coordinate coordinate : this.grid.coordinates()) { + this.grid.get(coordinate.x(), coordinate.y()) + .set(nextMatrix.get(coordinate.x(), coordinate.y()).get()); + } + this.generationNumber.set(this.generationNumber.get() + 1); // Increment generation number } - /** Computes the {@link ListMatrix} of states obtained after a single step of updates + /** + * Computes the {@link ListMatrix} of states obtained after a single step of updates * of the simulation. * * @return the states of each cell after one generation */ - private ListMatrix<S> nextGenerationMatrix() { - //TODO: à compléter - return null; + private ListMatrix<Cell<S>> nextGenerationMatrix() { + ListMatrix<Cell<S>> nextGrid = new ListMatrix<>( + this.grid.width(), + this.grid.height(), + new ConstantCellInitializer<>(automaton.defaultState()) // Pass the state directly + ); + + for (Coordinate coordinate : this.grid.coordinates()) { + S currentState = this.grid.get(coordinate.x(), coordinate.y()).get(); + List<S> neighbors = getNeighbors(coordinate); + S nextState = currentState.update(neighbors); + nextGrid.get(coordinate.x(), coordinate.y()).set(nextState); + } + + return nextGrid; + } + + /** + * Calculates the neighbors of a cell at the given coordinate. + * + * @param coordinate The coordinate of the cell. + * @return A list of states representing the neighbors of the cell. + */ + private List<S> getNeighbors(Coordinate coordinate) { + List<S> neighbors = new ArrayList<>(); + for (Coordinate neighbor : coordinate.orthodiagonalNeighbours()) { + if (isValidCoordinate(neighbor)) { + neighbors.add(this.grid.get(neighbor.x(), neighbor.y()).get()); + } + } + return neighbors; + } + + /** + * Validates if the given coordinate is within the bounds of the grid. + * + * @param coordinate The coordinate to validate. + * @return True if the coordinate is valid; false otherwise. + */ + private boolean isValidCoordinate(Coordinate coordinate) { + return coordinate.x() >= 0 && coordinate.x() < this.grid.width() + && coordinate.y() >= 0 && coordinate.y() < this.grid.height(); } + @Override public void next(Coordinate coordinate) { - //TODO: à compléter + Cell<S> cell = this.at(coordinate); + List<S> neighbors = getNeighbors(coordinate); + S nextState = cell.get().update(neighbors); + cell.set(nextState); } @Override public void copy(Coordinate source, Coordinate destination) { - //TODO: à compléter + S sourceState = this.at(source).get(); + this.at(destination).set(sourceState); } @Override public Color getColor(Coordinate coordinate) { - //TODO: à compléter - return null; + return this.at(coordinate).get().getColor(); } @Override @@ -98,24 +146,28 @@ public class CellularAutomatonSimulation<S extends State<S>> } @Override - public void setGenerationNumberChangeListener(OnChangeListener<Integer> listener){ + public void setGenerationNumberChangeListener(OnChangeListener<Integer> listener) { this.generationNumber.addOnChangeListener(listener); } - @Override public void clear() { - //TODO: à compléter (penser à remettre le nombre de génération à 0) + for (Coordinate coordinate : this.grid.coordinates()) { + this.at(coordinate).set(this.automaton.defaultState()); + } + this.generationNumber.set(0); // Reset generation counter } - @Override public void reset() { - //TODO: à compléter (penser à remettre le nombre de génération à 0) + for (Coordinate coordinate : this.grid.coordinates()) { + this.grid.set(coordinate.x(), coordinate.y(), new Cell<>(this.automaton.defaultState())); + } + this.generationNumber.set(0); } @Override public Iterator<Coordinate> iterator() { return this.grid.coordinates().iterator(); } -} +} \ No newline at end of file diff --git a/src/main/java/model/ConstantCellInitializer.java b/src/main/java/model/ConstantCellInitializer.java index 8e0d0cd19a5ad8c5329b8c0d28957802ad85e678..ecd7f5089c1c805ef236ef13572be6793375baa0 100644 --- a/src/main/java/model/ConstantCellInitializer.java +++ b/src/main/java/model/ConstantCellInitializer.java @@ -5,27 +5,36 @@ import matrix.ListMatrix; import matrix.MatrixInitializer; /** - * An initializer for {@link ListMatrix} of {@link Cell}s, where each cell is initialized to the - * same value. + * An initializer for {@link ListMatrix} of {@link Cell}s, where each cell is initialized to the + * same value. * * @param <T> the type of content of each cell */ -public class ConstantCellInitializer<T> implements MatrixInitializer<Cell<T>> { - //TODO: ajouter la/les propriétes nécessaires +public class ConstantCellInitializer<T> implements MatrixInitializer<Cell<T>> { - /** Make a new {@link MatrixInitializer} with cells containing a {@link Cell} with the same + /** + * The default value to be stored in each cell. + */ + private final T defaultValue; + + /** + * Make a new {@link MatrixInitializer} with cells containing a {@link Cell} with the same * value. * * @param defaultValue the value stored in each cell. */ - private T defaultValue; - public ConstantCellInitializer(T defaultValue) { this.defaultValue = defaultValue; } + /** + * Returns a new {@link Cell} initialized with the default value for the specified coordinate. + * + * @param coordinate The {@link Coordinate} at which to set the initial value. + * @return A new {@link Cell} containing the default value. + */ @Override public Cell<T> initialValueAt(Coordinate coordinate) { - return new Cell(defaultValue); + return new Cell<>(defaultValue); } -} +} \ No newline at end of file diff --git a/src/main/java/model/automata/GameOfLifeAutomaton.java b/src/main/java/model/automata/GameOfLifeAutomaton.java index f7e05a3843a30968f834ed93ca6349ee4c4a3c16..c3ed542a844b391b52cc94262d7df3327e8d92c7 100644 --- a/src/main/java/model/automata/GameOfLifeAutomaton.java +++ b/src/main/java/model/automata/GameOfLifeAutomaton.java @@ -8,7 +8,6 @@ public class GameOfLifeAutomaton implements CellularAutomaton<GameOfLifeState> { private final int numberOfColumns; private final int numberOfRows; - //(j'ai ecrit un message a moi-meme) return tipine dikkat et public GameOfLifeAutomaton(int numberOfColumns, int numberOfRows) { this.numberOfColumns = numberOfColumns; @@ -33,6 +32,5 @@ public class GameOfLifeAutomaton implements CellularAutomaton<GameOfLifeState> { @Override public GameOfLifeState randomState(Random generator) { return generator.nextBoolean() ? GameOfLifeState.ALIVE : GameOfLifeState.DEAD; - // message a moi-meme : dikkat et!! } } \ No newline at end of file