From d16b0732cd0253950dfd66327a4a28584e1a11cd Mon Sep 17 00:00:00 2001 From: Yanis O <oualanyanis01@gmail.com> Date: Wed, 13 Nov 2024 14:55:36 +0100 Subject: [PATCH] =?UTF-8?q?[Refac]=20D=C3=A9l=C3=A9gation=20de=20la=20logi?= =?UTF-8?q?que=20de=20Fire=20=C3=A0=20sa=20propre=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/resources/main/view/view.fxml | 42 ++++---- src/main/java/app/SimulatorApplication.java | 4 +- src/main/java/model/Board.java | 2 + src/main/java/model/Fire.java | 25 ++++- src/main/java/model/FireFighter.java | 4 +- src/main/java/model/FireFighterScenario.java | 105 ++++++++++++++----- src/main/java/util/Matrix.java | 7 ++ src/main/resources/view/view.fxml | 42 ++++---- src/test/java/view/FirefighterGridTest.java | 8 +- 9 files changed, 167 insertions(+), 72 deletions(-) diff --git a/build/resources/main/view/view.fxml b/build/resources/main/view/view.fxml index 336ffa3..6c1059b 100644 --- a/build/resources/main/view/view.fxml +++ b/build/resources/main/view/view.fxml @@ -1,37 +1,43 @@ <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.Separator?> +<?import javafx.scene.control.ToggleButton?> <?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.VBox?> <?import view.FirefighterGrid?> -<?import javafx.scene.control.ToggleButton?> -<?import javafx.scene.control.Separator?> -<?import javafx.scene.control.Label?> <HBox styleClass="background" stylesheets="@DarkTheme.css" - xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" + xmlns="http://javafx.com/javafx" + xmlns:fx="http://javafx.com/fxml" fx:controller="controller.Controller"> <VBox> <Separator maxHeight="-Infinity" maxWidth="-Infinity" - prefHeight="24.0" prefWidth="200.0"/> - <Label maxHeight="-Infinity" maxWidth="-Infinity" alignment="CENTER" prefHeight="24.0" prefWidth="200.0" - text="Generation number"/> - <Label fx:id="generationNumberLabel" alignment="CENTER" contentDisplay="TEXT_ONLY" - maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="24.0" prefWidth="200.0"/> + prefHeight="24.0" prefWidth="200.0" /> + <Label maxHeight="-Infinity" maxWidth="-Infinity" + alignment="CENTER" prefHeight="24.0" prefWidth="200.0" + text="Generation number" /> + <Label fx:id="generationNumberLabel" + alignment="CENTER" contentDisplay="TEXT_ONLY" + maxHeight="-Infinity" maxWidth="-Infinity" + prefHeight="24.0" prefWidth="200.0" /> <Separator maxHeight="-Infinity" maxWidth="-Infinity" - prefHeight="24.0" prefWidth="200.0"/> + prefHeight="24.0" prefWidth="200.0" /> <Button fx:id="restartButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#restartButtonAction" prefHeight="24.0" prefWidth="200.0" - text="Restart"/> + mnemonicParsing="false" onAction="#restartButtonAction" + prefHeight="24.0" prefWidth="200.0" text="Restart" /> <Button fx:id="oneStepButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#oneStepButtonAction" prefHeight="24.0" prefWidth="200.0" - text="One step"/> + mnemonicParsing="false" onAction="#oneStepButtonAction" + prefHeight="24.0" prefWidth="200.0" text="One step" /> <ToggleButton fx:id="playToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#playToggleButtonAction" prefHeight="24.0" - prefWidth="200.0" styleClass="button" text="Play"/> + mnemonicParsing="false" onAction="#playToggleButtonAction" + prefHeight="24.0" prefWidth="200.0" + styleClass="button" text="Play" /> <ToggleButton fx:id="pauseToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#pauseToggleButtonAction" prefHeight="24.0" - prefWidth="200.0" styleClass="button" text="Pause"/> + mnemonicParsing="false" onAction="#pauseToggleButtonAction" + prefHeight="24.0" prefWidth="200.0" + styleClass="button" text="Pause" /> </VBox> <FirefighterGrid fx:id="grid" xmlns="http://javafx.com/javafx" diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java index e1778df..86abb85 100644 --- a/src/main/java/app/SimulatorApplication.java +++ b/src/main/java/app/SimulatorApplication.java @@ -15,8 +15,8 @@ public class SimulatorApplication extends javafx.application.Application { private static final String APP_NAME = "Firefighter simulator"; private static final int ROW_COUNT = 20; private static final int COLUMN_COUNT = 20; - private static final int BOX_WIDTH = 50; - private static final int BOX_HEIGHT = 50; + private static final int BOX_WIDTH = 25; + private static final int BOX_HEIGHT = 25; public static final int INITIAL_FIRE_COUNT = 3; public static final int INITIAL_FIREFIGHTER_COUNT = 6; diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java index 30baf94..b25b421 100644 --- a/src/main/java/model/Board.java +++ b/src/main/java/model/Board.java @@ -64,5 +64,7 @@ public interface Board<S> { // Le booléen replaceState permet de forcer le remplacement des cases vides public void setState(Entity state, Position position, boolean replaceStates); + + public boolean doesPositionExist(Position position); } diff --git a/src/main/java/model/Fire.java b/src/main/java/model/Fire.java index c350082..7e54fc2 100644 --- a/src/main/java/model/Fire.java +++ b/src/main/java/model/Fire.java @@ -1,4 +1,8 @@ package model; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import javafx.scene.paint.Color; import util.Position; @@ -12,8 +16,27 @@ public class Fire implements Entity{ @Override public void nextTurn(Board<Entity> board) { - + List<Position> positions = generateAdjacentPosition(); + for(Position p : positions){ + board.setState(new Fire(p, board), p); + } } + + private List<Position> generateAdjacentPosition(){ + int x = position.x(); + int y = position.y(); + + return Stream.of( + new Position(x, y + 1), + new Position(x + 1, y), + new Position(x, y - 1), + new Position(x - 1, y) + ) + .filter(p -> b.doesPositionExist(p)) + .collect(Collectors.toList()); + } + + @Override public void setPosition(Position p) { this.position = p; diff --git a/src/main/java/model/FireFighter.java b/src/main/java/model/FireFighter.java index aea07f0..8a78412 100644 --- a/src/main/java/model/FireFighter.java +++ b/src/main/java/model/FireFighter.java @@ -5,9 +5,11 @@ import util.Position; public class FireFighter implements Entity{ private Position position; private final Color viewColor = Color.BLUE; + private Board<Entity> board; - public FireFighter(Position position){ + public FireFighter(Position position, Board<Entity> b){ this.position = position; + this.board = b; } public void nextTurn(Board<Entity> b){ diff --git a/src/main/java/model/FireFighterScenario.java b/src/main/java/model/FireFighterScenario.java index a01a9dd..5533077 100644 --- a/src/main/java/model/FireFighterScenario.java +++ b/src/main/java/model/FireFighterScenario.java @@ -1,77 +1,126 @@ package model; + import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Random; import util.Matrix; import util.Position; +public class FireFighterScenario extends EntityScenario implements Board<Entity> { -public class FireFighterScenario extends EntityScenario implements Board<Entity>{ - private Matrix<Entity> matrix; private int step; - public FireFighterScenario(int columns, int rows, int initialFireCount, int initialFireFightersCount){ - this.matrix = new Matrix<Entity>(columns, rows); + public FireFighterScenario(int columns, int rows, int initialFireCount, int initialFireFightersCount) { + this.matrix = new Matrix<Entity>(columns, rows); + initScenario(matrix); + placeInitialActors(initialFireCount, initialFireFightersCount); this.step = 0; } - public Entity getState(Position position){ - if(position.x() > matrix.size() || position.y() > matrix.size()){ - throw new IllegalArgumentException("The position x:" + position.x() + " y:" + position.y() + " is out of the board."); + +private void placeInitialActors(int initialFireCount, int initialFireFightersCount) { + int fireCount = 0; + int fireFighterCount = 0; + int chance = 5; // Chance initiale en pourcentage + Random random = new Random(); + + List<Position> positions = new ArrayList<>(); + for (int x = 0; x < matrix.getRows(); x++) { + for (int y = 0; y < matrix.getColumns(); y++) { + positions.add(new Position(x, y)); + } + } + + while (fireCount < initialFireCount || fireFighterCount < initialFireFightersCount) { + Collections.shuffle(positions); // Mélange les positions pour un parcours aléatoire + + for (Position pos : positions) { + if (getState(pos) instanceof EmptySquare) { + if (fireCount < initialFireCount && random.nextInt(100) < chance) { + setState(new Fire(pos, this), pos); + fireCount++; + if (fireCount == initialFireCount && fireFighterCount == initialFireFightersCount) { + return; + } + continue; + } + + if (fireFighterCount < initialFireFightersCount && random.nextInt(100) < chance) { + setState(new FireFighter(pos, this), pos); + fireFighterCount++; + if (fireCount == initialFireCount && fireFighterCount == initialFireFightersCount) { + return; + } + } + } + } + + // Augmente la chance de placement après chaque parcours complet + chance = Math.min(chance + 5, 100); // Ne dépasse pas 100% + } +} + + + public Entity getState(Position position) { + if (position.x() > matrix.size() || position.y() > matrix.size()) { + throw new IllegalArgumentException( + "The position x:" + position.x() + " y:" + position.y() + " is out of the board."); } return matrix.get(position.x(), position.y()); } - public void setState(Entity state, Position position){ - if(!(getState(position) instanceof EmptySquare)){ + public void setState(Entity state, Position position) { + if (!(getState(position) instanceof EmptySquare)) { return; } matrix.set(position.x(), position.y(), state); } - // Le booléen replaceState permet de forcer le remplacement des cases vides - public void setState(Entity state, Position position, boolean replaceStates){ - if(!(getState(position) instanceof EmptySquare) && !replaceStates){ + public void setState(Entity state, Position position, boolean replaceStates) { + if (!(getState(position) instanceof EmptySquare) && !replaceStates) { return; } matrix.set(position.x(), position.y(), state); } - - public int rowCount(){ + public int rowCount() { return matrix.getRows(); } - public int columnCount(){ + public int columnCount() { return matrix.getColumns(); } public List<Position> updateToNextGeneration() { ArrayList<Position> changedPositions = new ArrayList<>(); - Iterator<Entity> iterator = matrix.iterator(); + Iterator<Entity> iterator = matrix.iterator(); while (iterator.hasNext()) { - Entity e = iterator.next(); - Position p = new Position(e.getPosition().x(), e.getPosition().y()); - e.nextTurn(this); + Entity e = iterator.next(); + Position p = new Position(e.getPosition().x(), e.getPosition().y()); + e.nextTurn(this); - if (!e.getPosition().equals(p)) { - changedPositions.add(p); - } + if (!e.getPosition().equals(p)) { + changedPositions.add(p); + } } return changedPositions; -} - - + } - public void reset(){ + public void reset() { matrix.clear(); } - - public int stepNumber(){ + public int stepNumber() { this.step++; return this.step; } + + @Override + public boolean doesPositionExist(Position position) { + return matrix.validateIndexes(position); + } } diff --git a/src/main/java/util/Matrix.java b/src/main/java/util/Matrix.java index 38c6109..7d8f97f 100644 --- a/src/main/java/util/Matrix.java +++ b/src/main/java/util/Matrix.java @@ -56,6 +56,8 @@ public class Matrix<E> implements Iterable<E> { public int getRows(){ return this.rows; } + /* + public void displayMatrix() { System.out.print(" "); for (int j = 0; j < columns; j++) { @@ -80,12 +82,17 @@ public class Matrix<E> implements Iterable<E> { System.out.println(); } } + */ private void validateIndexes(int x, int y) { if (x < 0 || x >= rows || y < 0 || y >= columns) { throw new IndexOutOfBoundsException("Indices x: "+ x + " y: " + y + " hors limites pour la matrice."); } } + + public boolean validateIndexes(Position position){ + return position.x() < 0 || position.x() >= rows || position.y() < 0 || position.y() >= columns; + } diff --git a/src/main/resources/view/view.fxml b/src/main/resources/view/view.fxml index 336ffa3..6c1059b 100644 --- a/src/main/resources/view/view.fxml +++ b/src/main/resources/view/view.fxml @@ -1,37 +1,43 @@ <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.Separator?> +<?import javafx.scene.control.ToggleButton?> <?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.VBox?> <?import view.FirefighterGrid?> -<?import javafx.scene.control.ToggleButton?> -<?import javafx.scene.control.Separator?> -<?import javafx.scene.control.Label?> <HBox styleClass="background" stylesheets="@DarkTheme.css" - xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" + xmlns="http://javafx.com/javafx" + xmlns:fx="http://javafx.com/fxml" fx:controller="controller.Controller"> <VBox> <Separator maxHeight="-Infinity" maxWidth="-Infinity" - prefHeight="24.0" prefWidth="200.0"/> - <Label maxHeight="-Infinity" maxWidth="-Infinity" alignment="CENTER" prefHeight="24.0" prefWidth="200.0" - text="Generation number"/> - <Label fx:id="generationNumberLabel" alignment="CENTER" contentDisplay="TEXT_ONLY" - maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="24.0" prefWidth="200.0"/> + prefHeight="24.0" prefWidth="200.0" /> + <Label maxHeight="-Infinity" maxWidth="-Infinity" + alignment="CENTER" prefHeight="24.0" prefWidth="200.0" + text="Generation number" /> + <Label fx:id="generationNumberLabel" + alignment="CENTER" contentDisplay="TEXT_ONLY" + maxHeight="-Infinity" maxWidth="-Infinity" + prefHeight="24.0" prefWidth="200.0" /> <Separator maxHeight="-Infinity" maxWidth="-Infinity" - prefHeight="24.0" prefWidth="200.0"/> + prefHeight="24.0" prefWidth="200.0" /> <Button fx:id="restartButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#restartButtonAction" prefHeight="24.0" prefWidth="200.0" - text="Restart"/> + mnemonicParsing="false" onAction="#restartButtonAction" + prefHeight="24.0" prefWidth="200.0" text="Restart" /> <Button fx:id="oneStepButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#oneStepButtonAction" prefHeight="24.0" prefWidth="200.0" - text="One step"/> + mnemonicParsing="false" onAction="#oneStepButtonAction" + prefHeight="24.0" prefWidth="200.0" text="One step" /> <ToggleButton fx:id="playToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#playToggleButtonAction" prefHeight="24.0" - prefWidth="200.0" styleClass="button" text="Play"/> + mnemonicParsing="false" onAction="#playToggleButtonAction" + prefHeight="24.0" prefWidth="200.0" + styleClass="button" text="Play" /> <ToggleButton fx:id="pauseToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" - mnemonicParsing="false" onAction="#pauseToggleButtonAction" prefHeight="24.0" - prefWidth="200.0" styleClass="button" text="Pause"/> + mnemonicParsing="false" onAction="#pauseToggleButtonAction" + prefHeight="24.0" prefWidth="200.0" + styleClass="button" text="Pause" /> </VBox> <FirefighterGrid fx:id="grid" xmlns="http://javafx.com/javafx" diff --git a/src/test/java/view/FirefighterGridTest.java b/src/test/java/view/FirefighterGridTest.java index 4b45ebd..dfcdf5d 100644 --- a/src/test/java/view/FirefighterGridTest.java +++ b/src/test/java/view/FirefighterGridTest.java @@ -1,20 +1,20 @@ package view; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.*; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; public class FirefighterGridTest { @Test void testColumnCount(){ Grid<ViewElement> grid = new FirefighterGrid(); - grid.setDimensions(20,10,10,10); + grid.setDimensions(20,10,5,5); assertThat(grid.columnCount()).isEqualTo(20); } @Test void testRowCount(){ Grid<ViewElement> grid = new FirefighterGrid(); - grid.setDimensions(20,10,10,10); + grid.setDimensions(20,10,5,5); assertThat(grid.rowCount()).isEqualTo(10); } } -- GitLab