Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • main
  • variant
2 results

Target

Select target project
  • m19023837/firefighter-starter-mansour-chadi-chahine-rami
  • r24025701/firefighterstarter
  • n24026202/firefighterstarter
  • couetoux.b/firefighterstarter
  • b23027938/firefighterstarter
  • z20039716/fire-fighter
  • a18023913/firefighterstarter
  • o22010261/firefighterstarter
  • b22015516/firefighterstarter
  • alaboure/firefighter-template
  • p21211679/firefighter-luis-parra-yanis-lounadi
  • v23014723/firefighter-project
  • k20014011/firefighter-template
  • m23022217/firefighter-template
  • p20006624/firefighter-template
  • l21221596/firefighter-template
  • s21232465/firefighter-template
  • y21224754/firefighter-template
  • w21225935/firefighter-template
  • h22023886/firefighter-template
  • b21221604/firefighter-template-boucenna-yacine-zeghar-mohamed-lamine
  • c23025119/firefighterstarter
  • b20031964/firefighterstarter
23 results
Select Git revision
  • main
  • variant
2 results
Show changes
Commits on Source (16)
Showing
with 826 additions and 225 deletions
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
id 'application'
id "org.openjfx.javafxplugin" version "0.0.14"
id 'java'
id "org.openjfx.javafxplugin" version "0.1.0"
}
javafx {
version = "20"
modules = [ 'javafx.controls', 'javafx.fxml' ]
version = "21"
modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.graphics']
}
......@@ -15,9 +17,7 @@ repositories {
}
dependencies {
testRuntimeOnly("org.junit.platform:junit-platform-launcher") {
because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions")
}
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.assertj:assertj-core:3.24.2")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
......@@ -28,5 +28,7 @@ test {
}
application {
mainClass.set("App")
mainClass.set("app.SimulatorMain")
}
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
rootProject.name = 'firefighter'
include 'src:main:aapp'
findProject(':src:main:aapp')?.name = 'aapp'
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import static java.lang.Thread.sleep;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws InterruptedException {
Group root = new Group();
Button restart = new Button("Restart");
VBox buttons = new VBox();
HBox total = new HBox();
Grid grid = new Grid(1000,1000,20,20);
root.getChildren().add(total);
total.getChildren().add(buttons);
total.getChildren().add(grid);
buttons.getChildren().add(restart);
restart.setOnMouseClicked(grid::restart);
primaryStage.setScene(new Scene(root));
primaryStage.show();
grid.repaint();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
sleep(50);
grid.model.activation();
grid.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
public class Grid extends Canvas{
int width, height, colCount, rowCount;
Model model;
public Grid(int width, int height, int colCount, int rowCount) {
super(width,height);
this.width = width;
this.height = height;
this.colCount = colCount;
this.rowCount = rowCount;
setFocusTraversable(true);
setOnMousePressed(this::mousePressed);
model = new Model(this);
model.initialisation(3,8);
}
public void restart(MouseEvent mouseEvent){
model = new Model(this);
model.initialisation(3,6);
getGraphicsContext2D().clearRect(0,0,width,height);
repaint();
}
private void mousePressed(MouseEvent mouseEvent) {
model.activation();
repaint();
/*double x = mouseEvent.getX();
double y = mouseEvent.getY();
model.click((int)x*rowCount/height,(int)y*colCount/width);*/
}
void repaint(){
for(int col=0; col<colCount; col++)
getGraphicsContext2D().strokeLine(0, col*width/colCount,height, col*width/colCount);
for(int row=0; row<rowCount;row++)
getGraphicsContext2D().strokeLine(row*height/rowCount,0,row*height/rowCount,width);
}
void paint(int row, int col){
getGraphicsContext2D().setFill(Color.WHITE);
getGraphicsContext2D().fillRect(row*height/rowCount,col*width/colCount,height/rowCount,width/colCount);
}
public void paintFF(int row, int col) {
getGraphicsContext2D().setFill(Color.BLUE);
getGraphicsContext2D().fillRect(row*height/rowCount,col*width/colCount,height/rowCount,width/colCount);
}
public void paintFire(int row, int col) {
getGraphicsContext2D().setFill(Color.RED);
getGraphicsContext2D().fillRect(row*height/rowCount,col*width/colCount,height/rowCount,width/colCount);
}
}
\ No newline at end of file
import java.util.*;
public class Model {
Grid grid;
int colCount, rowCount;
List<Position> firefighters = new ArrayList<>();
Set<Position> fires = new HashSet<>();
List<Position> ffNewPositions;
int step = 0;
public Model(Grid grid) {
this.grid = grid;
colCount = grid.colCount;
rowCount = grid.rowCount;
}
public void initialisation(int fireNumber, int fireFighterNumber){
for(int index=0; index<fireNumber;index++)
fires.add(randomPosition());
for(int index=0; index<fireFighterNumber;index++)
firefighters.add(randomPosition());
}
private Position randomPosition() {
return new Position((int) (Math.random()*rowCount), (int) (Math.random()*colCount));
}
public void activation(){
ffNewPositions = new ArrayList<>();
for(Position ff : firefighters){
Position newPosition = activateFirefighter(ff);
grid.paint(ff.row,ff.col);
grid.paintFF(newPosition.row, newPosition.col);
ffNewPositions.add(newPosition);
}
firefighters = ffNewPositions;
if(step%2==0){
List<Position> newFires = new ArrayList<>();
for(Position fire : fires){
newFires.addAll(activateFire(fire));
}
for(Position newFire : newFires)
grid.paintFire(newFire.row, newFire.col);
fires.addAll(newFires);}
step++;
}
private List<Position> activateFire(Position position) {
return next(position);
}
private Position activateFirefighter(Position position) {
Position randomPosition = aStepTowardFire(position);
//next(position).get((int) (Math.random()*next(position).size()));
List<Position> nextFires = next(randomPosition).stream().filter(fires::contains).toList();
extinguish(randomPosition);
for (Position fire : nextFires)
extinguish(fire);
return randomPosition;
}
private void extinguish(Position position) {
fires.remove(position);
grid.paint(position.row, position.col);
}
private List<Position> next(Position position){
List<Position> list = new ArrayList<>();
if(position.row>0) list.add(new Position(position.row-1, position.col));
if(position.col>0) list.add(new Position(position.row, position.col-1));
if(position.row<rowCount-1) list.add(new Position(position.row+1, position.col));
if(position.col<colCount-1) list.add(new Position(position.row, position.col+1));
return list;
}
private Position aStepTowardFire(Position position){
Queue<Position> toVisit = new LinkedList<>();
Set<Position> seen = new HashSet<>();
HashMap<Position,Position> firstMove = new HashMap<>();
toVisit.addAll(next(position));
for(Position initialMove : toVisit)
firstMove.put(initialMove,initialMove);
while(!toVisit.isEmpty()){
Position current = toVisit.poll();
if(fires.contains(current))
return firstMove.get(current);
for(Position adjacent : next(current)){
if(seen.contains(adjacent)) continue;
toVisit.add(adjacent);
seen.add(adjacent);
firstMove.put(adjacent, firstMove.get(current));
}
}
return position;
}
public record Position(int row, int col){}
}
\ No newline at end of file
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(true);
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);
}
}
package app;
public class SimulatorMain {
public static void main(String[] args){
SimulatorApplication.main(args);
}
}
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
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();
}
});
}
}
});
}
}
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();
}
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 final TargetStrategy targetStrategy = new TargetStrategy();
private List<Position> firefighterPositions;
private Set<Position> firePositions;
private Map<Position, List<Position>> neighbors = new HashMap();
private final Position[][] positions;
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.positions = new Position[rowCount][columnCount];
for (int column = 0; column < columnCount; column++)
for (int row = 0; row < rowCount; row++)
positions[row][column] = new Position(row, column);
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);
}
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.get(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 =
targetStrategy.neighborClosestToFire(firefighterPosition,
firePositions, neighbors);
firefighterNewPositions.add(newFirefighterPosition);
extinguish(newFirefighterPosition);
modifiedPosition.add(firefighterPosition);
modifiedPosition.add(newFirefighterPosition);
List<Position> neighborFirePositions = neighbors.get(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);
}
@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
package model;
public enum ModelElement {
FIREFIGHTER, FIRE
}
module firefighter {
requires javafx.controls;
requires javafx.fxml;
requires javafx.graphics;
opens controller to javafx.fxml;
exports app;
opens app to javafx.fxml;
}
package util;
public record Position(int row, int column) {
}
package model;
import util.Position;
import java.util.*;
public class TargetStrategy {
/**
* @param position current position.
* @param targets positions that are targeted.
* @return the position next to the current position that is on the path to the closest target.
*/
Position neighborClosestToFire(Position position, Collection<Position> targets,
Map<Position,List<Position>>neighbors) {
Set<Position> seen = new HashSet<Position>();
HashMap<Position, Position> firstMove = new HashMap<Position, Position>();
Queue<Position> toVisit = new LinkedList<Position>(neighbors.get(position));
for (Position initialMove : toVisit)
firstMove.put(initialMove, initialMove);
while (!toVisit.isEmpty()) {
Position current = toVisit.poll();
if (targets.contains(current))
return firstMove.get(current);
for (Position adjacent : neighbors.get(current)) {
if (seen.contains(adjacent)) continue;
toVisit.add(adjacent);
seen.add(adjacent);
firstMove.put(adjacent, firstMove.get(current));
}
}
return position;
}
}
\ No newline at end of file
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
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();
}
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;
}
}
.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