diff --git a/src/main/java/model/Cloud.java b/src/main/java/model/Cloud.java new file mode 100644 index 0000000000000000000000000000000000000000..9f3647ce44120e361160a60246702211cb75fb89 --- /dev/null +++ b/src/main/java/model/Cloud.java @@ -0,0 +1,134 @@ +package model; + + +import util.Position; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + + +public class Cloud implements Board<List<ModelElement>> { + private final int columnCount; + private final int rowCount; + private List<Position> cloudPositions; + private List<Position> firePositions; + private int step = 0; + private Random randomGenerator = new Random(); + + public Cloud(int columnCount, int rowCount, int initialCloudCount) { + this.columnCount = columnCount; + this.rowCount = rowCount; + initializeElements(initialCloudCount); + } + + public void initializeElements(int initialCloudCount) { + cloudPositions = new ArrayList<>(); + firePositions = new ArrayList<>(); + for (int index = 0; index < initialCloudCount; index++) + cloudPositions.add(randomPosition()); + } + + public Position randomPosition() { + return new Position(randomGenerator.nextInt(rowCount), randomGenerator.nextInt(columnCount)); + } + + public Random getRandomGenerator() { + return randomGenerator; + } + void setRandomGenerator(Random randomGenerator){ + this.randomGenerator=randomGenerator; + + } + + @Override + public List<ModelElement> getState(Position position) { + List<ModelElement> result = new ArrayList<>(); + for (Position cloudPosition : cloudPositions) + if (cloudPosition.equals(position)) + result.add(ModelElement.CLOUD); + if (firePositions.contains(position)) + result.add(ModelElement.FIRE); + return result; + } + + @Override + public int rowCount() { + return rowCount; + } + + @Override + public int columnCount() { + return columnCount; + } + + public List<Position> updateToNextGeneration() { + List<Position> modifiedPositions = new ArrayList<>(); + modifiedPositions.addAll(updateClouds()); + step++; + return modifiedPositions; + } + + private List<Position> updateClouds() { + List<Position> modifiedPositions = new ArrayList<>(); + List<Position> cloudNewPositions = new ArrayList<>(); + for (Position cloudPosition : cloudPositions) { + Position newCloudPosition = randomNeighborPosition(cloudPosition); + cloudNewPositions.add(newCloudPosition); + extinguish(newCloudPosition); + modifiedPositions.add(cloudPosition); + modifiedPositions.add(newCloudPosition); + } + cloudPositions = cloudNewPositions; + return modifiedPositions; + } + + private void extinguish(Position position) { + firePositions.remove(position); + } + + private Position randomNeighborPosition(Position position) { + List<Position> neighbors = new ArrayList<>(); + if (position.row() > 0) neighbors.add(new Position(position.row() - 1, position.column())); + if (position.column() > 0) neighbors.add(new Position(position.row(), position.column() - 1)); + if (position.row() < rowCount - 1) neighbors.add(new Position(position.row() + 1, position.column())); + if (position.column() < columnCount - 1) neighbors.add(new Position(position.row(), position.column() + 1)); + + if (!neighbors.isEmpty()) { + int randomIndex = randomGenerator.nextInt(neighbors.size()); + return neighbors.get(randomIndex); + } else { + // Si aucun voisin n'est disponible, la position reste la même + return position; + } + } + + @Override + public void setState(List<ModelElement> state, Position position) { + firePositions.remove(position); + for (;;) { + if (!cloudPositions.remove(position)) break; + } + for (ModelElement element : state) { + switch (element) { + case FIRE: + firePositions.add(position); + break; + case CLOUD: + cloudPositions.add(position); + break; + } + } + } + + @Override + public void reset() { + step = 0; + initializeElements(cloudPositions.size()); + } + + @Override + public int stepNumber() { + return step; + } +} diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java index 759eee5e54c3a39472d8f7defbbbe6a2b67b8f00..24384beedf2afbb21cdf77ee1eec167d7046799b 100644 --- a/src/main/java/model/ModelElement.java +++ b/src/main/java/model/ModelElement.java @@ -1,5 +1,5 @@ package model; public enum ModelElement { - FIREFIGHTER, FIRE + FIREFIGHTER, CLOUD, FIRE } diff --git a/src/main/java/view/CloudView.java b/src/main/java/view/CloudView.java new file mode 100644 index 0000000000000000000000000000000000000000..38c2fdaed5d21aed7abbfb2ae9aaa7fa486eda2b --- /dev/null +++ b/src/main/java/view/CloudView.java @@ -0,0 +1,90 @@ +package view; +import javafx.scene.canvas.Canvas; +import javafx.scene.paint.Color; +import javafx.util.Pair; +import model.ModelElement; +import util.Position; +import view.Grid; + +import java.util.List; + +public class CloudView extends Canvas implements Grid<ModelElement> { + private int squareWidth; + private int squareHeight; + private int columnCount; + private int rowCount; + + public CloudView(int columnCount, int rowCount, int squareWidth, int squareHeight) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.squareWidth = squareWidth; + this.squareHeight = squareHeight; + setWidth(columnCount * squareWidth); + setHeight(rowCount * squareHeight); + } + + @Override + public void repaint(List<Pair<Position, ModelElement>> elements) { + clear(); + for (Pair<Position, ModelElement> element : elements) { + Position position = element.getKey(); + ModelElement modelElement = element.getValue(); + if (position.row() >= 0 && position.row() < rowCount && position.column() >= 0 && position.column() < columnCount) { + drawModelElement(modelElement, position); + } + } + } + + @Override + public void repaint(ModelElement[][] elements) { + clear(); + for (int row = 0; row < rowCount; row++) { + for (int column = 0; column < columnCount; column++) { + ModelElement modelElement = elements[row][column]; + if (modelElement != null) { + Position position = new Position(row, column); + drawModelElement(modelElement, position); + } + } + } + } + + private void clear() { + getGraphicsContext2D().clearRect(0, 0, getWidth(), getHeight()); + } + + @Override + public int columnCount() { + return columnCount; + } + + @Override + public int rowCount() { + return rowCount; + } + + private void drawModelElement(ModelElement modelElement, Position position) { + int x = position.column() * squareWidth; + int y = position.row() * squareHeight; + + // Dessinez la vue de l'élément (par exemple, le nuage) + switch (modelElement) { + case CLOUD: + getGraphicsContext2D().setFill(Color.YELLOW); + getGraphicsContext2D().fillOval(x, y, squareWidth, squareHeight); + break; + // Ajoutez d'autres cas pour d'autres éléments si nécessaire + } + } + + @Override + public void setDimensions(int columnCount, int rowCount, int squareWidth, int squareHeight) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.squareWidth = squareWidth; + this.squareHeight = squareHeight; + setWidth(columnCount * squareWidth); + setHeight(rowCount * squareHeight); + } +} + diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java index ffb76112e1af543df5af41fa906082ef11be9967..d416eefa5804f5ffafca67aa37cc2a2b230574ce 100644 --- a/src/main/java/view/ViewElement.java +++ b/src/main/java/view/ViewElement.java @@ -3,7 +3,10 @@ package view; import javafx.scene.paint.Color; public enum ViewElement { - FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); + FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE) , CLOUD(Color.YELLOW); + + + final Color color; ViewElement(Color color) { this.color = color; diff --git a/src/test/java/model/CloudTest.java b/src/test/java/model/CloudTest.java new file mode 100644 index 0000000000000000000000000000000000000000..510dfdfc044894594c7851dd00ba3760a91ea945 --- /dev/null +++ b/src/test/java/model/CloudTest.java @@ -0,0 +1,82 @@ +package model; + +import org.junit.jupiter.api.Test; +import model.Cloud; +import model.ModelElement; +import util.Position; +import java.util.List; +import java.util.Random; +import static org.assertj.core.api.Assertions.*; + +public class CloudTest { + @Test + void testInitialState() { + int columnCount = 10; + int rowCount = 10; + int initialCloudCount = 5; + Cloud cloud = new Cloud(columnCount, rowCount, initialCloudCount); + + assertThat(cloud.columnCount()).isEqualTo(columnCount); + assertThat(cloud.rowCount()).isEqualTo(rowCount); + assertThat(cloud.stepNumber()).isEqualTo(0); + } + + @Test + void testUpdateToNextGeneration() { + int columnCount = 10; + int rowCount = 10; + int initialCloudCount = 5; + Cloud cloud = new Cloud(columnCount, rowCount, initialCloudCount); + + List<Position> modifiedPositions = cloud.updateToNextGeneration(); + + // Vérifiez que des positions modifiées ont été renvoyées + assertThat(modifiedPositions).isNotEmpty(); + + // Vérifiez que le nombre d'étapes a augmenté + assertThat(cloud.stepNumber()).isEqualTo(1); + } + + @Test + void testInitialStateContainsClouds() { + int columnCount = 10; + int rowCount = 10; + int initialCloudCount = 5; + Cloud cloud = new Cloud(columnCount, rowCount, initialCloudCount); + + for (int row = 0; row < rowCount; row++) { + for (int column = 0; column < columnCount; column++) { + Position position = new Position(row, column); + List<ModelElement> state = cloud.getState(position); + + if (state.contains(ModelElement.CLOUD)) { + assertThat(state).containsOnly(ModelElement.CLOUD); + } + } + } + } + + @Test + void testCloudMovement() { + int columnCount = 10; + int rowCount = 10; + int initialCloudCount = 1; + Cloud cloud = new Cloud(columnCount, rowCount, initialCloudCount); + + // Utilisez une graine fixe pour Random afin de rendre le test déterministe + Random random = new Random(123); + + // Déplacez le nuage 10 fois avec une graine fixe pour Random + for (int i = 0; i < 10; i++) { + Random originalRandom = cloud.getRandomGenerator(); + cloud.setRandomGenerator(random); + + List<Position> modifiedPositions = cloud.updateToNextGeneration(); + + assertThat(modifiedPositions).isNotEmpty(); + assertThat(cloud.stepNumber()).isEqualTo(i + 1); + + cloud.setRandomGenerator(originalRandom); + } + } +} diff --git a/src/test/java/view/CloudView.java b/src/test/java/view/CloudView.java new file mode 100644 index 0000000000000000000000000000000000000000..3a11830438e3ced0f8c6d6ac48c1888feee0b8ce --- /dev/null +++ b/src/test/java/view/CloudView.java @@ -0,0 +1,90 @@ +package view; + +import javafx.scene.canvas.Canvas; +import javafx.scene.paint.Color; +import javafx.util.Pair; +import model.ModelElement; +import util.Position; +import view.Grid; + +import java.util.List; + +public class CloudView extends Canvas implements Grid<ModelElement> { + private int squareWidth; + private int squareHeight; + private int columnCount; + private int rowCount; + + public CloudView(int columnCount, int rowCount, int squareWidth, int squareHeight) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.squareWidth = squareWidth; + this.squareHeight = squareHeight; + setWidth(columnCount * squareWidth); + setHeight(rowCount * squareHeight); + } + + @Override + public void repaint(List<Pair<Position, ModelElement> > elements) { + clear(); + for (Pair<Position, ModelElement> element : elements) { + Position position = element.getKey(); + ModelElement modelElement = element.getValue(); + if (position.row() >= 0 && position.row() < rowCount && position.column() >= 0 && position.column() < columnCount) { + drawModelElement(modelElement, position); + } + } + } + + @Override + public void repaint(ModelElement[][] elements) { + clear(); + for (int row = 0; row < rowCount; row++) { + for (int column = 0; column < columnCount; column++) { + ModelElement modelElement = elements[row][column]; + if (modelElement != null) { + Position position = new Position(row, column); + drawModelElement(modelElement, position); + } + } + } + } + + private void clear() { + getGraphicsContext2D().clearRect(0, 0, getWidth(), getHeight()); + } + + @Override + public int columnCount() { + return columnCount; + } + + @Override + public int rowCount() { + return rowCount; + } + + private void drawModelElement(ModelElement modelElement, Position position) { + int x = position.column() * squareWidth; + int y = position.row() * squareHeight; + + // Dessinez la vue de l'élément (par exemple, le nuage) + switch (modelElement) { + case CLOUD: + getGraphicsContext2D().setFill(Color.YELLOW); + getGraphicsContext2D().fillRect(x, y, squareWidth, squareHeight); + break; + // Ajoutez d'autres cas pour d'autres éléments si nécessaire + } + } + + @Override + public void setDimensions(int columnCount, int rowCount, int squareWidth, int squareHeight) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.squareWidth = squareWidth; + this.squareHeight = squareHeight; + setWidth(columnCount * squareWidth); + setHeight(rowCount * squareHeight); + } +}