diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java deleted file mode 100644 index f2ec0dc5ff4bd59e5589e9fd29a9acea0d25cf71..0000000000000000000000000000000000000000 --- a/src/main/java/app/SimulatorApplication.java +++ /dev/null @@ -1,59 +0,0 @@ -package app; - -import controller.Controller; -import javafx.application.Platform; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.stage.Stage; - -import java.io.IOException; -import java.net.URL; - -public class SimulatorApplication extends javafx.application.Application { - private static final String VIEW_RESOURCE_PATH = "/view/view.fxml"; - 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; - public static final int INITIAL_FIREFIGHTER_COUNT = 6; - - private Stage primaryStage; - private Parent view; - private void initializePrimaryStage(Stage primaryStage) { - this.primaryStage = primaryStage; - this.primaryStage.setTitle(APP_NAME); - this.primaryStage.setOnCloseRequest(event -> Platform.exit()); - this.primaryStage.setResizable(false); - this.primaryStage.sizeToScene(); - } - - @Override - public void start(Stage primaryStage) throws IOException { - initializePrimaryStage(primaryStage); - initializeView(); - showScene(); - } - - private void initializeView() throws IOException { - FXMLLoader loader = new FXMLLoader(); - URL location = SimulatorApplication.class.getResource(VIEW_RESOURCE_PATH); - loader.setLocation(location); - view = loader.load(); - Controller controller = loader.getController(); - controller.initialize(BOX_WIDTH, BOX_HEIGHT, COLUMN_COUNT, ROW_COUNT, - INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); - } - - private void showScene() { - Scene scene = new Scene(view); - primaryStage.setScene(scene); - primaryStage.show(); - } - - public static void main(String[] args) { - launch(args); - } -} diff --git a/src/main/java/app/SimulatorMain.java b/src/main/java/app/SimulatorMain.java deleted file mode 100644 index f2e49f262ebec4136cf57d3b50fea3987b3b69fc..0000000000000000000000000000000000000000 --- a/src/main/java/app/SimulatorMain.java +++ /dev/null @@ -1,7 +0,0 @@ -package app; - -public class SimulatorMain { - public static void main(String[] args){ - SimulatorApplication.main(args); - } -} diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java deleted file mode 100644 index 2a60897c6eb8ba847cb8589840c16a0f175ce0a3..0000000000000000000000000000000000000000 --- a/src/main/java/controller/Controller.java +++ /dev/null @@ -1,141 +0,0 @@ -package controller; - -import javafx.animation.Animation; -import javafx.animation.KeyFrame; -import javafx.animation.Timeline; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -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 util.Position; -import view.Grid; -import view.ViewElement; - -import java.util.ArrayList; -import java.util.List; - -import static java.util.Objects.requireNonNull; - -public class Controller { - - public static final int PERIOD_IN_MILLISECONDS = 50; - @FXML - public Button restartButton; - @FXML - public Button oneStepButton; - @FXML - public Label generationNumberLabel; - @FXML - private ToggleButton pauseToggleButton; - @FXML - private ToggleButton playToggleButton; - @FXML - private Grid<ViewElement> grid; - private Timeline timeline; - private Board<List<ModelElement>> board; - - @FXML - private void initialize() { - initializePlayAndPauseToggleButtons(); - initializeTimeline(); - } - - private void initializePlayAndPauseToggleButtons() { - ToggleGroup toggleGroup = new PersistentToggleGroup(); - toggleGroup.getToggles().addAll(playToggleButton, pauseToggleButton); - pauseToggleButton.setSelected(true); - } - - private void setModel(FirefighterBoard firefighterBoard) { - this.board = requireNonNull(firefighterBoard, "firefighter.model is null"); - } - - private void updateBoard(){ - List<Position> updatedPositions = board.updateToNextGeneration(); - List<Pair<Position, ViewElement>> updatedSquares = new ArrayList<>(); - for(Position updatedPosition : updatedPositions){ - List<ModelElement> squareState = board.getState(updatedPosition); - ViewElement viewElement = getViewElement(squareState); - updatedSquares.add(new Pair<>(updatedPosition, viewElement)); - } - grid.repaint(updatedSquares); - updateGenerationLabel(board.stepNumber()); - } - - private void repaintGrid(){ - int columnCount = board.columnCount(); - int rowCount = board.rowCount(); - 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))); - grid.repaint(viewElements); - updateGenerationLabel(board.stepNumber()); - } - - private ViewElement getViewElement(List<ModelElement> squareState) { - if(squareState.contains(ModelElement.FIREFIGHTER)){ - return ViewElement.FIREFIGHTER; - } - if (squareState.contains(ModelElement.FIRE)){ - return ViewElement.FIRE; - } - return ViewElement.EMPTY; - } - - private void initializeTimeline() { - Duration duration = new Duration(Controller.PERIOD_IN_MILLISECONDS); - EventHandler<ActionEvent> eventHandler = - event -> updateBoard(); - KeyFrame keyFrame = new KeyFrame(duration, eventHandler); - timeline = new Timeline(keyFrame); - timeline.setCycleCount(Animation.INDEFINITE); - } - - public void play() { - timeline.play(); - } - - public void pause() { - timeline.pause(); - } - - public void pauseToggleButtonAction() { - this.pause(); - } - - public void playToggleButtonAction() { - this.play(); - } - - public void restartButtonAction() { - this.pause(); - board.reset(); - pauseToggleButton.setSelected(true); - repaintGrid(); - } - - public void initialize(int squareWidth, int squareHeight, int columnCount, - int rowCount, int initialFireCount, int initialFirefighterCount) { - grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight); - this.setModel(new FirefighterBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount)); - repaintGrid(); - } - - public void oneStepButtonAction() { - this.pause(); - updateBoard(); - } - - private void updateGenerationLabel(int value){ - generationNumberLabel.setText(Integer.toString(value)); - } -} \ No newline at end of file diff --git a/src/main/java/controller/PersistentToggleGroup.java b/src/main/java/controller/PersistentToggleGroup.java deleted file mode 100644 index 7c2c4b5c79d6ff65e0bfbe53c2fb7e9fd5944a1b..0000000000000000000000000000000000000000 --- a/src/main/java/controller/PersistentToggleGroup.java +++ /dev/null @@ -1,34 +0,0 @@ -package controller; - -import javafx.collections.ListChangeListener.Change; -import javafx.scene.control.Toggle; -import javafx.scene.control.ToggleButton; -import javafx.scene.control.ToggleGroup; -import javafx.scene.input.MouseEvent; - -/** - * An extension of {@link ToggleGroup} that ensures that a {@link Toggle} in a group must always be - * selected. - * - */ -class PersistentToggleGroup extends ToggleGroup { - - /** - * Creates a new {@code PersistentToggleGroup}. - */ - PersistentToggleGroup() { - getToggles().addListener((Change<? extends Toggle> change) -> { - while (change.next()) { - for (Toggle toggle : change.getAddedSubList()) { - ToggleButton toggleButton = (ToggleButton) toggle; - toggleButton.addEventFilter(MouseEvent.MOUSE_RELEASED, mouseEvent -> { - if (toggleButton.equals(getSelectedToggle())) { - mouseEvent.consume(); - } - }); - } - } - }); - } - -} diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java deleted file mode 100644 index bb089a41406d57b0b2fe3d43b3c040cbd640b6b9..0000000000000000000000000000000000000000 --- a/src/main/java/model/Board.java +++ /dev/null @@ -1,65 +0,0 @@ -package model; - -import util.Position; - -import java.util.List; - -/** - * This interface represents a generic board for modeling various state-based systems. - * - * @param <S> The type of state represented on the board. - */ -public interface Board<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); - - /** - * Get the number of rows in the board. - * - * @return The number of rows in the board. - */ - int rowCount(); - - /** - * Get the number of columns in the board. - * - * @return The number of columns in the board. - */ - int columnCount(); - - /** - * 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(); - - /** - * Reset the board to its initial state. - */ - void reset(); - - /** - * Get the current step number or generation of the board. - * - * @return The current step number or generation. - */ - int stepNumber(); -} - diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java deleted file mode 100644 index 97abb90182242c43b0dea173a4b0f853b93922b0..0000000000000000000000000000000000000000 --- a/src/main/java/model/FirefighterBoard.java +++ /dev/null @@ -1,157 +0,0 @@ -package model; - -import util.Position; - -import java.util.*; - - -public class FirefighterBoard implements Board<List<ModelElement>> { - private final int columnCount; - private final int rowCount; - private final int initialFireCount; - private final int initialFirefighterCount; - private List<Position> firefighterPositions; - private Set<Position> firePositions; - private int step = 0; - private final Random randomGenerator = new Random(); - - public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { - this.columnCount = columnCount; - this.rowCount = rowCount; - this.initialFireCount = initialFireCount; - this.initialFirefighterCount = initialFirefighterCount; - initializeElements(); - } - - public void initializeElements() { - firefighterPositions = new ArrayList<>(); - firePositions = new HashSet<>(); - for (int index = 0; index < initialFireCount; index++) - firePositions.add(randomPosition()); - for (int index = 0; index < initialFirefighterCount; index++) - firefighterPositions.add(randomPosition()); - } - - private Position randomPosition() { - return new Position(randomGenerator.nextInt(rowCount), randomGenerator.nextInt(columnCount)); - } - - @Override - public List<ModelElement> getState(Position position) { - List<ModelElement> result = new ArrayList<>(); - for(Position firefighterPosition : firefighterPositions) - if (firefighterPosition.equals(position)) - result.add(ModelElement.FIREFIGHTER); - 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 = updateFirefighters(); - modifiedPositions.addAll(updateFires()); - step++; - return modifiedPositions; - } - - private List<Position> updateFires() { - List<Position> modifiedPositions = new ArrayList<>(); - if (step % 2 == 0) { - List<Position> newFirePositions = new ArrayList<>(); - for (Position fire : firePositions) { - newFirePositions.addAll(neighbors(fire)); - } - firePositions.addAll(newFirePositions); - modifiedPositions.addAll(newFirePositions); - } - return modifiedPositions; - - } - - @Override - public int stepNumber() { - return step; - } - - private List<Position> updateFirefighters() { - List<Position> modifiedPosition = new ArrayList<>(); - List<Position> firefighterNewPositions = new ArrayList<>(); - for (Position firefighterPosition : firefighterPositions) { - Position newFirefighterPosition = neighborClosestToFire(firefighterPosition); - firefighterNewPositions.add(newFirefighterPosition); - extinguish(newFirefighterPosition); - modifiedPosition.add(firefighterPosition); - modifiedPosition.add(newFirefighterPosition); - List<Position> neighborFirePositions = neighbors(newFirefighterPosition).stream() - .filter(firePositions::contains).toList(); - for(Position firePosition : neighborFirePositions) - extinguish(firePosition); - modifiedPosition.addAll(neighborFirePositions); - } - firefighterPositions = firefighterNewPositions; - return modifiedPosition; - } - - @Override - public void reset() { - step = 0; - initializeElements(); - } - - private void extinguish(Position position) { - firePositions.remove(position); - } - - private List<Position> neighbors(Position position) { - List<Position> list = new ArrayList<>(); - if (position.row() > 0) list.add(new Position(position.row() - 1, position.column())); - if (position.column() > 0) list.add(new Position(position.row(), position.column() - 1)); - if (position.row() < rowCount - 1) list.add(new Position(position.row() + 1, position.column())); - if (position.column() < columnCount - 1) list.add(new Position(position.row(), position.column() + 1)); - return list; - } - - private Position neighborClosestToFire(Position position) { - Set<Position> seen = new HashSet<>(); - HashMap<Position, Position> firstMove = new HashMap<>(); - Queue<Position> toVisit = new LinkedList<>(neighbors(position)); - for (Position initialMove : toVisit) - firstMove.put(initialMove, initialMove); - while (!toVisit.isEmpty()) { - Position current = toVisit.poll(); - if (firePositions.contains(current)) - return firstMove.get(current); - for (Position adjacent : neighbors(current)) { - if (seen.contains(adjacent)) continue; - toVisit.add(adjacent); - seen.add(adjacent); - firstMove.put(adjacent, firstMove.get(current)); - } - } - return position; - } - - @Override - public void setState(List<ModelElement> state, Position position) { - firePositions.remove(position); - for (;;) { - if (!firefighterPositions.remove(position)) break; - } - for(ModelElement element : state){ - switch (element){ - case FIRE -> firePositions.add(position); - case FIREFIGHTER -> firefighterPositions.add(position); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java deleted file mode 100644 index 759eee5e54c3a39472d8f7defbbbe6a2b67b8f00..0000000000000000000000000000000000000000 --- a/src/main/java/model/ModelElement.java +++ /dev/null @@ -1,5 +0,0 @@ -package model; - -public enum ModelElement { - FIREFIGHTER, FIRE -} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java deleted file mode 100644 index 4c36d97709b342e457203c75d081fc5cc1955c0f..0000000000000000000000000000000000000000 --- a/src/main/java/module-info.java +++ /dev/null @@ -1,8 +0,0 @@ -module firefighter { - requires javafx.controls; - requires javafx.fxml; - requires javafx.graphics; - opens controller to javafx.fxml; - exports app; - opens app to javafx.fxml; -} diff --git a/src/main/java/util/Position.java b/src/main/java/util/Position.java deleted file mode 100644 index 31dc4c1fb6a04b4e96649e133d1d116120d34683..0000000000000000000000000000000000000000 --- a/src/main/java/util/Position.java +++ /dev/null @@ -1,5 +0,0 @@ -package util; - -public record Position(int row, int column) { - -} diff --git a/src/main/java/view/FirefighterGrid.java b/src/main/java/view/FirefighterGrid.java deleted file mode 100644 index 4c9041f034ec9a4eb07ce4334de237f1e99ccdc9..0000000000000000000000000000000000000000 --- a/src/main/java/view/FirefighterGrid.java +++ /dev/null @@ -1,99 +0,0 @@ -package view; - -import javafx.scene.canvas.Canvas; -import javafx.scene.paint.Color; -import javafx.util.Pair; -import util.Position; - -import java.util.List; - -public class FirefighterGrid extends Canvas implements Grid<ViewElement>{ - - private void paintElementAtPosition(ViewElement element, Position position) { - paintBox(position.row(), position.column(), element.color); - } - private int boxWidth; - private int boxHeight; - private int columnCount; - private int rowCount; - - @Override - public void repaint(List<Pair<Position, ViewElement>> positionedElements) { - clear(positionedElements); - paint(positionedElements); - paintLines(); - } - - private void clear(List<Pair<Position, ViewElement>> positionedElements) { - for (Pair<Position, ViewElement> positionElement : positionedElements) { - Position position = positionElement.getKey(); - clearBox(position.row(), position.column()); - } - } - - private void paint(List<Pair<Position, ViewElement>> positionedElements) { - for(Pair<Position, ViewElement> pair : positionedElements){ - paintElementAtPosition(pair.getValue(), pair.getKey()); - } - } - - @Override - public void repaint(ViewElement[][] elements) { - clear(); - paint(elements); - paintLines(); - } - - private void clear() { - getGraphicsContext2D().clearRect(0,0,getWidth(), getHeight()); - } - - private void paint(ViewElement[][] elements) { - for(int column = 0; column < columnCount; column++) - for(int row = 0; row < rowCount; row++){ - paintElementAtPosition(elements[row][column], new Position(row, column)); - } - } - - public int columnCount() { - return columnCount; - } - - public int rowCount() { - return rowCount; - } - - @Override - public void setDimensions(int columnCount, int rowCount, int boxWidth, int boxHeight) { - this.boxWidth = boxWidth; - this.boxHeight = boxHeight; - this.columnCount = columnCount; - this.rowCount = rowCount; - super.setWidth(boxWidth * columnCount); - super.setHeight(boxHeight * rowCount); - } - - private void paintLines(){ - paintHorizontalLines(); - paintVerticalLines(); - } - - private void paintVerticalLines() { - for(int column = 0; column < columnCount; column++) - getGraphicsContext2D().strokeLine(column * boxWidth, 0,column * boxWidth, getHeight()); - } - - private void paintHorizontalLines() { - for(int row = 0; row < rowCount; row++) - getGraphicsContext2D().strokeLine(0, row * boxHeight, getWidth(), row * boxHeight); - } - - private void paintBox(int row, int column, Color color){ - getGraphicsContext2D().setFill(color); - getGraphicsContext2D().fillRect(column * boxWidth,row * boxHeight, boxWidth, boxHeight); - } - - private void clearBox(int row, int column){ - getGraphicsContext2D().clearRect(column * boxWidth,row * boxHeight, boxWidth, boxHeight); - } -} \ No newline at end of file diff --git a/src/main/java/view/Grid.java b/src/main/java/view/Grid.java deleted file mode 100644 index b95d59f622a86b41f2a41261b8b27aaf2e911dfb..0000000000000000000000000000000000000000 --- a/src/main/java/view/Grid.java +++ /dev/null @@ -1,55 +0,0 @@ -package view; - -import javafx.util.Pair; -import util.Position; - -import java.util.List; - -/** - * This interface represents a generic grid structure for displaying two-dimensional data. - * - * @param <E> The type of elements stored in the grid. - */ -public interface Grid<E> { - - /** - * Repaint the grid with a list of elements, each associated with their respective positions. - * - * @param elements A list of pairs, each containing a position and the element to be displayed at that position. - */ - void repaint(List<Pair<Position, E>> elements); - - /** - * Repaint the grid with a two-dimensional array of elements. The array's dimensions should match - * the row and column count of the grid. - * - * @param elements A two-dimensional array of elements to be displayed on the grid. - */ - void repaint(E[][] elements); - - /** - * Set the dimensions of the grid to the specified number of columns, number of rows, square width, - * and square height. - * - * @param columnCount The new number of columns in the grid. - * @param rowCount The new number of rows in the grid. - * @param squareWidth The width of each square within the grid. - * @param squareHeight The height of each square within the grid. - */ - void setDimensions(int columnCount, int rowCount, int squareWidth, int squareHeight); - - /** - * Get the number of columns in the grid. - * - * @return The number of columns in the grid. - */ - int columnCount(); - - /** - * Get the number of rows in the grid. - * - * @return The number of rows in the grid. - */ - int rowCount(); -} - diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java deleted file mode 100644 index ffb76112e1af543df5af41fa906082ef11be9967..0000000000000000000000000000000000000000 --- a/src/main/java/view/ViewElement.java +++ /dev/null @@ -1,11 +0,0 @@ -package view; - -import javafx.scene.paint.Color; - -public enum ViewElement { - FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); - final Color color; - ViewElement(Color color) { - this.color = color; - } -}