Skip to content
Snippets Groups Projects
Commit 316059ad authored by KALLEL Mohamed ali's avatar KALLEL Mohamed ali
Browse files

task 1

parent fa1fe3cd
No related branches found
No related tags found
No related merge requests found
Showing
with 184 additions and 117 deletions
package app; package app;
import controller.Controller; import controller.fireFigther.ControllerFireFigtherBord;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import model.Element.*;
import java.util.HashMap;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.Map;
public class SimulatorApplication extends javafx.application.Application { public class SimulatorApplication extends javafx.application.Application {
private static final String VIEW_RESOURCE_PATH = "/view/view.fxml"; private static final String VIEW_RESOURCE_PATH = "/view/fireFigtherView/fireFigtherBord.fxml";
private static final String APP_NAME = "Firefighter simulator"; private static final String APP_NAME = "Firefighter simulator";
private static final int ROW_COUNT = 20; private static final int ROW_COUNT = 20;
private static final int COLUMN_COUNT = 20; private static final int COLUMN_COUNT = 20;
private static final int SQUARE_WIDTH = 50; private static final int SQUARE_WIDTH = 30;
private static final int SQUARE_HEIGHT = 50; private static final int SQUARE_HEIGHT = 30;
public static final int INITIAL_FIRE_COUNT = 3; private Map<ModelElement,Integer> INITIAL_ELEMENTS_COUNT;
public static final int INITIAL_FIREFIGHTER_COUNT = 10;
public static final int INITIAL_CLOUD_COUNT=10;
private Stage primaryStage; private Stage primaryStage;
private Parent view; private Parent view;
...@@ -31,21 +34,34 @@ public class SimulatorApplication extends javafx.application.Application { ...@@ -31,21 +34,34 @@ public class SimulatorApplication extends javafx.application.Application {
this.primaryStage.sizeToScene(); this.primaryStage.sizeToScene();
} }
@Override @Override
public void start(Stage primaryStage) throws IOException { public void start(Stage primaryStage) throws IOException {
initializePrimaryStage(primaryStage); initializePrimaryStage(primaryStage);
initializeInitialElementCount();
initializeView(); initializeView();
showScene(); showScene();
} }
private void initializeInitialElementCount() {
INITIAL_ELEMENTS_COUNT = new HashMap<>();
INITIAL_ELEMENTS_COUNT.put(new Fire(), 1);
INITIAL_ELEMENTS_COUNT.put(new FireFigther(), 3);
INITIAL_ELEMENTS_COUNT.put(new Cloud(), 2);
INITIAL_ELEMENTS_COUNT.put(new MotorisedFirefigther(), 3);
INITIAL_ELEMENTS_COUNT.put(new Mountain(), 1);
INITIAL_ELEMENTS_COUNT.put(new Road(), 4);
INITIAL_ELEMENTS_COUNT.put(new Rockerie(), 5);
}
private void initializeView() throws IOException { private void initializeView() throws IOException {
FXMLLoader loader = new FXMLLoader(); FXMLLoader loader = new FXMLLoader();
URL location = SimulatorApplication.class.getResource(VIEW_RESOURCE_PATH); URL location = SimulatorApplication.class.getResource(VIEW_RESOURCE_PATH);
loader.setLocation(location); loader.setLocation(location);
view = loader.load(); view = loader.load();
Controller controller = loader.getController(); ControllerFireFigtherBord controller = loader.getController();
controller.initialize(SQUARE_WIDTH, SQUARE_HEIGHT, COLUMN_COUNT, ROW_COUNT, controller.initialize(SQUARE_WIDTH, SQUARE_HEIGHT, COLUMN_COUNT, ROW_COUNT,INITIAL_ELEMENTS_COUNT
INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); );
} }
private void showScene() { private void showScene() {
......
package controller;
import javafx.fxml.FXML;
import javafx.scene.control.Spinner;
public class SettingsController {
@FXML
private Spinner<Integer> rowCountSpinner;
@FXML
private Spinner<Integer> columnCountSpinner;
public int getRowCount() {
return rowCountSpinner.getValue();
}
public int getColumnCount() {
return columnCountSpinner.getValue();
}
}
package controller;
public class controllerMenu {
}
package controller; package controller.fireFigther;
import controller.fireFigther.PersistentToggleGroup;
import javafx.animation.Animation; import javafx.animation.Animation;
import javafx.animation.KeyFrame; import javafx.animation.KeyFrame;
import javafx.animation.Timeline; import javafx.animation.Timeline;
...@@ -13,8 +14,6 @@ import javafx.scene.control.ToggleGroup; ...@@ -13,8 +14,6 @@ import javafx.scene.control.ToggleGroup;
import javafx.util.Duration; import javafx.util.Duration;
import javafx.util.Pair; import javafx.util.Pair;
import model.Board; import model.Board;
import model.Element.Fire;
import model.Element.FireFigther;
import model.Element.ModelElement; import model.Element.ModelElement;
import model.FirefighterBoard; import model.FirefighterBoard;
import util.Position; import util.Position;
...@@ -27,7 +26,7 @@ import java.util.Map; ...@@ -27,7 +26,7 @@ import java.util.Map;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
public class Controller { public class ControllerFireFigtherBord {
public static final int PERIOD_IN_MILLISECONDS = 50; public static final int PERIOD_IN_MILLISECONDS = 50;
@FXML @FXML
...@@ -98,7 +97,7 @@ public class Controller { ...@@ -98,7 +97,7 @@ public class Controller {
private void initializeTimeline() { private void initializeTimeline() {
Duration duration = new Duration(Controller.PERIOD_IN_MILLISECONDS); Duration duration = new Duration(ControllerFireFigtherBord.PERIOD_IN_MILLISECONDS);
EventHandler<ActionEvent> eventHandler = EventHandler<ActionEvent> eventHandler =
event -> updateBoard(); event -> updateBoard();
KeyFrame keyFrame = new KeyFrame(duration, eventHandler); KeyFrame keyFrame = new KeyFrame(duration, eventHandler);
...@@ -130,9 +129,9 @@ public class Controller { ...@@ -130,9 +129,9 @@ public class Controller {
} }
public void initialize(int squareWidth, int squareHeight, int columnCount, public void initialize(int squareWidth, int squareHeight, int columnCount,
int rowCount, int initialFireCount, int initialFirefighterCount) { int rowCount,Map<ModelElement,Integer> initialElementCount) {
grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight); grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight);
this.setModel(new FirefighterBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount)); this.setModel(new FirefighterBoard(columnCount, rowCount, initialElementCount));
repaintGrid(); repaintGrid();
} }
......
package controller; package controller.fireFigther;
import javafx.collections.ListChangeListener.Change; import javafx.collections.ListChangeListener.Change;
import javafx.scene.control.Toggle; import javafx.scene.control.Toggle;
......
...@@ -19,13 +19,18 @@ public class Cloud implements ModelElement { ...@@ -19,13 +19,18 @@ public class Cloud implements ModelElement {
@Override @Override
public void update(Position position, Map<Position, List<ModelElement>> board, int step, int columnCount, int rowCount) { public void update(Position position, Map<Position, List<ModelElement>> board, int step, int columnCount, int rowCount) {
List<Position> neighbors = neighbors(position, rowCount, columnCount);
if (!neighbors.isEmpty()) {
Random nextCloud = new Random(); Random nextCloud = new Random();
addElement(neighbors(position, rowCount, columnCount).get(nextCloud.nextInt()),board, new Cloud()); Position randomNeighbor = neighbors.get(nextCloud.nextInt(neighbors.size()));
removeElement(position,board,new Cloud()); addElement(randomNeighbor, board, new Cloud());
}
removeElement(position, board, new Cloud());
} }
@Override @Override
public ViewElement getViewElement() { public ViewElement getViewElement() {
return ViewElement.Cloud; return ViewElement.Cloud;
......
package model.Element; package model.Element;
import model.FirefighterBoard;
import util.Position; import util.Position;
import view.ViewElement; import view.ViewElement;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import static util.Tools.addElement; import static util.Tools.addElement;
...@@ -14,10 +10,32 @@ import static util.Tools.neighbors; ...@@ -14,10 +10,32 @@ import static util.Tools.neighbors;
public class Fire implements ModelElement { public class Fire implements ModelElement {
int fireWasCreate; int fireWasCreate;
private final List<ModelElement>prohibitedPropagationFire;
public Fire() {
this.prohibitedPropagationFire= Collections.unmodifiableList(Arrays.asList(
new Mountain(),
new FireFigther(),
new MotorisedFirefigther(),
new Cloud(),
new Road()));
}
public void setFireWasCreate(int fireWasCreate) { public void setFireWasCreate(int fireWasCreate) {
this.fireWasCreate = fireWasCreate; this.fireWasCreate = fireWasCreate;
} }
private boolean canFireSpread(Position position, Map<Position, List<ModelElement>> board) {
if(board.getOrDefault(position,List.of()).contains(new Fire()))return false;
for (ModelElement element : prohibitedPropagationFire) {
if (board.getOrDefault(position,List.of()).contains(element)) {
return false;
}
}
return true;
}
@Override @Override
public void update(Position position, Map<Position, List<ModelElement>> board,int step, int columnCount, int rowCount) { public void update(Position position, Map<Position, List<ModelElement>> board,int step, int columnCount, int rowCount) {
...@@ -25,23 +43,27 @@ public class Fire implements ModelElement { ...@@ -25,23 +43,27 @@ public class Fire implements ModelElement {
Fire nextFire = new Fire(); Fire nextFire = new Fire();
nextFire.setFireWasCreate(step); nextFire.setFireWasCreate(step);
for (Position position1 : neighbors(position, rowCount, columnCount)) { for (Position position1 : neighbors(position, rowCount, columnCount)) {
if (canFireSpread(position1,board)) {
if (!board.containsKey(position1)){ addElement(position1, board, nextFire);
addElement(position1, board, new Fire());
} else if (board.get(position1).isEmpty()) { } else if (board.get(position1).isEmpty()) {
addElement(position1, board, new Fire()); addElement(position1, board, nextFire);
} }
if (board.get(position1).contains(new Rockerie()) && (step - fireWasCreate) % 4 == 0) { if (board.get(position1).contains(new Rockerie()) && (step - fireWasCreate) % 4 == 0) {
if (!(board.get(position1).contains(new Mountain())||board.get(position1).contains(new FireFigther())||board.get(position1).contains(new MotorisedFirefigther())||board.get(position1).contains(new Cloud())||(board.get(position1).contains(new FireFigther())))){ if (canFireSpread(position1,board)) {
addElement(position1, board, new Fire()); addElement(position1, board, nextFire);
} }
} }
} }
} }
} }
@Override @Override
public ViewElement getViewElement() { public ViewElement getViewElement() {
return ViewElement.FIRE; return ViewElement.FIRE;
......
...@@ -14,14 +14,14 @@ public class FireFigther implements ModelElement{ ...@@ -14,14 +14,14 @@ public class FireFigther implements ModelElement{
for (Position position1 : neighbors(position, rowCount, columnCount)) { for (Position position1 : neighbors(position, rowCount, columnCount)) {
if (board.containsKey(position1)) { if (board.containsKey(position1)) {
if (board.get(position1).contains(new Fire())) { if (board.get(position1).contains(new Fire())) {
extinguish(position,board); extinguish(position1,board);
return;
} }
} }
} }
Position newPositionStep = neighborClosestToFire(position,board,rowCount,columnCount); Position newPositionStep = neighborClosestTo(position,board,rowCount,columnCount);
extinguish(newPositionStep,board); extinguish(newPositionStep,board);
removeElement(position,board,new FireFigther()); removeElement(position,board,new FireFigther());
addElement(newPositionStep,board,new FireFigther()); addElement(newPositionStep,board,new FireFigther());
......
...@@ -22,11 +22,13 @@ public class MotorisedFirefigther implements ModelElement{ ...@@ -22,11 +22,13 @@ public class MotorisedFirefigther implements ModelElement{
} }
} }
Position newPositionStep = neighborClosestToFire(position,board,rowCount,columnCount); MotorisedFirefigther motorisedFirefigther=new MotorisedFirefigther();
Position newPositionTwoStep=neighborClosestToFire(newPositionStep,board,rowCount,columnCount); Position newPositionStep = neighborClosestTo(position,board,rowCount,columnCount);
Position newPositionTwoStep= neighborClosestTo(newPositionStep,board,rowCount,columnCount);
extinguish(newPositionTwoStep,board); extinguish(newPositionTwoStep,board);
addElement(newPositionTwoStep,board,new MotorisedFirefigther()); removeElement(position,board,motorisedFirefigther);
removeElement(position,board,new MotorisedFirefigther()); addElement(newPositionTwoStep,board,motorisedFirefigther);
} }
...@@ -37,6 +39,6 @@ public class MotorisedFirefigther implements ModelElement{ ...@@ -37,6 +39,6 @@ public class MotorisedFirefigther implements ModelElement{
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return obj instanceof Mountain; return obj instanceof MotorisedFirefigther;
} }
} }
package model; package model;
import model.Element.Cloud;
import model.Element.Fire; import model.Element.Fire;
import model.Element.FireFigther; import model.Element.FireFigther;
import model.Element.ModelElement; import model.Element.ModelElement;
...@@ -13,30 +14,31 @@ import static util.Tools.addElement; ...@@ -13,30 +14,31 @@ import static util.Tools.addElement;
public class FirefighterBoard implements Board<List<ModelElement>> { public class FirefighterBoard implements Board<List<ModelElement>> {
private final int columnCount; private final int columnCount;
private final int rowCount; private final int rowCount;
private int initialFireCount ;
private int initialFirefighterCount; private Map<ModelElement,Integer>initialElementCount;
private Map<Position,List<ModelElement>>board; private Map<Position,List<ModelElement>>board;
private int step = 0; private int step = 0;
private final Random randomGenerator = new Random(); private final Random randomGenerator = new Random();
public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { public FirefighterBoard(int columnCount, int rowCount,Map<ModelElement,Integer>initialElementCount ) {
this.columnCount = columnCount; this.columnCount = columnCount;
this.rowCount = rowCount; this.rowCount = rowCount;
this.initialFirefighterCount=initialFirefighterCount; this.initialElementCount=initialElementCount;
this.initialFireCount=initialFireCount;
board=new HashMap<>(); board=new HashMap<>();
initializeElements(); initializeElements(initialElementCount);
} }
public void initializeElements() { public void initializeElements(Map<ModelElement,Integer>initialElementCount) {
for (int index = 0; index < initialFireCount; index++) { for (ModelElement element :initialElementCount.keySet()
addElement(randomPosition(),board,new Fire()); ) {
for (int index = 0; index < initialElementCount.get(element); index++) {
addElement(randomPosition(),board,element);
} }
for (int index = 0; index < initialFirefighterCount; index++) {
addElement(randomPosition(),board,new FireFigther());
} }
} }
private Position randomPosition() { private Position randomPosition() {
...@@ -90,7 +92,8 @@ public class FirefighterBoard implements Board<List<ModelElement>> { ...@@ -90,7 +92,8 @@ public class FirefighterBoard implements Board<List<ModelElement>> {
@Override @Override
public void reset() { public void reset() {
step = 0; step = 0;
initializeElements(); board.clear();
initializeElements(initialElementCount);
} }
@Override @Override
......
...@@ -5,4 +5,5 @@ module firefighter { ...@@ -5,4 +5,5 @@ module firefighter {
opens controller to javafx.fxml; opens controller to javafx.fxml;
exports app; exports app;
opens app to javafx.fxml; opens app to javafx.fxml;
opens controller.fireFigther to javafx.fxml;
} }
package util; package util;
import model.Element.Fire; import model.Element.Fire;
import model.Element.FireFigther;
import model.Element.ModelElement; import model.Element.ModelElement;
import model.Element.Mountain; import model.Element.Mountain;
...@@ -18,7 +17,8 @@ public class Tools { ...@@ -18,7 +17,8 @@ public class Tools {
if (position.column() < columnCount - 1) list.add(new Position(position.row(), position.column() + 1)); if (position.column() < columnCount - 1) list.add(new Position(position.row(), position.column() + 1));
return list; return list;
} }
public static Position neighborClosestToFire(Position position,Map<Position, List<ModelElement>> board,int rowCount , int columnCount) {
public static Position neighborClosestTo(Position position, Map<Position, List<ModelElement>> board, int rowCount , int columnCount) {
Set<Position> seen = new HashSet<>(); Set<Position> seen = new HashSet<>();
HashMap<Position, Position> firstMove = new HashMap<>(); HashMap<Position, Position> firstMove = new HashMap<>();
Queue<Position> toVisit = new LinkedList<>(neighbors(position,rowCount,columnCount)); Queue<Position> toVisit = new LinkedList<>(neighbors(position,rowCount,columnCount));
...@@ -29,23 +29,24 @@ public class Tools { ...@@ -29,23 +29,24 @@ public class Tools {
Position current = toVisit.poll(); Position current = toVisit.poll();
if (board.containsKey(current)) { if (board.containsKey(current)) {
if (board.get(current).contains(new Fire())){ if (board.get(current).contains(new Fire())){
System.out.println("ok chef 4");
return firstMove.get(current); return firstMove.get(current);
} }
for (Position adjacent : neighbors(current, rowCount, columnCount)) {
if (seen.contains(adjacent)) {
continue;
} }
for (Position adjacent : neighbors(current, rowCount, columnCount)) {
if (!(seen.contains(adjacent) )) {
toVisit.add(adjacent); toVisit.add(adjacent);
seen.add(adjacent); seen.add(adjacent);
firstMove.put(adjacent, firstMove.get(current)); firstMove.put(adjacent, firstMove.get(current));
} }
} }
} }
return position; return position;
} }
public static void extinguish(Position position,Map<Position, List<ModelElement>> board) { public static void extinguish(Position position,Map<Position, List<ModelElement>> board) {
board.remove(position); board.remove(position);
} }
...@@ -69,4 +70,6 @@ public class Tools { ...@@ -69,4 +70,6 @@ public class Tools {
} }
...@@ -3,7 +3,7 @@ package view; ...@@ -3,7 +3,7 @@ package view;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
public enum ViewElement { public enum ViewElement {
FIREFIGHTER(Color.BLUE), FIRE(Color.RED),Cloud(Color.GRAY),Rockerie(Color.LIGHTGREY),MotorisedFirefigther(Color.ALICEBLUE),Road(Color.BLACK),Mountain(Color.BROWN), EMPTY(Color.WHITE); FIREFIGHTER(Color.BLUE), FIRE(Color.RED),Cloud(Color.GRAY),Rockerie(Color.LIGHTGREY),MotorisedFirefigther(Color.ORANGE),Road(Color.BLACK),Mountain(Color.BROWN), EMPTY(Color.WHITE);
final Color color; final Color color;
ViewElement(Color color) { ViewElement(Color color) {
this.color = color; this.color = color;
......
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.layout.GridPane?>
<GridPane xmlns:fx="http://javafx.com/fxml"
fx:controller="controller.fireFigther.SettingsController" alignment="center" hgap="10" vgap="10" padding="20">
<Label text="Settings" style="-fx-font-size: 16;" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/>
<!-- Row Count -->
<Label text="Row Count:" GridPane.columnIndex="0" GridPane.rowIndex="1"/>
<Spinner fx:id="rowCountSpinner" value="10" min="1" max="100" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<!-- Column Count -->
<Label text="Column Count:" GridPane.columnIndex="0" GridPane.rowIndex="2"/>
<Spinner fx:id="columnCountSpinner" value="10" min="1" max="100" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
</GridPane>
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<HBox styleClass="background" stylesheets="@DarkTheme.css" <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"> fx:controller="controller.fireFigther.ControllerFireFigtherBord">
<VBox> <VBox>
<Separator maxHeight="-Infinity" maxWidth="-Infinity" <Separator maxHeight="-Infinity" maxWidth="-Infinity"
prefHeight="24.0" prefWidth="200.0"/> prefHeight="24.0" prefWidth="200.0"/>
......
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="controller.controllerMenu"
prefHeight="400.0" prefWidth="600.0">
</AnchorPane>
package model;
import model.Element.Fire;
import model.Element.ModelElement;
import org.junit.jupiter.api.Test;
import util.Position;
import java.util.List;
import static org.assertj.core.api.Assertions.*;
public class FirefighterBoardTest {
@Test
void testColumnCount(){
Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3);
assertThat(board.columnCount()).isEqualTo(20);
}
@Test
void testRowCount(){
Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3);
assertThat(board.rowCount()).isEqualTo(10);
}
@Test
void testStepNumber(){
Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3);
for(int index = 0; index < 10; index++){
assertThat(board.stepNumber()).isEqualTo(index);
board.updateToNextGeneration();
}
assertThat(board.stepNumber()).isEqualTo(10);
}
@Test
void testGetState_afterSet(){
Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 0, 0);
Position position = new Position(1,2);
assertThat(board.getState(position)).isEmpty();
board.setState(List.of(new Fire()), position);
assertThat(board.getState(position)).containsExactly(new Fire());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment