Skip to content
Snippets Groups Projects
Commit deacc664 authored by SAHIN Melis damla's avatar SAHIN Melis damla
Browse files

TP

parent 6adaf247
No related branches found
No related tags found
No related merge requests found
Pipeline #45493 passed
...@@ -43,7 +43,6 @@ public class ListMatrix<T> implements Matrix<T> { ...@@ -43,7 +43,6 @@ public class ListMatrix<T> implements Matrix<T> {
} }
matrix.add(column); matrix.add(column);
} }
} }
......
package model; package model;
import model.automata.GameOfLifeAutomaton;
import model.automata.GameOfLifeState;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -14,16 +11,17 @@ import java.util.List; ...@@ -14,16 +11,17 @@ import java.util.List;
*/ */
public class Cell<T> implements Lens<T> { public class Cell<T> implements Lens<T> {
private T content;
// la liste des objets écoutant les modifications du contenu de la cellule // la liste des objets écoutant les modifications du contenu de la cellule
private final List<OnChangeListener<T>> listeners = new ArrayList<>(); private final List<OnChangeListener<T>> listeners = new ArrayList<>();
private T initialContent;
/** Initialize a new cell with a given value. /** Initialize a new cell with a given value.
* *
* @param initialContent the value initially stored by the cell. * @param initialContent the value initially stored by the cell.
*/ */
public Cell(T initialContent) { public Cell(T initialContent) {
this.initialContent = initialContent; this.content = initialContent;
} }
/** Add a {@link OnChangeListener} to react to any change of value in the cell. /** Add a {@link OnChangeListener} to react to any change of value in the cell.
...@@ -42,11 +40,11 @@ public class Cell<T> implements Lens<T> { ...@@ -42,11 +40,11 @@ public class Cell<T> implements Lens<T> {
* @param value the new content of this {@link Cell} * @param value the new content of this {@link Cell}
*/ */
public void set(T value) { public void set(T value) {
T oldValue = initialContent; T oldValue = this.content;
initialContent = value; this.content = value;
for (OnChangeListener<T> L : listeners) { for (OnChangeListener<T> listener : listeners) {
L.valueChanged(oldValue, value); listener.valueChanged(oldValue, value);
} }
} }
...@@ -56,6 +54,8 @@ public class Cell<T> implements Lens<T> { ...@@ -56,6 +54,8 @@ public class Cell<T> implements Lens<T> {
* @return the current content of this {@link Cell} * @return the current content of this {@link Cell}
*/ */
public T get(){ public T get(){
return initialContent; return this.content;
} }
} }
...@@ -4,19 +4,19 @@ import controller.Simulation; ...@@ -4,19 +4,19 @@ import controller.Simulation;
import matrix.Coordinate; import matrix.Coordinate;
import matrix.ListMatrix; import matrix.ListMatrix;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import model.*;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Random; import java.util.Random;
/** /**
* {@link CellularAutomatonSimulation} instances run <i>The Game of Life</i>. * {@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 ListMatrix<Cell<S>> grid;
private final Cell<Integer> generationNumber = new Cell<>(0); private final Cell<Integer> generationNumber = new Cell<>(0);
...@@ -39,14 +39,15 @@ public class CellularAutomatonSimulation<S extends State<S>> implements Simulati ...@@ -39,14 +39,15 @@ public class CellularAutomatonSimulation<S extends State<S>> implements Simulati
this.generator = generator; this.generator = generator;
} }
@Override @Override
public int numberOfColumns() { public int numberOfColumns() {
return this.grid.width(); return automaton.numberOfColumns();
} }
@Override @Override
public int numberOfRows() { public int numberOfRows() {
return this.grid.height(); return automaton.numberOfRows();
} }
/** /**
...@@ -56,86 +57,45 @@ public class CellularAutomatonSimulation<S extends State<S>> implements Simulati ...@@ -56,86 +57,45 @@ public class CellularAutomatonSimulation<S extends State<S>> implements Simulati
* @return The cell at the specified coordinate. * @return The cell at the specified coordinate.
*/ */
public Cell<S> at(Coordinate coordinate) { public Cell<S> at(Coordinate coordinate) {
return this.grid.get(coordinate.x(), coordinate.y()); return grid.get(coordinate);
} }
@Override @Override
public void updateToNextGeneration() { public void updateToNextGeneration() {
ListMatrix<Cell<S>> nextMatrix = nextGenerationMatrix(); ListMatrix<S> nextStates = nextGenerationMatrix();
for (Coordinate coordinate : this.grid.coordinates()) { for (Coordinate coordinate : grid.coordinates()) {
this.grid.get(coordinate.x(), coordinate.y()) grid.get(coordinate).set(nextStates.get(coordinate));
.set(nextMatrix.get(coordinate.x(), coordinate.y()).get());
} }
this.generationNumber.set(this.generationNumber.get() + 1); // Increment generation number generationNumber.set(generationNumber.get() + 1);
} }
/** /** 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. * of the simulation.
* *
* @return the states of each cell after one generation * @return the states of each cell after one generation
*/ */
private ListMatrix<Cell<S>> nextGenerationMatrix() { private ListMatrix<S> nextGenerationMatrix() {
ListMatrix<Cell<S>> nextGrid = new ListMatrix<>( return new ListMatrix<>(
this.grid.width(), numberOfColumns(),
this.grid.height(), numberOfRows(),
new ConstantCellInitializer<>(automaton.defaultState()) // Pass the state directly new NextGenerationInitializer<>(this)
); );
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 @Override
public void next(Coordinate coordinate) { public void next(Coordinate coordinate) {
Cell<S> cell = this.at(coordinate); Cell<S> cell = at(coordinate);
List<S> neighbors = getNeighbors(coordinate); cell.set(cell.get().next());
S nextState = cell.get().update(neighbors);
cell.set(nextState);
} }
@Override @Override
public void copy(Coordinate source, Coordinate destination) { public void copy(Coordinate source, Coordinate destination) {
S sourceState = this.at(source).get(); Cell<S> sourceCell = at(source);
this.at(destination).set(sourceState); at(destination).set(sourceCell.get());
} }
@Override @Override
public Color getColor(Coordinate coordinate) { public Color getColor(Coordinate coordinate) {
return this.at(coordinate).get().getColor(); return at(coordinate).get().getColor();
} }
@Override @Override
...@@ -150,24 +110,28 @@ public class CellularAutomatonSimulation<S extends State<S>> implements Simulati ...@@ -150,24 +110,28 @@ public class CellularAutomatonSimulation<S extends State<S>> implements Simulati
this.generationNumber.addOnChangeListener(listener); this.generationNumber.addOnChangeListener(listener);
} }
@Override @Override
public void clear() { public void clear() {
for (Coordinate coordinate : this.grid.coordinates()) { for(Coordinate coordinate : grid.coordinates()) {
this.at(coordinate).set(this.automaton.defaultState()); at(coordinate).set(automaton.defaultState());
} }
this.generationNumber.set(0); // Reset generation counter generationNumber.set(0);
} }
@Override @Override
public void reset() { public void reset() {
for (Coordinate coordinate : this.grid.coordinates()) { for(Coordinate coordinate : grid.coordinates()) {
this.grid.set(coordinate.x(), coordinate.y(), new Cell<>(this.automaton.defaultState())); at(coordinate).set(automaton.randomState(generator));
} }
this.generationNumber.set(0); generationNumber.set(0);
} }
@Override @Override
public Iterator<Coordinate> iterator() { public Iterator<Coordinate> iterator() {
return this.grid.coordinates().iterator(); return this.grid.coordinates().iterator();
} }
} }
\ No newline at end of file
...@@ -31,14 +31,15 @@ public class NextGenerationInitializer<S extends State<S>> implements MatrixInit ...@@ -31,14 +31,15 @@ public class NextGenerationInitializer<S extends State<S>> implements MatrixInit
@Override @Override
public S initialValueAt(Coordinate coordinate) { public S initialValueAt(Coordinate coordinate) {
List<Coordinate> coordinates = coordinate.orthogonalNeighbours(); List<Coordinate> neighborCoordinates = coordinate.orthodiagonalNeighbours();
List<S> states = new ArrayList<>(); List<S> neighborStates = new ArrayList<>();
for (Coordinate c : coordinates) {
states.add(simulation.at(this.wrap(c)).get()); for (Coordinate neighbor : neighborCoordinates) {
} neighborStates.add(simulation.at(this.wrap(neighbor)).get());
return simulation.at(coordinate).get().update(states);
} }
return simulation.at(coordinate).get().update(neighborStates);
}
/** Computes the grid {@link Coordinate} for an arbitrary {@link Coordinate}, even outside /** Computes the grid {@link Coordinate} for an arbitrary {@link Coordinate}, even outside
* the grid. This is done by considering that the grid wraps over its edges, connecting the left side to the right * the grid. This is done by considering that the grid wraps over its edges, connecting the left side to the right
* side, and the top side to the bottom side. This way, every cell has 4 orthogonal * side, and the top side to the bottom side. This way, every cell has 4 orthogonal
......
...@@ -4,6 +4,7 @@ import javafx.scene.paint.Color; ...@@ -4,6 +4,7 @@ import javafx.scene.paint.Color;
import model.State; import model.State;
import java.util.List; import java.util.List;
import java.util.Random;
/** /**
* {@link GameOfLifeState} instances represent the possible states of a {@link GameOfLifeState}. * {@link GameOfLifeState} instances represent the possible states of a {@link GameOfLifeState}.
...@@ -11,61 +12,27 @@ import java.util.List; ...@@ -11,61 +12,27 @@ import java.util.List;
public enum GameOfLifeState implements State<GameOfLifeState> { public enum GameOfLifeState implements State<GameOfLifeState> {
ALIVE, DEAD; ALIVE, DEAD;
@Override @Override
public Color getColor() { public Color getColor() {
switch (this) { return this == ALIVE ? Color.RED : Color.WHITE;
case ALIVE:
return Color.RED;
case DEAD:
return Color.WHITE;
default:
return Color.WHITE;
}
} }
/* correction avec if :
if this.equals(ALIVE) {
return COLOR.RED;
else {
return COLOR.WHITE;
*/
@Override @Override
public GameOfLifeState next() { public GameOfLifeState next() {
switch (this) { return this == ALIVE ? DEAD : ALIVE;
case ALIVE:
return DEAD;
case DEAD:
return ALIVE;
default:
return DEAD;
} }
}
/* correction avec if :
if this.equals(ALIVE) {
return DEAD;
else {
return ALIVE;
*/
@Override @Override
public GameOfLifeState update(List<GameOfLifeState> neighbours) { public GameOfLifeState update(List<GameOfLifeState> neighbors) {
int count = State.count(ALIVE, neighbours); int aliveCount = State.count(ALIVE, neighbors);
switch (this) {
case DEAD: if (this == ALIVE) {
if (count == 3) { return (aliveCount == 2 || aliveCount == 3) ? ALIVE : DEAD;
return ALIVE; } else {
} return (aliveCount == 3) ? ALIVE : DEAD;
break;
case ALIVE:
if (count == 3) {
return ALIVE;
} else if (count == 2) {
return ALIVE;
} }
break;
} }
return DEAD; public GameOfLifeState randomState(Random generator) {
return generator.nextBoolean() ? GameOfLifeState.ALIVE : GameOfLifeState.DEAD;
} }
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment