diff --git a/.gradle/8.10.2/executionHistory/executionHistory.bin b/.gradle/8.10.2/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..443d4d5ea93b32a3dc4d063767a912cdc82ed35f Binary files /dev/null and b/.gradle/8.10.2/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.10.2/executionHistory/executionHistory.lock b/.gradle/8.10.2/executionHistory/executionHistory.lock index 0480205df97bb90c7d52cd13b2dab59ff642a77a..d3b6d4e9e68aba47925719e91064028d23b2f565 100644 Binary files a/.gradle/8.10.2/executionHistory/executionHistory.lock and b/.gradle/8.10.2/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.10.2/fileHashes/fileHashes.bin b/.gradle/8.10.2/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..a79d267978955d653818ac77d353056e20bc1fc1 Binary files /dev/null and b/.gradle/8.10.2/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.10.2/fileHashes/fileHashes.lock b/.gradle/8.10.2/fileHashes/fileHashes.lock index e7c208981bc92398a6f20f01d067290243cc2f24..850c64af6de6967637cd111fe779c806fbfc8311 100644 Binary files a/.gradle/8.10.2/fileHashes/fileHashes.lock and b/.gradle/8.10.2/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.10.2/fileHashes/resourceHashesCache.bin b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..7c2f7414f6ad7716a4b6f4d622d56616f836fee9 Binary files /dev/null and b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 1ca5f492f53f2a0fb2ecc71ddac5072417c9f223..c3231602f858320fe10e544fc872e1bf439216b3 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e8b136f48d43e5a0ae1493dcf50928121d85224 Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe new file mode 100644 index 0000000000000000000000000000000000000000..dd8d8c71378bdebbd024af691eb99aedfb1b3956 Binary files /dev/null and b/.gradle/file-system.probe differ diff --git a/build/classes/java/main/app/SimulatorApplication.class b/build/classes/java/main/app/SimulatorApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..9f4ba80d3723bf3c3d2277cabddbdb2158b0e3b0 Binary files /dev/null and b/build/classes/java/main/app/SimulatorApplication.class differ diff --git a/build/classes/java/main/app/SimulatorMain.class b/build/classes/java/main/app/SimulatorMain.class new file mode 100644 index 0000000000000000000000000000000000000000..1314135817cf7f41f01f0fac00bb895810cda7b6 Binary files /dev/null and b/build/classes/java/main/app/SimulatorMain.class differ diff --git a/build/classes/java/main/controller/Controller.class b/build/classes/java/main/controller/Controller.class new file mode 100644 index 0000000000000000000000000000000000000000..ba9a9a72b88e5144c8d5c44921a83eae7d3a08f8 Binary files /dev/null and b/build/classes/java/main/controller/Controller.class differ diff --git a/build/classes/java/main/controller/PersistentToggleGroup.class b/build/classes/java/main/controller/PersistentToggleGroup.class new file mode 100644 index 0000000000000000000000000000000000000000..c628d6aee41898dcc4426423e5c33466a8821e27 Binary files /dev/null and b/build/classes/java/main/controller/PersistentToggleGroup.class differ diff --git a/build/classes/java/main/model/Board.class b/build/classes/java/main/model/Board.class new file mode 100644 index 0000000000000000000000000000000000000000..ecd1336b457fb2c6c77d72d175d53e4bae454df9 Binary files /dev/null and b/build/classes/java/main/model/Board.class differ diff --git a/build/classes/java/main/model/Cloud.class b/build/classes/java/main/model/Cloud.class new file mode 100644 index 0000000000000000000000000000000000000000..8dcbc37aed2db074546809869075deef1c561b29 Binary files /dev/null and b/build/classes/java/main/model/Cloud.class differ diff --git a/build/classes/java/main/model/Fire.class b/build/classes/java/main/model/Fire.class new file mode 100644 index 0000000000000000000000000000000000000000..465cb4df67a517d056d1ade6cb49281769807781 Binary files /dev/null and b/build/classes/java/main/model/Fire.class differ diff --git a/build/classes/java/main/model/Firefighter.class b/build/classes/java/main/model/Firefighter.class new file mode 100644 index 0000000000000000000000000000000000000000..fb5822010569277b91e906a7bb675ac35da745a5 Binary files /dev/null and b/build/classes/java/main/model/Firefighter.class differ diff --git a/build/classes/java/main/model/ModelElement.class b/build/classes/java/main/model/ModelElement.class new file mode 100644 index 0000000000000000000000000000000000000000..766931b7d86443a91ddc6cc4e96f592b3cc53abe Binary files /dev/null and b/build/classes/java/main/model/ModelElement.class differ diff --git a/build/classes/java/main/model/MotorizedFirefighter.class b/build/classes/java/main/model/MotorizedFirefighter.class new file mode 100644 index 0000000000000000000000000000000000000000..30f0a1cb84767e5c05ec92af2d604bd5e617071b Binary files /dev/null and b/build/classes/java/main/model/MotorizedFirefighter.class differ diff --git a/build/classes/java/main/module-info.class b/build/classes/java/main/module-info.class new file mode 100644 index 0000000000000000000000000000000000000000..81adf2cbd56ceb6466f120bc7c89d7b59cfb2e9c Binary files /dev/null and b/build/classes/java/main/module-info.class differ diff --git a/build/classes/java/main/util/Position.class b/build/classes/java/main/util/Position.class new file mode 100644 index 0000000000000000000000000000000000000000..66d847d3166c32ee8297dd7615040ae908de271d Binary files /dev/null and b/build/classes/java/main/util/Position.class differ diff --git a/build/classes/java/main/view/FirefighterGrid.class b/build/classes/java/main/view/FirefighterGrid.class new file mode 100644 index 0000000000000000000000000000000000000000..f6de666959a2628b436cb1c723bb16b559cf622b Binary files /dev/null and b/build/classes/java/main/view/FirefighterGrid.class differ diff --git a/build/classes/java/main/view/Grid.class b/build/classes/java/main/view/Grid.class new file mode 100644 index 0000000000000000000000000000000000000000..b0148f831a19ab0bf46bfcb627f8a2be7b5470d8 Binary files /dev/null and b/build/classes/java/main/view/Grid.class differ diff --git a/build/classes/java/main/view/ViewElement.class b/build/classes/java/main/view/ViewElement.class new file mode 100644 index 0000000000000000000000000000000000000000..c1d3219fb1703274bf77fb3fedd0509e3bf4a3f9 Binary files /dev/null and b/build/classes/java/main/view/ViewElement.class differ diff --git a/build/resources/main/view/DarkTheme.css b/build/resources/main/view/DarkTheme.css new file mode 100644 index 0000000000000000000000000000000000000000..46b78aaf90972dd435399466c9fd861ca73fc59f --- /dev/null +++ b/build/resources/main/view/DarkTheme.css @@ -0,0 +1,142 @@ +.background { + -fx-background-color: #1d1d1d; +} + +.label { + -fx-font-size: 11pt; + -fx-font-family: "Segoe UI Semibold"; + -fx-text-fill: white; + -fx-opacity: 0.6; +} + +.label-bright { + -fx-font-size: 11pt; + -fx-font-family: "Segoe UI Semibold"; + -fx-text-fill: white; + -fx-opacity: 1; +} + +.label-header { + -fx-font-size: 32pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-opacity: 1; +} + +.table-view { + -fx-base: #1d1d1d; + -fx-control-inner-background: #1d1d1d; + -fx-background-color: #1d1d1d; + -fx-table-cell-border-color: transparent; + -fx-table-header-border-color: transparent; + -fx-padding: 5; +} + +.table-view .column-header-background { + -fx-background-color: transparent; +} + +.table-view .column-header, .table-view .filler { + -fx-border-width: 0 0 1 0; + -fx-background-color: transparent; + -fx-border-color: + transparent + transparent + derive(-fx-base, 80%) + transparent; + -fx-border-insets: 0 10 1 0; +} + +.table-view .column-header .label { + -fx-font-size: 20pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-alignment: center-left; + -fx-opacity: 1; +} + +.table-view:focused .table-row-cell:filled:focused:selected { + -fx-background-color: -fx-focus-color; +} + +.split-pane:horizontal > .split-pane-divider { + -fx-border-color: transparent #1d1d1d transparent #1d1d1d; + -fx-background-color: transparent, derive(#1d1d1d,20%); +} + +.split-pane { + -fx-padding: 1 0 0 0; +} + +.menu-bar { + -fx-background-color: derive(#1d1d1d,20%); +} + +.context-menu { + -fx-background-color: derive(#1d1d1d,50%); +} + +.menu-bar .label { + -fx-font-size: 14pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-opacity: 0.9; +} + +.menu .left-container { + -fx-background-color: black; +} + +.text-field { + -fx-font-size: 12pt; + -fx-font-family: "Segoe UI Semibold"; +} + +/* + * Metro style Push Button + * Author: Pedro Duque Vieira + * http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-controls-on-java/ + */ +.button { + -fx-padding: 5 22 5 22; + -fx-border-color: #e2e2e2; + -fx-border-width: 2; + -fx-background-radius: 0; + -fx-background-color: #1d1d1d; + -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif; + -fx-font-size: 11pt; + -fx-text-fill: #d8d8d8; + -fx-background-insets: 0 0 0 0, 0, 1, 2; +} + +.button:hover { + -fx-background-color: #3a3a3a; +} + +.button:pressed, .button:default:hover:pressed { + -fx-background-color: white; + -fx-text-fill: #1d1d1d; +} + +.button:focused { + -fx-border-color: white, white; + -fx-border-width: 1, 1; + -fx-border-style: solid; + -fx-border-radius: 0, 0; + -fx-border-insets: 1 1 1 1, 0; +} + +.button:disabled, .button:default:disabled { + -fx-opacity: 0.4; + -fx-background-color: #1d1d1d; + -fx-text-fill: white; +} + +.button:default { + -fx-background-color: -fx-focus-color; + -fx-text-fill: #ffffff; +} + +.button:default:hover { + -fx-background-color: derive(-fx-focus-color,30%); +} \ No newline at end of file diff --git a/build/resources/main/view/view.fxml b/build/resources/main/view/view.fxml new file mode 100644 index 0000000000000000000000000000000000000000..336ffa315645baacbe25bf59171d2ff6d867b9c5 --- /dev/null +++ b/build/resources/main/view/view.fxml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?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" + 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"/> + <Separator maxHeight="-Infinity" maxWidth="-Infinity" + 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"/> + <Button fx:id="oneStepButton" maxHeight="-Infinity" maxWidth="-Infinity" + 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"/> + <ToggleButton fx:id="pauseToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#pauseToggleButtonAction" prefHeight="24.0" + prefWidth="200.0" styleClass="button" text="Pause"/> + </VBox> + <FirefighterGrid fx:id="grid" + xmlns="http://javafx.com/javafx" + xmlns:fx="http://javafx.com/fxml"> + </FirefighterGrid> +</HBox> diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..1ab43a3ea9ccf94372fb5664ca54f09cc38b32c7 Binary files /dev/null and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java index e88b0e9856086cc6f53f2782175393dca6365eb6..c0a8fdaabafec0847c30e46c7b5574ce09231e5f 100644 --- a/src/main/java/app/SimulatorApplication.java +++ b/src/main/java/app/SimulatorApplication.java @@ -15,10 +15,15 @@ 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; - public static final int INITIAL_FIRE_COUNT = 3; + private static final int BOX_WIDTH = 30; + private static final int BOX_HEIGHT = 30; + public static final int INITIAL_FIRE_COUNT = 6; public static final int INITIAL_FIREFIGHTER_COUNT = 6; + public static final int INITIAL_CLOUD_COUNT = 4; + private static final int INITIAL_ROAD_COUNT = 5; + public static final int INITIAL_MOTORIZEDFIREFIGHTER_COUNT = 4; + public static final int INITIAL_MOINTAIN_COUNT = 10; + private Stage primaryStage; private Parent view; @@ -26,7 +31,7 @@ public class SimulatorApplication extends javafx.application.Application { this.primaryStage = primaryStage; this.primaryStage.setTitle(APP_NAME); this.primaryStage.setOnCloseRequest(event -> Platform.exit()); - this.primaryStage.setResizable(true); + this.primaryStage.setResizable(false); this.primaryStage.sizeToScene(); } @@ -44,7 +49,7 @@ public class SimulatorApplication extends javafx.application.Application { view = loader.load(); Controller controller = loader.getController(); controller.initialize(BOX_WIDTH, BOX_HEIGHT, COLUMN_COUNT, ROW_COUNT, - INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); + INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT,INITIAL_CLOUD_COUNT , INITIAL_ROAD_COUNT,INITIAL_MOTORIZEDFIREFIGHTER_COUNT,INITIAL_MOINTAIN_COUNT); } private void showScene() { diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 2a60897c6eb8ba847cb8589840c16a0f175ce0a3..9639cb678584e519edeae8f7848a9b22ef77f35b 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -12,9 +12,7 @@ import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleGroup; import javafx.util.Duration; import javafx.util.Pair; -import model.Board; -import model.ModelElement; -import model.FirefighterBoard; +import model.*; import util.Position; import view.Grid; import view.ViewElement; @@ -40,7 +38,9 @@ public class Controller { @FXML private Grid<ViewElement> grid; private Timeline timeline; - private Board<List<ModelElement>> board; + private Board board; + private State<List<ModelElement>> state; + private Updater boardUpdater; @FXML private void initialize() { @@ -54,20 +54,24 @@ public class Controller { pauseToggleButton.setSelected(true); } - private void setModel(FirefighterBoard firefighterBoard) { + private void setModel(FirefightingBoard firefighterBoard) { this.board = requireNonNull(firefighterBoard, "firefighter.model is null"); + this.state = new StateManager(board); + this.boardUpdater = new BoardUpdater(board); } private void updateBoard(){ - List<Position> updatedPositions = board.updateToNextGeneration(); + List<Position> updatedPositions = boardUpdater.update(); List<Pair<Position, ViewElement>> updatedSquares = new ArrayList<>(); for(Position updatedPosition : updatedPositions){ - List<ModelElement> squareState = board.getState(updatedPosition); + List<ModelElement> squareState = state.getState(updatedPosition); ViewElement viewElement = getViewElement(squareState); updatedSquares.add(new Pair<>(updatedPosition, viewElement)); } grid.repaint(updatedSquares); updateGenerationLabel(board.stepNumber()); + if (board.getFire().getPositions().isEmpty()) + pause(); } private void repaintGrid(){ @@ -76,7 +80,7 @@ public class Controller { ViewElement[][] viewElements = new ViewElement[rowCount][columnCount]; for(int column = 0; column < columnCount; column++) for(int row = 0; row < rowCount; row++) - viewElements[row][column] = getViewElement(board.getState(new Position(row, column))); + viewElements[row][column] = getViewElement(state.getState(new Position(row, column))); grid.repaint(viewElements); updateGenerationLabel(board.stepNumber()); } @@ -85,9 +89,21 @@ public class Controller { if(squareState.contains(ModelElement.FIREFIGHTER)){ return ViewElement.FIREFIGHTER; } + if(squareState.contains(ModelElement.CLOUD)){ + return ViewElement.CLOUD; + } + if(squareState.contains(ModelElement.MOTORIZEDFIREFIGHTER)){ + return ViewElement.MOTORIZEDFIREFIGHTER; + } + if(squareState.contains(ModelElement.MOUNTAIN)){ + return ViewElement.MOUNTAIN; + } if (squareState.contains(ModelElement.FIRE)){ return ViewElement.FIRE; } + if (squareState.contains(ModelElement.ROAD)){ + return ViewElement.ROAD; + } return ViewElement.EMPTY; } @@ -124,9 +140,10 @@ public class Controller { } public void initialize(int squareWidth, int squareHeight, int columnCount, - int rowCount, int initialFireCount, int initialFirefighterCount) { + int rowCount, int initialFireCount, int initialFirefighterCount,int initialCloudCount ,int initialRoadsCount, + int initialMotorizedFirefighterCount, int initialMountainCount) { grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight); - this.setModel(new FirefighterBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount)); + this.setModel(new FirefightingBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount,initialCloudCount , initialRoadsCount,initialMotorizedFirefighterCount,initialMountainCount)); repaintGrid(); } diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java index bb089a41406d57b0b2fe3d43b3c040cbd640b6b9..1d9a993c97b7c67e75fb7e706599ab4d26512514 100644 --- a/src/main/java/model/Board.java +++ b/src/main/java/model/Board.java @@ -3,63 +3,70 @@ package model; import util.Position; import java.util.List; +import java.util.Set; /** - * This interface represents a generic board for modeling various state-based systems. + * This interface represents a board for modeling various state-based systems. * - * @param <S> The type of state represented on the board. */ -public interface Board<S> { +public interface Board { - /** - * Get the state of the board at a specific position. - * - * @param position The position on the board for which to retrieve the state. - * @return The state at the specified position. - */ - S getState(Position position); + /** + * Get the number of rows in the board. + * + * @return The number of rows in the board. + */ + int rowCount(); - /** - * Set the state of a specific position on the board to the specified state. - * - * @param state The state to set for the given position. - * @param position The position on the board for which to set the state. - */ - void setState(S state, Position position); + /** + * Get the number of columns in the board. + * + * @return The number of columns in the board. + */ + int columnCount(); + /** + * Set the step number of the board to the specified value. + * + * @param step The step number to be set for the board. + */ + void setStep(int step); - /** - * Get the number of rows in the board. - * - * @return The number of rows in the board. - */ - int rowCount(); + /** + * Reset the board to its initial state. + */ + void reset(); - /** - * Get the number of columns in the board. - * - * @return The number of columns in the board. - */ - int columnCount(); + /** + * Get the current step number or generation of the board. + * + * @return The current step number or generation. + */ + int stepNumber(); - /** - * Update the board to its next generation or state. This method may modify the - * internal state of the board and return a list of positions that have changed - * during the update. - * - * @return A list of positions that have changed during the update. - */ - List<Position> updateToNextGeneration(); + /** + * Get the element representing the positions of firefighters on the board. + * + * @return The element containing the positions of firefighters. + */ + FireExtinguisher getFirefighter(); + /** + * Retrieve the element containing the positions of clouds on the board. + * + * @return The element representing the positions of clouds. + */ + Elements<List<Position>> getCloud(); - /** - * Reset the board to its initial state. - */ - void reset(); + /** + * Get the element representing the positions of fire on the board. + * + * @return The element containing the positions of fire. + */ + Elements<Set<Position>> getFire(); - /** - * Get the current step number or generation of the board. - * - * @return The current step number or generation. - */ - int stepNumber(); + FireExtinguisher getMotorizedFirefighter(); + + Elements<List<Position>> getRoad(); + + Elements<List<Position>> getMountain(); } diff --git a/src/main/java/model/BoardUpdater.java b/src/main/java/model/BoardUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..17766061842616d5e0c8929a24e2ebcc81c1c220 --- /dev/null +++ b/src/main/java/model/BoardUpdater.java @@ -0,0 +1,26 @@ +package model; + +import util.Position; + +import java.util.List; + +public class BoardUpdater implements Updater { + private final Board board; + + public BoardUpdater(Board board) { + this.board = board; + } + + @Override + public List<Position> update() { + Updater updater = new FirefighterUpdater(board); + List<Position> modifiedPositions = updater.update(); + updater = new CloudUpdater(board); + modifiedPositions.addAll(updater.update()); + updater = new MotorizedFirefighterUpdater(board); + modifiedPositions.addAll(updater.update()); + updater = new FireUpdater(board); + modifiedPositions.addAll(updater.update()); + board.setStep(board.stepNumber()+1); + return modifiedPositions; } +} diff --git a/src/main/java/model/Cloud.java b/src/main/java/model/Cloud.java index ad88e366ecf4391a567df365643a70e257903cd0..d1bafb91ef19602314b493149c09e727b2a03a9b 100644 --- a/src/main/java/model/Cloud.java +++ b/src/main/java/model/Cloud.java @@ -1,46 +1,30 @@ package model; import util.Position; -import java.util.List; -import java.util.Random; -import java.util.Set; -public class Cloud { - private List<Position> positions; +import java.util.ArrayList; +import java.util.List; - public Cloud(List<Position> initialPositions) { - this.positions = initialPositions; +public class Cloud implements Elements<List<Position>> { + private List<Position> cloudPositions; + private final int initialCloudCount; + public Cloud(int initialCloudCount) { + this.initialCloudCount = initialCloudCount; + cloudPositions = new ArrayList<>(); } - /** - * Déplace chaque nuage vers une position aléatoire parmi les positions possibles. - * - * @param possiblePositions Ensemble des positions possibles. - * @return Liste des nouvelles positions des nuages. - */ - public List<Position> moveRandomly(Set<Position> possiblePositions) { - Random random = new Random(); - for (int i = 0; i < positions.size(); i++) { - // Choisir une position aléatoire dans l'ensemble des positions possibles - Position newPosition = possiblePositions.stream() - .skip(random.nextInt(possiblePositions.size())) - .findFirst() - .orElse(positions.get(i)); - positions.set(i, newPosition); - } - return positions; + @Override + public List<Position> getPositions() { + return this.cloudPositions; } - /** - * Éteint les feux situés sur les positions occupées par les nuages. - * - * @param fire L'objet Fire à modifier. - */ - public void extinguishFire(Fire fire) { - positions.forEach(fire::extinguish); + @Override + public void setPositions(List<Position> positions) { + this.cloudPositions = positions; } - public List<Position> getPositions() { - return positions; + @Override + public int getInitialCount() { + return initialCloudCount; } } diff --git a/src/main/java/model/CloudUpdater.java b/src/main/java/model/CloudUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..aa6f851a703badb4610f1600aa9da0d1564d524d --- /dev/null +++ b/src/main/java/model/CloudUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.*; + +public class CloudUpdater extends FireExtinguisherUpdater implements Updater { + private final Board board; + public CloudUpdater(Board board) { + super(board); + this.board = board; + } + + @Override + public List<Position> update() { + Neighbors neighbors = new Neighbors(board); + List<Position> modifiedPosition = new ArrayList<>(); + List<Position> cloudPositions = new ArrayList<>(); + RandomPositionsGenerator randomPositionsGenerator = new RandomPositionsGenerator(board); + + for (Position cloudPosition : board.getCloud().getPositions()) { + Position newCloudPosition = randomPositionsGenerator.randomPosition(); + cloudPositions.add(newCloudPosition); + extinguish(newCloudPosition); + modifiedPosition.add(cloudPosition); + modifiedPosition.add(newCloudPosition); + List<Position> neighborFirePositions = neighbors.neighbors(newCloudPosition,1).stream() + .filter(board.getFire().getPositions()::contains).toList(); + for(Position firePosition : neighborFirePositions) + extinguish(firePosition); + modifiedPosition.addAll(neighborFirePositions); + } + board.getCloud().setPositions(cloudPositions); + return modifiedPosition; + } +} diff --git a/src/main/java/model/Elements.java b/src/main/java/model/Elements.java new file mode 100644 index 0000000000000000000000000000000000000000..781fb79f3715b880ef6f2d97828c9a44cafdcf12 --- /dev/null +++ b/src/main/java/model/Elements.java @@ -0,0 +1,11 @@ +package model; + +import util.Position; + +import java.util.List; + +public interface Elements <T>{ + T getPositions(); + void setPositions(T positions); + int getInitialCount(); +} diff --git a/src/main/java/model/Fire.java b/src/main/java/model/Fire.java index 28bc66bdef89a84b19e3670eb47ee8f524d8aa3e..4eeff26e8de7673df31a31d119e966fbec4a0106 100644 --- a/src/main/java/model/Fire.java +++ b/src/main/java/model/Fire.java @@ -2,36 +2,33 @@ package model; import util.Position; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; import java.util.Set; -public class Fire { - private Set<Position> positions; +public class Fire implements Elements<Set<Position>>{ - public Fire(Set<Position> initialPositions) { - this.positions = initialPositions; + private final int initialFireCount; + private Set<Position> firePositions; + + public Fire(int initialFireCount) { + this.initialFireCount = initialFireCount; + this.firePositions = new HashSet<>(); } + @Override public Set<Position> getPositions() { - return positions; + return firePositions; } - public List<Position> spread(Set<Position> allPositions, Set<Position> roadPositions) { - List<Position> newFirePositions = new ArrayList<>(); - for (Position position : positions) { - for (Position neighbor : allPositions) { - if (!roadPositions.contains(neighbor) && !positions.contains(neighbor)) { - newFirePositions.add(neighbor); - } - } - } - positions.addAll(newFirePositions); - return newFirePositions; - } + @Override + public void setPositions(Set<Position> positions) { + this.firePositions = positions; + } - public void extinguish(Position position) { - positions.remove(position); - }} \ No newline at end of file + @Override + public int getInitialCount() { + return initialFireCount; + } +} diff --git a/src/main/java/model/FireExtinguisher.java b/src/main/java/model/FireExtinguisher.java new file mode 100644 index 0000000000000000000000000000000000000000..b1728f19f6535d5f8db19b0e4ea5e343c74cf5a8 --- /dev/null +++ b/src/main/java/model/FireExtinguisher.java @@ -0,0 +1,32 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public abstract class FireExtinguisher implements Elements<List<Position>> { + + private final int initialCount; + private List<Position> Positions; + + public FireExtinguisher(int initialCount) { + this.initialCount = initialCount; + this.Positions = new ArrayList<>(); + } + @Override + public List<Position> getPositions() { + return this.Positions; + } + + @Override + public void setPositions(List<Position> positions) { + this.Positions = positions; + } + + @Override + public int getInitialCount() { + return initialCount; + } + +} diff --git a/src/main/java/model/FireExtinguisherUpdater.java b/src/main/java/model/FireExtinguisherUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..a091589a9f4d859b0a7b14195062cfc2f4b33fdf --- /dev/null +++ b/src/main/java/model/FireExtinguisherUpdater.java @@ -0,0 +1,42 @@ +package model; + +import util.Position; + +import java.util.*; + +public abstract class FireExtinguisherUpdater implements Updater{ + private final Board board; + + public FireExtinguisherUpdater(Board board) { + this.board = board; + } + + public Position neighborClosestToFire(Position position,int step) { + Set<Position> seen = new HashSet<>(); + Neighbors neighborsOfPosition = new Neighbors(board); + HashMap<Position, Position> firstMove = new HashMap<>(); + Queue<Position> toVisit = new LinkedList<>(neighborsOfPosition.neighbors(position,step)); + for (Position initialMove : toVisit) + firstMove.put(initialMove, initialMove); + while (!toVisit.isEmpty()) { + Position current = toVisit.poll(); + if (board.getFire().getPositions().contains(current)) + return firstMove.get(current); + for (Position adjacent : neighborsOfPosition.neighbors(current,step)) { + if (seen.contains(adjacent)) continue; + toVisit.add(adjacent); + seen.add(adjacent); + firstMove.put(adjacent, firstMove.get(current)); + } + } + return position; + } + public void extinguish(Position position) { + board.getFire().getPositions().remove(position); + } + public void restraintFireExtinguisher(List<Position> positions){ + for (Position moutainPosition : board.getMountain().getPositions()) + if (positions.contains(moutainPosition)) + positions.remove(moutainPosition); + } +} diff --git a/src/main/java/model/FireUpdater.java b/src/main/java/model/FireUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..4e830ddba13a17d5915fc73c51ca8e1c1c50071a --- /dev/null +++ b/src/main/java/model/FireUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class FireUpdater implements Updater{ + + private final Board board; + + + public FireUpdater(Board board) { + this.board = board; + } + + @Override + public List<Position> update() { + Neighbors neighborsPosition = new Neighbors(board); + + List<Position> modifiedPositions = new ArrayList<>(); + if (board.stepNumber() % 2 == 0) { + List<Position> newFirePositions = new ArrayList<>(); + for (Position fire : board.getFire().getPositions()) { + for(Position neighborsPositions : neighborsPosition.neighbors(fire , 1)) { + if (!board.getRoad().getPositions().contains(neighborsPositions) && !board.getMountain().getPositions().equals(neighborsPositions)) { + newFirePositions.add(neighborsPositions); + } + } + } + board.getFire().getPositions().addAll(newFirePositions); + modifiedPositions.addAll(newFirePositions); + } + return modifiedPositions; + } +} diff --git a/src/main/java/model/Firefighter.java b/src/main/java/model/Firefighter.java index 0538a324c7f1881ec31549b61914293782998c82..0dcc893ce44a9c84ec641762487aeaa11dce7fa2 100644 --- a/src/main/java/model/Firefighter.java +++ b/src/main/java/model/Firefighter.java @@ -1,65 +1,11 @@ package model; import util.Position; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import util.TargetStrategy; - -public class Firefighter { - private List<Position> positions; - private TargetStrategy targetStrategy; - - // Constructor - public Firefighter(List<Position> initialPositions, TargetStrategy targetStrategy) { - this.positions = initialPositions; - this.targetStrategy = targetStrategy; - } - - public boolean canFireSpreadToRock(Position position, int currentStepNumber, FirefighterBoard board) { - List<ModelElement> elements = board.getState(position); - if (elements.contains(ModelElement.ROCK)) { - return currentStepNumber >= 4; - } - return false; - } - - public List<Position> moveToClosestFire(Set<Position> firePositions, - Map<Position, List<Position>> neighbors, - Set<Position> roadPositions) { - List<Position> modifiedPositions = new ArrayList<>(); - List<Position> newPositions = new ArrayList<>(); - - for (Position position : getPositions()) { - Position firstStep = getTargetStrategy().neighborClosestToFire(position, firePositions, neighbors, roadPositions); - - Position secondStep = (firstStep != null) - ? getTargetStrategy().neighborClosestToFire(firstStep, firePositions, neighbors, roadPositions) - : null; - Position newPosition = (secondStep != null) ? secondStep : firstStep; - - modifiedPositions.add(position); - if (firstStep != null) modifiedPositions.add(firstStep); - if (secondStep != null) modifiedPositions.add(secondStep); - - newPositions.add(newPosition); - } - - setPositions(newPositions); - return modifiedPositions; - } - - public TargetStrategy getTargetStrategy() { - return targetStrategy; - } - - public List<Position> getPositions() { - return positions; - } +import java.util.List; - protected void setPositions(List<Position> positions) { - this.positions = positions; +public class Firefighter extends FireExtinguisher implements Elements<List<Position>> { + public Firefighter(int initialFirefighterCount) { + super(initialFirefighterCount); } } diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java deleted file mode 100644 index 6b7272980ab6a282752f8aa9f75d76276caf7734..0000000000000000000000000000000000000000 --- a/src/main/java/model/FirefighterBoard.java +++ /dev/null @@ -1,147 +0,0 @@ -package model; - -import util.Position; -import java.util.*; -import util.TargetStrategy; - -public class FirefighterBoard implements Board<List<ModelElement>> { - private final int columnCount; - private final int rowCount; - private final int initialFireCount; - private final int initialFirefighterCount; - private final Position[][] positions; - private final Map<Position, List<Position>> neighbors = new HashMap<>(); - private Cloud clouds; - private Firefighter motorizedFirefighter; - private Set<Position> mountainPositions = new HashSet<>(); - private Set<Position> roadPositions = new HashSet<>(); - - private Fire fire; - private Firefighter firefighter; - private int step = 0; - - public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { - this.columnCount = columnCount; - this.rowCount = rowCount; - this.initialFireCount = initialFireCount; - this.initialFirefighterCount = initialFirefighterCount; - this.positions = new Position[rowCount][columnCount]; - initializePositions(); - initializeNeighbors(); - initializeElements(); - } - - private boolean canFireSpreadToRock(Position position, int currentStepNumber) { - List<ModelElement> elements = getState(position); - if (elements.contains(ModelElement.ROCK)) { - return currentStepNumber >= 4; - } - return false; - } - - private void initializePositions() { - for (int column = 0; column < columnCount; column++) - for (int row = 0; row < rowCount; row++) - positions[row][column] = new Position(row, column); - } - - private void initializeNeighbors() { - for (int column = 0; column < columnCount; column++) - for (int row = 0; row < rowCount; row++) { - List<Position> list = new ArrayList<>(); - if (row > 0) list.add(positions[row - 1][column]); - if (column > 0) list.add(positions[row][column - 1]); - if (row < rowCount - 1) list.add(positions[row + 1][column]); - if (column < columnCount - 1) list.add(positions[row][column + 1]); - neighbors.put(positions[row][column], list); - } - } - - private void initializeElements() { - Set<Position> initialFirePositions = new HashSet<>(); - List<Position> initialFirefighterPositions = new ArrayList<>(); - Random random = new Random(); - - for (int i = 0; i < initialFireCount; i++) { - initialFirePositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); - } - for (int i = 0; i < initialFirefighterCount; i++) { - initialFirefighterPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); - } - - for (int i = 0; i < 10; i++) { - roadPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); - } - - fire = new Fire(initialFirePositions); - firefighter = new Firefighter(initialFirefighterPositions, new TargetStrategy()); - } - - @Override - public List<ModelElement> getState(Position position) { - List<ModelElement> elements = new ArrayList<>(); - if (mountainPositions.contains(position)) elements.add(ModelElement.MOUNTAIN); - if (fire.getPositions().contains(position)) elements.add(ModelElement.FIRE); - if (firefighter.getPositions().contains(position)) elements.add(ModelElement.FIREFIGHTER); - return elements; - } - - @Override - public List<Position> updateToNextGeneration() { - List<Position> modifiedPositions = new ArrayList<>(); - Set<Position> newFires = new HashSet<>(); - - for (int row = 0; row < rowCount; row++) { - for (int column = 0; column < columnCount; column++) { - Position position = positions[row][column]; - List<ModelElement> elements = getState(position); - - if (elements.contains(ModelElement.ROCK)) { - for (Position adj : neighbors.get(position)) { - List<ModelElement> adjElements = getState(adj); - if (adjElements.contains(ModelElement.FIRE) && canFireSpreadToRock(position, step)) { - newFires.add(position); - } - } - } - } - } - - for (Position firePos : newFires) { - List<ModelElement> elements = getState(firePos); - elements.add(ModelElement.FIRE); - setState(elements, firePos); - modifiedPositions.add(firePos); - } - - step++; - return modifiedPositions; - } - - @Override - public void setState(List<ModelElement> state, Position position) { - if (state.contains(ModelElement.FIRE)) fire.getPositions().add(position); - if (state.contains(ModelElement.FIREFIGHTER)) firefighter.getPositions().add(position); - } - - @Override - public int rowCount() { - return rowCount; - } - - @Override - public int columnCount() { - return columnCount; - } - - @Override - public int stepNumber() { - return step; - } - - @Override - public void reset() { - step = 0; - initializeElements(); - } -} diff --git a/src/main/java/model/FirefighterUpdater.java b/src/main/java/model/FirefighterUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..aafda36d1b700f26faeb4621f934f6f0a7343d60 --- /dev/null +++ b/src/main/java/model/FirefighterUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class FirefighterUpdater extends FireExtinguisherUpdater implements Updater{ + private final Board board; + public FirefighterUpdater(Board board){ + super(board); + this.board = board; + } + @Override + public List<Position> update() { + Neighbors neighbors = new Neighbors(board); + List<Position> modifiedPosition = new ArrayList<>(); + List<Position> firefighterNewPositions = new ArrayList<>(); + + for (Position firefighterPosition : board.getFirefighter().getPositions()) { + Position newFirefighterPosition = neighborClosestToFire(firefighterPosition,1); + firefighterNewPositions.add(newFirefighterPosition); + extinguish(newFirefighterPosition); + modifiedPosition.add(firefighterPosition); + modifiedPosition.add(newFirefighterPosition); + List<Position> neighborFirePositions = neighbors.neighbors(newFirefighterPosition,1).stream() + .filter(board.getFire().getPositions()::contains).toList(); + for(Position firePosition : neighborFirePositions) + extinguish(firePosition); + modifiedPosition.addAll(neighborFirePositions); + } + this.restraintFireExtinguisher(modifiedPosition); + board.getFirefighter().setPositions(firefighterNewPositions); + return modifiedPosition; + } +} diff --git a/src/main/java/model/FirefightingBoard.java b/src/main/java/model/FirefightingBoard.java new file mode 100644 index 0000000000000000000000000000000000000000..fc470fbee254d5ab0975002182019a23bb0183b8 --- /dev/null +++ b/src/main/java/model/FirefightingBoard.java @@ -0,0 +1,111 @@ +package model; + +import util.Position; + +import java.util.*; + + +public class FirefightingBoard implements Board { + + private final Elements<Set<Position>> fire; + private final FireExtinguisher firefighter; + private final Elements<List<Position>> cloud; + private final Elements<List<Position>> road; + private final FireExtinguisher motorizedFirefighter; + private final Elements<List<Position>> mountain; + private final int columnCount; + private final int rowCount; + private int step = 0; + private final RandomPositionsGenerator randomPositionsGenerator; + + + public FirefightingBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount, int initialCloudCount , int initialRoadscount, int initialMotorizedFirefighterCount, int initialMountainCount) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.road = new Road(initialRoadscount); + this.fire = new Fire(initialFireCount); + this.firefighter = new Firefighter(initialFirefighterCount); + this.cloud = new Cloud(initialCloudCount); + this.motorizedFirefighter = new MotorizedFirefighter(initialMotorizedFirefighterCount); + this.mountain = new Mountain(initialMountainCount); + this.randomPositionsGenerator = new RandomPositionsGenerator(this); + initializeElements(); + } + + public void initializeElements() { + fire.setPositions(new HashSet<>()); + firefighter.setPositions(new ArrayList<>()); + cloud.setPositions(new ArrayList<>()); + road.setPositions(new ArrayList<>()); + motorizedFirefighter.setPositions(new ArrayList<>()); + mountain.setPositions(new ArrayList<>()); + for (int index = 0; index < fire.getInitialCount(); index++) + fire.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < firefighter.getInitialCount(); index++) + firefighter.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < motorizedFirefighter.getInitialCount(); index++) + motorizedFirefighter.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < mountain.getInitialCount(); index++) + mountain.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < cloud.getInitialCount(); index++) + cloud.getPositions().add(randomPositionsGenerator.randomPosition()); + for(int index = 0;index<road.getInitialCount();index++) + road.getPositions().add(randomPositionsGenerator.randomPosition()); + } + + @Override + public int rowCount() { + return rowCount; + } + + @Override + public int columnCount() { + return columnCount; + } + + @Override + public Elements<Set<Position>> getFire() { + return fire; + } + + @Override + public FireExtinguisher getMotorizedFirefighter() { + return motorizedFirefighter; + } + + + @Override + public FireExtinguisher getFirefighter() { + return firefighter; + } + + @Override + public Elements<List<Position>> getCloud() { + return cloud; + } + + public Elements<List<Position>> getRoad() { + return road; + } + + @Override + public Elements<List<Position>> getMountain() { + return mountain; + } + + @Override + public int stepNumber() { + return step; + } + @Override + public void setStep(int step) { + this.step = step; + } + + @Override + public void reset() { + step = 0; + initializeElements(); + } + +} \ No newline at end of file diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java index e5f54173d395ca09e21f27a7e0912f92c9ef47cc..f4be7169c5013be62532524605b9e51d238a2a10 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, CLOUD, MOUNTAIN,ROCK + FIREFIGHTER, FIRE, CLOUD, MOTORIZEDFIREFIGHTER , MOUNTAIN, ROAD } diff --git a/src/main/java/model/MotorizedFirefighter.java b/src/main/java/model/MotorizedFirefighter.java index c88a82386b3d75926b7d451970caf0d43c419feb..ac01df3318c9af36c91b8b9903e9ca254cfd84f5 100644 --- a/src/main/java/model/MotorizedFirefighter.java +++ b/src/main/java/model/MotorizedFirefighter.java @@ -2,40 +2,10 @@ package model; import util.Position; -import java.util.*; -import util.TargetStrategy; +import java.util.List; -public class MotorizedFirefighter extends Firefighter { - - public MotorizedFirefighter(List<Position> initialPositions, TargetStrategy targetStrategy) { - super(initialPositions, targetStrategy); - } - - @Override - public List<Position> moveToClosestFire(Set<Position> firePositions, - Map<Position, List<Position>> neighbors, - Set<Position> roadPositions) { - List<Position> modifiedPositions = new ArrayList<>(); - List<Position> newPositions = new ArrayList<>(); - - for (Position position : getPositions()) { - Position firstStep = getTargetStrategy().neighborClosestToFire(position, firePositions, neighbors, roadPositions); - - Position secondStep = (firstStep != null) - ? getTargetStrategy().neighborClosestToFire(firstStep, firePositions, neighbors, roadPositions) - : null; - - Position newPosition = (secondStep != null) ? secondStep : firstStep; - - modifiedPositions.add(position); - if (firstStep != null) modifiedPositions.add(firstStep); - if (secondStep != null) modifiedPositions.add(secondStep); - - newPositions.add(newPosition); - } - - setPositions(newPositions); - return modifiedPositions; +public class MotorizedFirefighter extends FireExtinguisher implements Elements<List<Position>> { + public MotorizedFirefighter(int initialMotorizedFirefighterCount) { + super(initialMotorizedFirefighterCount); } - } diff --git a/src/main/java/model/MotorizedFirefighterUpdater.java b/src/main/java/model/MotorizedFirefighterUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..fa748b5aef92a2b4d366ccddf5c59ff2a83ffb9f --- /dev/null +++ b/src/main/java/model/MotorizedFirefighterUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.*; + +public class MotorizedFirefighterUpdater extends FireExtinguisherUpdater implements Updater{ + private final Board board; + public MotorizedFirefighterUpdater(Board board) { + super(board); + this.board = board; + } + + @Override + public List<Position> update() { + Neighbors neighbors = new Neighbors(board); + List<Position> modifiedPosition = new ArrayList<>(); + List<Position> motorizedFirefighterNewPositions = new ArrayList<>(); + + for (Position motorizedFirefighterPosition : board.getMotorizedFirefighter().getPositions()) { + Position newMotorizedFirefighterPosition = this.neighborClosestToFire(motorizedFirefighterPosition,2); + motorizedFirefighterNewPositions.add(newMotorizedFirefighterPosition); + extinguish(newMotorizedFirefighterPosition); + modifiedPosition.add(motorizedFirefighterPosition); + modifiedPosition.add(newMotorizedFirefighterPosition); + List<Position> neighborFirePositions = neighbors.neighbors(newMotorizedFirefighterPosition,2).stream() + .filter(board.getFire().getPositions()::contains).toList(); + for(Position firePosition : neighborFirePositions) + extinguish(firePosition); + modifiedPosition.addAll(neighborFirePositions); + } + this.restraintFireExtinguisher(modifiedPosition); + board.getMotorizedFirefighter().setPositions(motorizedFirefighterNewPositions); + return modifiedPosition; + } +} diff --git a/src/main/java/model/Mountain.java b/src/main/java/model/Mountain.java new file mode 100644 index 0000000000000000000000000000000000000000..6eb06f3477907f3cccb87e6575052bc0dac9ba5c --- /dev/null +++ b/src/main/java/model/Mountain.java @@ -0,0 +1,31 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class Mountain implements Elements<List<Position>>{ + private final int initialMountainCount; + private List<Position> mountainPositions; + + public Mountain(int initialMountainCount) { + this.initialMountainCount = initialMountainCount; + this.mountainPositions = new ArrayList<>(); + } + + @Override + public List<Position> getPositions() { + return mountainPositions; + } + + @Override + public void setPositions(List<Position> positions) { + mountainPositions = positions; + } + + @Override + public int getInitialCount() { + return initialMountainCount; + } +} diff --git a/src/main/java/model/Neighbors.java b/src/main/java/model/Neighbors.java new file mode 100644 index 0000000000000000000000000000000000000000..8268f54f7ac4c1bbc94ee5ec3c0a5670cc5f4652 --- /dev/null +++ b/src/main/java/model/Neighbors.java @@ -0,0 +1,24 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class Neighbors { + + private final Board board; + + public Neighbors(Board board) { + this.board = board; + } + + public List<Position> neighbors(Position position,int step) { + List<Position> list = new ArrayList<>(); + if (position.row() > 0) list.add(new Position(position.row() - step, position.column())); + if (position.column() > 0) list.add(new Position(position.row(), position.column() - step)); + if (position.row() < board.rowCount() - step) list.add(new Position(position.row() + step, position.column())); + if (position.column() < board.columnCount() - step) list.add(new Position(position.row(), position.column() + step)); + return list; + } +} diff --git a/src/main/java/model/RandomPositionsGenerator.java b/src/main/java/model/RandomPositionsGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..fa7b1752de1b373e3d96f0b67202bdde1607a830 --- /dev/null +++ b/src/main/java/model/RandomPositionsGenerator.java @@ -0,0 +1,20 @@ +package model; + +import util.Position; + +import java.util.Random; + +public class RandomPositionsGenerator { + private final Board board; + private final Random randomGenerator ; + + public RandomPositionsGenerator(Board board) { + this.board = board; + this.randomGenerator = new Random(); + } + + public Position randomPosition() { + return new Position(randomGenerator.nextInt(board.rowCount()), randomGenerator.nextInt(board.columnCount())); + } + +} diff --git a/src/main/java/model/Road.java b/src/main/java/model/Road.java new file mode 100644 index 0000000000000000000000000000000000000000..fd8bc2b994d7658dac9c43e0a47ec748d133864c --- /dev/null +++ b/src/main/java/model/Road.java @@ -0,0 +1,31 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class Road implements Elements<List<Position>> { + private List<Position> roadsPositions; + private int initialRoadsCount; + + public Road (int initialRoadsCount) { + this.initialRoadsCount=initialRoadsCount; + roadsPositions= new ArrayList<>(); + } + + @Override + public List<Position> getPositions() { + return roadsPositions; + } + + @Override + public void setPositions(List<Position> positions) { + this.roadsPositions = positions; + } + + @Override + public int getInitialCount() { + return initialRoadsCount; + } +} diff --git a/src/main/java/model/State.java b/src/main/java/model/State.java new file mode 100644 index 0000000000000000000000000000000000000000..d7b70690402109eb8ae4553c5ec6ba74eff1ec95 --- /dev/null +++ b/src/main/java/model/State.java @@ -0,0 +1,29 @@ +package model; + +import util.Position; + +/** + * Represents a state manager for a board at specific positions. + * Implementations of this interface provide methods to retrieve and set the state + * of a position on the board. + * + * @param <S> The type of state represented on the board. + */ + +public interface State<S>{ + /** + * Get the state of the board at a specific position. + * + * @param position The position on the board for which to retrieve the state. + * @return The state at the specified position. + */ + S getState(Position position); + + /** + * Set the state of a specific position on the board to the specified state. + * + * @param state The state to set for the given position. + * @param position The position on the board for which to set the state. + */ + void setState(S state, Position position); +} diff --git a/src/main/java/model/StateManager.java b/src/main/java/model/StateManager.java new file mode 100644 index 0000000000000000000000000000000000000000..8aeb8b470a559d3e04f8264676e96bbdfe589f4a --- /dev/null +++ b/src/main/java/model/StateManager.java @@ -0,0 +1,59 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class StateManager implements State<List<ModelElement>>{ + + private final Board board; + + public StateManager(Board board) { + this.board = board; + } + + @Override + public List<ModelElement> getState(Position position) { + List<ModelElement> result = new ArrayList<>(); + for (Position firefighterPosition : board.getFirefighter().getPositions()) + if (firefighterPosition.equals(position)) + result.add(ModelElement.FIREFIGHTER); + for (Position cloudPosition : board.getCloud().getPositions()) + if (cloudPosition.equals(position)) + result.add(ModelElement.CLOUD); + for (Position motorizedFirefighterPosition : board.getMotorizedFirefighter().getPositions()) + if (motorizedFirefighterPosition.equals(position)) + result.add(ModelElement.MOTORIZEDFIREFIGHTER); + for (Position mountainPosition : board.getMountain().getPositions()) + if (mountainPosition.equals(position)) + result.add(ModelElement.MOUNTAIN); + if (board.getFire().getPositions().contains(position)) + result.add(ModelElement.FIRE); + if(board.getRoad().getPositions().contains(position)) + result.add(ModelElement.ROAD); + return result; + } + + @Override + public void setState(List<ModelElement> state, Position position) { + board.getFire().getPositions().remove(position); + for (; ; ) { + if (!board.getFirefighter().getPositions().remove(position)) break; + if (!board.getCloud().getPositions().remove(position)) break; + if (!board.getMotorizedFirefighter().getPositions().remove(position)) break; + if (!board.getRoad().getPositions().remove(position)) break; + } + for (ModelElement element : state) { + switch (element) { + case FIRE -> board.getFire().getPositions().add(position); + case FIREFIGHTER -> board.getFirefighter().getPositions().add(position); + case CLOUD -> board.getCloud().getPositions().add(position); + case MOUNTAIN -> board.getMountain().getPositions().add(position); + case MOTORIZEDFIREFIGHTER -> board.getMotorizedFirefighter().getPositions().add(position); + case ROAD -> board.getRoad().getPositions().add(position); + + } + } + } +} diff --git a/src/main/java/model/Updater.java b/src/main/java/model/Updater.java new file mode 100644 index 0000000000000000000000000000000000000000..3ade6c68e369a25080b8861376ee9b6c63e60b1f --- /dev/null +++ b/src/main/java/model/Updater.java @@ -0,0 +1,9 @@ +package model; + +import util.Position; + +import java.util.List; + +public interface Updater { + List<Position> update(); +} diff --git a/src/main/java/util/Position.java b/src/main/java/util/Position.java index 5220fa02a9a2e9818a6b5929f9b4bb5b4c88ce2a..31dc4c1fb6a04b4e96649e133d1d116120d34683 100644 --- a/src/main/java/util/Position.java +++ b/src/main/java/util/Position.java @@ -1,47 +1,5 @@ package util; -import java.util.Objects; +public record Position(int row, int column) { -public class Position { - private final int row; - private final int column; - - public Position(int row, int column) { - this.row = row; - this.column = column; - } - - public int row() { - return row; - } - - public int column() { - return column; - } - - public int getRow() { - return row; - } - - public int getColumn() { - return column; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Position position = (Position) o; - return row == position.row && column == position.column; - } - - @Override - public int hashCode() { - return Objects.hash(row, column); - } - - @Override - public String toString() { - return "Position{" + "row=" + row + ", column=" + column + '}'; - } } diff --git a/src/main/java/util/TargetStrategy.java b/src/main/java/util/TargetStrategy.java deleted file mode 100644 index 629b6f6f28fabbff5ebebe35399ecca443491839..0000000000000000000000000000000000000000 --- a/src/main/java/util/TargetStrategy.java +++ /dev/null @@ -1,53 +0,0 @@ -package util; - -import util.Position; - -import java.util.*; - -public class TargetStrategy { - - /** - * Trouve la case adjacente la plus proche du feu en respectant les routes. - * - * @param position Position actuelle. - * @param targets Positions des feux. - * @param neighbors Carte des voisins pour chaque position. - * @param roadPositions Positions représentant les routes. - * @return La position voisine qui se rapproche le plus d'un feu, respectant les routes. - */ - public Position neighborClosestToFire(Position position, Collection<Position> targets, - Map<Position, List<Position>> neighbors, - Set<Position> roadPositions) { - Set<Position> seen = new HashSet<>(); - Map<Position, Position> firstMove = new HashMap<>(); - Queue<Position> toVisit = new LinkedList<>(neighbors.get(position)); - - // Initialisation des mouvements possibles - for (Position initialMove : toVisit) { - if (roadPositions.contains(initialMove)) { - firstMove.put(initialMove, initialMove); - } - } - - // Parcours en largeur (BFS) pour trouver le feu le plus proche - while (!toVisit.isEmpty()) { - Position current = toVisit.poll(); - - // Si la position actuelle est un feu, on retourne le premier mouvement vers cette position - if (targets.contains(current)) { - return firstMove.get(current); - } - - // Ajout des voisins non visités qui sont sur les routes - for (Position adjacent : neighbors.get(current)) { - if (seen.contains(adjacent) || !roadPositions.contains(adjacent)) continue; - toVisit.add(adjacent); - seen.add(adjacent); - firstMove.put(adjacent, firstMove.get(current)); - } - } - - // Si aucun feu n'est trouvé, retourner la position actuelle - return position; - } -} diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java index ffb76112e1af543df5af41fa906082ef11be9967..accd977c55e7c3be9b4e024673ce40c626603978 100644 --- a/src/main/java/view/ViewElement.java +++ b/src/main/java/view/ViewElement.java @@ -1,9 +1,10 @@ package view; import javafx.scene.paint.Color; +import model.Road; public enum ViewElement { - FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); + FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE), CLOUD(Color.GRAY),MOTORIZEDFIREFIGHTER(Color.AQUA), ROAD(Color.BLACK), MOUNTAIN(Color.BROWN); final Color color; ViewElement(Color color) { this.color = color;