Skip to content
Snippets Groups Projects
Commit ac3e3620 authored by Guyslain's avatar Guyslain
Browse files

Version template du projet

parent 39f46b80
Branches
Tags template
No related merge requests found
Showing
with 90 additions and 337 deletions
......@@ -7,8 +7,7 @@ import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import model.CellularAutomatonSimulation;
import model.automata.BiColorAutomaton;
import model.automata.SeedsAutomaton;
import model.automata.GameOfLifeAutomaton;
import java.io.IOException;
import java.net.URL;
......@@ -38,7 +37,7 @@ public class SimulatorApplication extends Application {
public SimulatorApplication() {
this.simulation =
new CellularAutomatonSimulation<>(
new BiColorAutomaton(NUMBER_OF_COLUMNS,NUMBER_OF_ROWS),
new GameOfLifeAutomaton(NUMBER_OF_COLUMNS,NUMBER_OF_ROWS),
GENERATOR
);
}
......
......@@ -51,13 +51,6 @@ public class Controller {
}
/**
* Sets {@link CellularAutomatonSimulation} instance.
*
* @param simulation {@link CellularAutomatonSimulation} instance
* @throws NullPointerException if {@code gameOfLife} is {@code null}
*/
public void setSimulation(Simulation simulation) {
this.simulation = requireNonNull(simulation, "game of life is null");
setGenerationNumberLabelTextProperty();
......
......@@ -16,7 +16,8 @@ public record Coordinate(int x, int y) {
* @return A new {@link Coordinate} instance.
*/
public static Coordinate of(int x, int y) {
return new Coordinate(x, y);
// TODO: compléter ce fabriquant
return null;
}
/**
......@@ -25,7 +26,8 @@ public record Coordinate(int x, int y) {
* @return The left adjacent {@link Coordinate}.
*/
public Coordinate left() {
return new Coordinate(x - 1, y);
// TODO: à compléter
return null;
}
/**
......@@ -34,7 +36,8 @@ public record Coordinate(int x, int y) {
* @return The right adjacent {@link Coordinate}.
*/
public Coordinate right() {
return new Coordinate(x + 1, y);
// TODO: à compléter
return null;
}
/**
......@@ -43,7 +46,8 @@ public record Coordinate(int x, int y) {
* @return The above adjacent {@link Coordinate}.
*/
public Coordinate above() {
return new Coordinate(x, y + 1);
// TODO: à compléter
return null;
}
/**
......@@ -52,7 +56,8 @@ public record Coordinate(int x, int y) {
* @return The below adjacent {@link Coordinate}.
*/
public Coordinate below() {
return new Coordinate(x, y - 1);
// TODO: à compléter
return null;
}
/**
......@@ -61,12 +66,8 @@ public record Coordinate(int x, int y) {
* @return A list of orthogonal neighboring {@link Coordinate}s.
*/
public List<Coordinate> orthogonalNeighbours() {
return List.of(
this.right(),
this.left(),
this.above(),
this.below()
);
// TODO: à compléter
return List.of();
}
/**
......@@ -75,12 +76,8 @@ public record Coordinate(int x, int y) {
* @return A list of diagonal neighboring {@link Coordinate}s.
*/
public List<Coordinate> diagonalNeighbours() {
return List.of(
this.right().above(),
this.left().above(),
this.left().below(),
this.right().below()
);
// TODO: à compléter
return List.of();
}
/**
......@@ -89,9 +86,8 @@ public record Coordinate(int x, int y) {
* @return A list of all neighboring {@link Coordinate}s.
*/
public List<Coordinate> orthodiagonalNeighbours() {
List<Coordinate> neighbours = new ArrayList<>(this.orthogonalNeighbours());
neighbours.addAll(this.diagonalNeighbours());
return neighbours;
// TODO: à compléter
return List.of();
}
@Override
......
......@@ -8,10 +8,6 @@ import java.util.NoSuchElementException;
* height range.
*/
class CoordinateIterator implements Iterator<Coordinate> {
private final int width;
private final int height;
private int x = 0;
private int y = 0;
/**
* Creates a new {@link CoordinateIterator} with the specified width and height.
......@@ -20,8 +16,7 @@ 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;
// TODO: à compléter
}
/**
......@@ -31,7 +26,8 @@ class CoordinateIterator implements Iterator<Coordinate> {
*/
@Override
public boolean hasNext() {
return y < this.height;
// TODO: à compléter
return false;
}
/**
......@@ -42,15 +38,7 @@ class CoordinateIterator implements Iterator<Coordinate> {
*/
@Override
public Coordinate next() {
if (!this.hasNext()) {
throw new NoSuchElementException();
}
Coordinate coordinate = new Coordinate(this.x, this.y);
this.x = this.x + 1;
if (this.x == this.width) {
this.x = 0;
this.y = this.y + 1;
}
return coordinate;
// TODO: à compléter
return null;
}
}
......@@ -12,7 +12,10 @@ import java.util.List;
* @param <T> The type of value stored in the cell.
*/
public class Cell<T> implements Lens<T> {
private T content;
//TODO: ajouter la ou les propriétés nécessaires
// la liste des objets écoutant les modifications du contenu de la cellule
private final List<OnChangeListener<T>> listeners = new ArrayList<>();
/** Initialize a new cell with a given value.
......@@ -20,7 +23,7 @@ public class Cell<T> implements Lens<T> {
* @param initialContent the value initially stored by the cell.
*/
public Cell(T initialContent) {
this.content = initialContent;
//TODO: à compléter
}
/** Add a {@link OnChangeListener} to react to any change of value in the cell.
......@@ -39,11 +42,8 @@ public class Cell<T> implements Lens<T> {
* @param value the new content of this {@link Cell}
*/
public void set(T value) {
T oldValue = this.content;
this.content = value;
for (OnChangeListener<T> listener : this.listeners) {
listener.valueChanged(oldValue, value);
}
//TODO: modifier le contenu de la cellule, puis appeler les méthodes valueChanged des
// listeners
}
/**
......@@ -52,6 +52,7 @@ public class Cell<T> implements Lens<T> {
* @return the current content of this {@link Cell}
*/
public T get(){
return this.content;
//TODO: à compléter
return null;
}
}
......@@ -42,12 +42,14 @@ public class CellularAutomatonSimulation<S extends State<S>>
@Override
public int numberOfColumns() {
return this.grid.width();
//TODO: à compléter
return 0;
}
@Override
public int numberOfRows() {
return this.grid.height();
//TODO: à compléter
return 0;
}
/**
......@@ -57,16 +59,13 @@ public class CellularAutomatonSimulation<S extends State<S>>
* @return The cell at the specified coordinate.
*/
public Cell<S> at(Coordinate coordinate) {
return this.grid.get(coordinate);
//TODO: à compléter
return null;
}
@Override
public void updateToNextGeneration() {
this.generationNumber.set(this.generationNumber.get()+1);
Matrix<S> nextStates = this.nextGenerationMatrix();
for (Coordinate coordinate : this.grid.coordinates()) {
this.at(coordinate).set(nextStates.get(coordinate));
}
//TODO: à compléter, en utilisant nextGenerationMatrix()
}
/** Computes the {@link Matrix} of states obtained after a single step of updates
......@@ -75,27 +74,23 @@ public class CellularAutomatonSimulation<S extends State<S>>
* @return the states of each cell after one generation
*/
private Matrix<S> nextGenerationMatrix() {
return new Matrix<>(
this.grid.width(),
this.grid.height(),
new NextGenerationInitializer<>(this)
);
//TODO: à compléter
return null;
}
@Override
public void next(Coordinate coordinate) {
S oldState = this.grid.get(coordinate).get();
this.at(coordinate).set(oldState.next());
//TODO: à compléter
}
@Override
public void copy(Coordinate source, Coordinate destination) {
S state = this.at(source).get();
this.at(destination).set(state);
//TODO: à compléter
}
@Override
public Color getColor(Coordinate coordinate) {
return this.at(coordinate).get().getColor();
//TODO: à compléter
return null;
}
@Override
......@@ -113,19 +108,13 @@ public class CellularAutomatonSimulation<S extends State<S>>
@Override
public void clear() {
for (Cell<S> cell : this.grid) {
cell.set(this.automaton.defaultState());
}
this.generationNumber.set(0);
//TODO: à compléter (penser à remettre le nombre de génération à 0)
}
@Override
public void reset() {
for (Cell<S> cell : this.grid) {
cell.set(this.automaton.randomState(generator));
}
this.generationNumber.set(0);
//TODO: à compléter (penser à remettre le nombre de génération à 0)
}
@Override
......
......@@ -11,7 +11,7 @@ import datastruct.MatrixInitializer;
* @param <T> the type of content of each cell
*/
public class ConstantCellInitializer<T> implements MatrixInitializer<Cell<T>> {
private final T defaultValue;
//TODO: ajouter la/les propriétes nécessaires
/** Make a new {@link MatrixInitializer} with cells containing a {@link Cell} with the same
* value.
......@@ -19,11 +19,12 @@ public class ConstantCellInitializer<T> implements MatrixInitializer<Cell<T>> {
* @param defaultValue the value stored in each cell.
*/
public ConstantCellInitializer(T defaultValue) {
this.defaultValue = defaultValue;
//TODO: à compléter
}
@Override
public Cell<T> initialValueAt(Coordinate coordinate) {
return new Cell<>(defaultValue);
//TODO: à compléter
return null;
}
}
......@@ -15,7 +15,7 @@ import java.util.List;
*/
public class NextGenerationInitializer<S extends State<S>> implements MatrixInitializer<S> {
private final CellularAutomatonSimulation<S> simulation;
//TODO: ajouter les propriétés nécessaires
/** Create a {@link MatrixInitializer} to compute the next generation in
* a 2D cellular automaton.
......@@ -23,18 +23,13 @@ public class NextGenerationInitializer<S extends State<S>> implements MatrixInit
* @param simulation the {@link Simulation} representing the cellular automaton.
*/
public NextGenerationInitializer(CellularAutomatonSimulation<S> simulation) {
this.simulation = simulation;
//TODO: à compléter
}
@Override
public S initialValueAt(Coordinate coordinate) {
List<State<S>> neighbours = new ArrayList<>();
for (Coordinate neighbourCoord : coordinate.orthodiagonalNeighbours()) {
Coordinate wrapped = wrap(neighbourCoord);
neighbours.add(this.simulation.at(wrapped).get());
}
S state = this.simulation.at(coordinate).get();
return state.update(neighbours);
//TODO: à compléter
return null;
}
/** Computes the grid {@link Coordinate} for an arbitrary {@link Coordinate}, even outside
......@@ -45,11 +40,11 @@ public class NextGenerationInitializer<S extends State<S>> implements MatrixInit
* @param coordinate a {@link Coordinate} that may be outside the grid.
* @return a corresponding {@link Coordinate}, that is inside the grid.
*/
private Coordinate wrap(Coordinate coordinate) {
return new Coordinate(
modulo(coordinate.x(),this.simulation.numberOfColumns()),
modulo(coordinate.y(),this.simulation.numberOfRows())
);
Coordinate wrap(Coordinate coordinate) {
//TODO: à compléter
//Il faut recalculer les coordonnées x et y modulo les dimensions de la grille.
//Pour le modulo, utiliser la fonction ci-dessous, qui s'assure que le résultat est positif.
return null;
}
/** The non-negative remainder of n divided by d.
......@@ -58,7 +53,7 @@ public class NextGenerationInitializer<S extends State<S>> implements MatrixInit
* @param d a non-zero integer.
* @return the remainder of {@code n/d}, between {@code 0} and {@code n-1}.
*/
private static int modulo(int n, int d) {
static int modulo(int n, int d) {
int result = n % d;
return n < 0 ? result + d : result;
}
......
......@@ -44,12 +44,7 @@ public interface State<S> {
* @return The number of times the specified state appears in the list of neighbors.
*/
static <T> int count(T state, List<T> neighbours) {
int count = 0;
for (T neighbour : neighbours) {
if (neighbour.equals(state)) {
count++;
}
}
return count;
//TODO: à compléter
return 0;
}
}
\ No newline at end of file
package model.automata;
import model.CellularAutomaton;
import model.State;
public abstract class AbstractAutomaton<S extends State<S>> implements CellularAutomaton<S> {
private final int numberOfColumns;
private final int numberOfRows;
protected AbstractAutomaton(int numberOfColumns, int numberOfRows) {
this.numberOfColumns = numberOfColumns;
this.numberOfRows = numberOfRows;
}
public int numberOfColumns() {
return numberOfColumns;
}
public int numberOfRows() {
return numberOfRows;
}
}
package model.automata;
import java.util.Random;
public class BiColorAutomaton extends AbstractAutomaton<BiColorState> {
public BiColorAutomaton(int numberOfColumns, int numberOfRows) {
super(numberOfColumns, numberOfRows);
}
@Override
public BiColorState defaultState() {
return BiColorState.DEAD;
}
@Override
public BiColorState randomState(Random generator) {
return generator.nextBoolean()? BiColorState.DEAD:
generator.nextBoolean()? BiColorState.RED:
BiColorState.BLUE;
}
}
package model.automata;
import javafx.scene.paint.Color;
import model.State;
import java.util.List;
public enum BiColorState implements State<BiColorState> {
BLUE, RED, DEAD;
@Override
public Color getColor() {
return switch (this) {
case BLUE -> Color.BLUE;
case RED -> Color.RED;
case DEAD -> Color.WHITE;
};
}
@Override
public BiColorState next() {
return switch (this) {
case BLUE -> RED;
case RED -> DEAD;
case DEAD -> BLUE;
};
}
@Override
public BiColorState update(List<BiColorState> neighbours) {
int countBlue = State.count(BLUE, neighbours);
int countRed = State.count(RED, neighbours);
int countAlive = countBlue + countRed;
if (this == DEAD) {
return (countAlive != 3)? DEAD:
countBlue > countRed? BLUE:
RED;
}
return 2 <= countAlive && countAlive <= 3? this:
DEAD;
}
}
package model.automata;
import java.util.Random;
public class BriansBrainAutomaton extends AbstractAutomaton<BriansBrainState> {
public BriansBrainAutomaton(int numberOfColumns, int numberOfRows) {
super(numberOfColumns, numberOfRows);
}
@Override
public BriansBrainState defaultState() {
return BriansBrainState.OFF;
}
@Override
public BriansBrainState randomState(Random generator) {
return generator.nextInt(10) == 0 ?
BriansBrainState.ON:
BriansBrainState.OFF;
}
}
package model.automata;
import javafx.scene.paint.Color;
import model.State;
import java.util.List;
public enum BriansBrainState implements State<BriansBrainState> {
ON, OFF, DYING;
@Override
public Color getColor() {
return switch (this) {
case ON -> Color.WHITE;
case OFF -> Color.BLACK;
case DYING -> Color.BLUE;
};
}
@Override
public BriansBrainState next() {
return switch (this) {
case ON -> DYING;
case OFF -> ON;
case DYING -> OFF;
};
}
@Override
public BriansBrainState update(List<BriansBrainState> neighbours) {
return switch (this) {
case ON -> DYING;
case DYING -> OFF;
case OFF -> {
int count = State.count(ON, neighbours);
yield count==2 ? ON : OFF;
}
};
}
}
package model.automata;
import model.CellularAutomaton;
import java.util.Random;
public class GameOfLifeAutomaton extends AbstractAutomaton<GameOfLifeState> {
public class GameOfLifeAutomaton implements CellularAutomaton<GameOfLifeState> {
public GameOfLifeAutomaton(int numberOfColumns, int numberOfRows) {
super(numberOfColumns, numberOfRows);
//TODO: à compléter
}
@Override
public int numberOfColumns() {
//TODO: à compléter
return 0;
}
@Override
public int numberOfRows() {
//TODO: à compléter
return 0;
}
@Override
public GameOfLifeState defaultState() {
return GameOfLifeState.DEAD;
//TODO: à compléter
return null;
}
@Override
public GameOfLifeState randomState(Random generator) {
return generator.nextBoolean()?
GameOfLifeState.ALIVE:
GameOfLifeState.DEAD;
//TODO: à compléter
return null;
}
}
......@@ -9,31 +9,25 @@ import java.util.List;
* {@link GameOfLifeState} instances represent the possible states of a {@link GameOfLifeState}.
*/
public enum GameOfLifeState implements State<GameOfLifeState> {
ALIVE(Color.RED),
DEAD(Color.WHITE);
ALIVE, DEAD;
public final Color color;
GameOfLifeState(Color color) {
this.color = color;
}
@Override
public Color getColor() {
return this.color;
//TODO: à compléter
return Color.BLACK;
}
@Override
public GameOfLifeState next() {
return GameOfLifeState.values()[1 - this.ordinal()];
//TODO: à compléter
return null;
}
@Override
public GameOfLifeState update(List<GameOfLifeState> neighbours) {
int countAlive = State.count(ALIVE, neighbours);
return (countAlive == 3 || this == ALIVE && countAlive == 2)?
ALIVE:
DEAD;
//TODO: à compléter
return null;
}
}
package model.automata;
import java.util.Random;
public class SeedsAutomaton extends AbstractAutomaton<SeedsState> {
public SeedsAutomaton(int numberOfColumns, int numberOfRows) {
super(numberOfColumns, numberOfRows);
}
@Override
public SeedsState defaultState() {
return SeedsState.OFF;
}
@Override
public SeedsState randomState(Random generator) {
return generator.nextInt(10) == 0?
SeedsState.ON:
SeedsState.OFF;
}
}
package model.automata;
import javafx.scene.paint.Color;
import model.State;
import java.util.List;
public enum SeedsState implements State<SeedsState> {
ON, OFF;
@Override
public Color getColor() {
return switch (this) {
case ON -> Color.GOLD;
case OFF -> Color.BLACK;
};
}
@Override
public SeedsState next() {
return switch (this) {
case ON -> OFF;
case OFF -> ON;
};
}
@Override
public SeedsState update(List<SeedsState> neighbours) {
return switch (this) {
case ON -> OFF;
case OFF -> State.count(ON,neighbours) == 2 ? ON: OFF;
};
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment