From 8e1d13aaaaa24fa4830916834555eb8d8f746b62 Mon Sep 17 00:00:00 2001 From: Yanis O <oualanyanis01@gmail.com> Date: Wed, 13 Nov 2024 19:09:47 +0100 Subject: [PATCH] =?UTF-8?q?[Ajout]=20Logique=20de=20d=C3=A9placement=20et?= =?UTF-8?q?=20d'extinction=20de=20feu=20des=20pompiers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/Controller.java | 1 - src/main/java/model/Board.java | 4 + src/main/java/model/EmptySquare.java | 10 ++- src/main/java/model/Entity.java | 7 +- src/main/java/model/Fire.java | 28 +++--- src/main/java/model/FireFighter.java | 94 +++++++++++++++++--- src/main/java/model/FireFighterScenario.java | 18 +++- src/main/java/util/Matrix.java | 21 ++++- src/main/java/util/PositionUtil.java | 83 +++++++++++++++++ 9 files changed, 228 insertions(+), 38 deletions(-) diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 2450bf5..154a1b8 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -74,7 +74,6 @@ public class Controller { int columnCount = board.columnCount(); int rowCount = board.rowCount(); ViewElement[][] viewElements = new ViewElement[rowCount][columnCount]; - System.out.println("columnsCOunt : " + columnCount + " rowCount : " + rowCount); for(int column = 0; column < columnCount; column++) for(int row = 0; row < rowCount; row++) viewElements[row][column] = getViewElement(board.getState(new Position(row, column))); diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java index b88601b..1326ce8 100644 --- a/src/main/java/model/Board.java +++ b/src/main/java/model/Board.java @@ -67,5 +67,9 @@ public interface Board<S> { public void setState(Entity state, Position position, boolean replaceStates); public boolean doesPositionExist(Position position); + + public void clearCase(Position position); + + public Position getNearestEntity(Position fromPos, Class<?> entityType); } diff --git a/src/main/java/model/EmptySquare.java b/src/main/java/model/EmptySquare.java index 1d5749d..113ea0a 100644 --- a/src/main/java/model/EmptySquare.java +++ b/src/main/java/model/EmptySquare.java @@ -10,8 +10,14 @@ public class EmptySquare implements Entity{ private Position position; private final Color viewColor = Color.WHITE; + private int age; public EmptySquare(Position p){ this.position = p; + this.age = -999; + } + public EmptySquare(Position p, int age){ + this.position = p; + this.age = age; } @Override public List<Position> nextTurn(Board<Entity> board) { @@ -33,11 +39,11 @@ public class EmptySquare implements Entity{ } @Override public int getAge() { - return -999; + return this.age; } @Override public void incrementAge() { - return; + age = age + 1; } } diff --git a/src/main/java/model/Entity.java b/src/main/java/model/Entity.java index 61626fa..5569aa5 100644 --- a/src/main/java/model/Entity.java +++ b/src/main/java/model/Entity.java @@ -6,7 +6,12 @@ import javafx.scene.paint.Color; import util.Position; public interface Entity { - // Calcule ce que l'entité va faire au prochain tour, et retourne la liste des positions affectés + /** + * Exécute un tour de jeu, en vérifiant les cases adjacentes pour des instances de Fire. + * + * @param b Le plateau de jeu contenant des entités. + * @return Une liste de positions affectées durant le tour (que la vue doit mettre à jour). + */ public List<Position> nextTurn(Board<Entity> board); public Position getPosition(); public void setPosition(Position p); diff --git a/src/main/java/model/Fire.java b/src/main/java/model/Fire.java index 43f7967..019137e 100644 --- a/src/main/java/model/Fire.java +++ b/src/main/java/model/Fire.java @@ -1,10 +1,10 @@ package model; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; import javafx.scene.paint.Color; import util.Position; +import util.PositionUtil; public class Fire implements Entity{ Board<Entity> b; @@ -24,30 +24,22 @@ public class Fire implements Entity{ @Override public List<Position> nextTurn(Board<Entity> board) { - age = age +1; - List<Position> positions = generateAdjacentPosition(); + if(board.getStepNumber() % 2 == 0)return new ArrayList<Position>(); + List<Position> positions = PositionUtil.generateAdjacentPositions(position, board); for(Position p : positions){ - board.setState(new Fire(p, board), p); + if(b.getState(p) instanceof EmptySquare){ + if(b.getState(p).getAge() < b.getStepNumber()){ + board.setState(new Fire(p, board), p); + } + } if(!b.doesPositionExist(p)){ positions.remove(p); } } return positions; } + - private List<Position> generateAdjacentPosition(){ - int x = position.x(); - int y = position.y(); - - return Stream.of( - new Position(x, y + 1), - new Position(x + 1, y), - new Position(x, y - 1), - new Position(x - 1, y) - ) - .filter(p -> b.doesPositionExist(p)) - .collect(Collectors.toList()); - } @Override diff --git a/src/main/java/model/FireFighter.java b/src/main/java/model/FireFighter.java index 4088d8e..718589d 100644 --- a/src/main/java/model/FireFighter.java +++ b/src/main/java/model/FireFighter.java @@ -4,6 +4,7 @@ import java.util.List; import javafx.scene.paint.Color; import util.Position; +import util.PositionUtil; public class FireFighter implements Entity{ private int age; @@ -22,18 +23,91 @@ public class FireFighter implements Entity{ this.age = age; } - public List<Position> nextTurn(Board<Entity> b){ - age++; - List<Position> positions = new ArrayList<Position>(); - positions.add(position); + public List<Position> nextTurn(Board<Entity> b) { + List<Position> positions = new ArrayList<>(); + + // Générer les positions adjacentes + List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, b); + + // Vérifier s'il y a du feu dans une des positions adjacentes + boolean hasFire = adjacentPositions.stream() + .anyMatch(p -> b.getState(p) instanceof Fire); + + if (hasFire) { + // Si du feu est trouvé, on éteint les feux adjacents + positions.addAll(extinguish(adjacentPositions, b)); + } else { + // Chercher la position du feu le plus proche + Position nearestFirePos = b.getNearestEntity(position, Fire.class); + + if (nearestFirePos != null && !nearestFirePos.equals(position)) { + // Trouver la meilleure position pour se rapprocher du feu + Position nextPos = getNextPositionTowards(position, nearestFirePos, b); + + if (nextPos != null) { + // Mettre à jour la position du pompier + b.clearCase(position); // Vider l'ancienne case + positions.add(new Position(position.x(), position.y())); + this.position = nextPos; + b.setState(this, nextPos); // Mettre à jour la nouvelle case + positions.add(nextPos); + adjacentPositions = PositionUtil.generateAdjacentPositions(nextPos, b); + positions.addAll(extinguish(adjacentPositions, b)); + } + // Aucun déplacement possible = le pompier reste sur place + } + } + return positions; - // Récupérer la position - //Si un feu est à proximité : éteindre les feux à x + 1 y, x y+1, x+1 y-1, x-1 y+1 - //Sinon - //Se déplacer vers le feu le plus proche - //Si un feu est à proximité : éteindre les feux à x + 1 y, x y+1, x+1 y-1, x-1 y+1 - // Ajouter un feu à x + 1 y, x y+1, x-1 y, x y-1 } + + private List<Position> extinguish(List<Position> adjacentPositions, Board<Entity> b) { + List<Position> extinguishedPositions = new ArrayList<>(); + for (Position p : adjacentPositions) { + if (b.getState(p) instanceof Fire) { + b.clearCase(p); + extinguishedPositions.add(p); // Ajouter la position où le feu a été éteint + } + } + return extinguishedPositions; + } + + private Position getNextPositionTowards(Position currentPos, Position targetPos, Board<Entity> b) { + // Générer les 8 positions adjacentes possibles + List<Position> possibleMoves = PositionUtil.generateAllAdjacentPositions(currentPos, b); + + // Filtrer les positions qui sont libres + possibleMoves.removeIf(p -> !(b.getState(p) instanceof EmptySquare)); + + // Si aucune position libre n'est disponible, retourner null + if (possibleMoves.isEmpty()) { + return null; + } + + // Calculer la distance actuelle vers la cible + int currentDistance = PositionUtil.getManhattanDistance(currentPos, targetPos); + + // Choisir la position libre qui réduit le plus la distance vers le feu + Position bestMove = null; + int minDistance = currentDistance; + for (Position move : possibleMoves) { + int distance = PositionUtil.getManhattanDistance(move, targetPos); + if (distance < minDistance) { + minDistance = distance; + bestMove = move; + } + } + + // Si aucun déplacement ne réduit la distance, annuler le déplacement + if (bestMove == null) { + return null; + } + System.out.println("moving from " + position.toString() + " to " + bestMove.toString()); + return bestMove; + } + + + @Override public void setPosition(Position p) { diff --git a/src/main/java/model/FireFighterScenario.java b/src/main/java/model/FireFighterScenario.java index 786d169..9c2a923 100644 --- a/src/main/java/model/FireFighterScenario.java +++ b/src/main/java/model/FireFighterScenario.java @@ -15,8 +15,12 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity> private Matrix<Entity> matrix; private int step; + private int initialFireCount; + private int initialFireFightersCount; public FireFighterScenario(int columns, int rows, int initialFireCount, int initialFireFightersCount) { this.matrix = new Matrix<Entity>(columns, rows); + this.initialFireCount = initialFireCount; + this.initialFireFightersCount = initialFireFightersCount; initScenario(matrix); placeInitialActors(initialFireCount, initialFireFightersCount); this.step = 0; @@ -95,6 +99,10 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity> public int columnCount() { return matrix.getColumns(); } + @Override + public void clearCase(Position position){ + setState(new EmptySquare(position, step+1), position, true); + } public List<Position> updateToNextGeneration() { ArrayList<Position> changedPositions = new ArrayList<>(); @@ -103,15 +111,18 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity> Entity e = iterator.next(); if (e instanceof EmptySquare) continue; - System.out.println("found age : " + e.getAge() + " current age : " + step); if (e.getAge() == 0) { e.incrementAge(); continue; } - ; + if(e.getAge() == step+1){ + continue; + } List<Position> entityUpdatedPositions = e.nextTurn(this); + e.incrementAge(); changedPositions.addAll(entityUpdatedPositions); } + matrix.displayMatrix(); return changedPositions; } @@ -142,7 +153,10 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity> public void reset() { + step = 0; matrix.clear(); + initScenario(matrix); + placeInitialActors(initialFireCount, initialFireFightersCount); } public int stepNumber() { diff --git a/src/main/java/util/Matrix.java b/src/main/java/util/Matrix.java index c68517f..53da808 100644 --- a/src/main/java/util/Matrix.java +++ b/src/main/java/util/Matrix.java @@ -4,6 +4,9 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; +import model.Fire; +import model.FireFighter; + public class Matrix<E> implements Iterable<E> { private ArrayList<ArrayList<E>> matrix; private final int rows; @@ -36,9 +39,11 @@ public class Matrix<E> implements Iterable<E> { } public void clear() { - this.matrix.clear(); + this.matrix = new ArrayList<>(rows); + // Initialiser chaque ligne de la matrice for (int i = 0; i < rows; i++) { ArrayList<E> row = new ArrayList<>(columns); + // Initialiser chaque colonne avec des valeurs nulles for (int j = 0; j < columns; j++) { row.add(null); } @@ -56,7 +61,7 @@ public class Matrix<E> implements Iterable<E> { public int getRows(){ return this.rows; } - /* + public void displayMatrix() { System.out.print(" "); @@ -69,7 +74,15 @@ public class Matrix<E> implements Iterable<E> { System.out.print("| "); for (int j = 0; j < columns; j++) { if (matrix.get(i).get(j) != null) { - System.out.print(" x | "); + if(matrix.get(i).get(j) instanceof Fire){ + System.out.print(" F | "); + } + else if(matrix.get(i).get(j) instanceof FireFighter){ + System.out.print(" ff | "); + }else{ + System.out.print(" | "); + } + } else { System.out.print(" | "); } @@ -82,7 +95,7 @@ public class Matrix<E> implements Iterable<E> { System.out.println(); } } - */ + private void validateIndex(int x, int y) { if (x < 0 || x >= rows || y < 0 || y >= columns) { diff --git a/src/main/java/util/PositionUtil.java b/src/main/java/util/PositionUtil.java index 7b2b235..48f5436 100644 --- a/src/main/java/util/PositionUtil.java +++ b/src/main/java/util/PositionUtil.java @@ -2,8 +2,31 @@ package util; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import model.Board; +import model.Entity; public class PositionUtil { + /** + * Calcule et retourne une liste de positions situées à une distance de + * Manhattan spécifique à partir d'une position donnée. + * La distance de Manhattan entre deux points (x1, y1) et (x2, y2) est donnée + * par |x1 - x2| + |y1 - y2|. + * Cette méthode génère toutes les positions possibles à cette distance dans une + * grille de taille spécifiée. + * + * @param fromPos la position de départ à partir de laquelle la distance est + * calculée. + * @param distance la distance de Manhattan à utiliser pour trouver les + * positions. + * @param rows le nombre de lignes dans la grille. + * @param cols le nombre de colonnes dans la grille. + * @return une liste de positions à la distance de Manhattan spécifiée de la + * position initiale, qui se trouvent également dans les limites de la + * grille. + */ public static List<Position> getPositionsAtManhattanDistance(Position fromPos, int distance, int rows, int cols) { List<Position> positions = new ArrayList<>(); int x0 = fromPos.x(); @@ -27,4 +50,64 @@ public class PositionUtil { return positions; } + + /** + * Génère une liste de positions adjacentes à une position donnée, en vérifiant + * si chaque position est valide dans le contexte du jeu. + * + * @param position la position de départ pour laquelle générer les positions + * adjacentes. + * @param board l'objet représentant le plateau de jeu qui permet de vérifier + * si une position existe. + * @return une liste des positions adjacentes valides. + */ + public static List<Position> generateAdjacentPositions(Position position, Board<Entity> board) { + int x = position.x(); + int y = position.y(); + + return Stream.of( + new Position(x, y + 1), + new Position(x + 1, y), + new Position(x, y - 1), + new Position(x - 1, y)) + .filter(p -> board.doesPositionExist(p)) + .collect(Collectors.toList()); + } + + // Méthode pour générer toutes les positions adjacentes (y compris les + // diagonales) + public static List<Position> generateAllAdjacentPositions(Position position, Board<Entity> board) { + int x = position.x(); + int y = position.y(); + + List<Position> positions = new ArrayList<>(); + + // Liste des 8 déplacements possibles + int[][] deltas = { + { 1, 0 }, // x+1, y + { -1, 0 }, // x-1, y + { 0, 1 }, // x, y+1 + { 0, -1 }, // x, y-1 + { 1, 1 }, // x+1, y+1 + { -1, -1 }, // x-1, y-1 + { 1, -1 }, // x+1, y-1 + { -1, 1 } // x-1, y+1 + }; + + for (int[] delta : deltas) { + int newX = x + delta[0]; + int newY = y + delta[1]; + Position p = new Position(newX, newY); + if (board.doesPositionExist(p)) { + positions.add(p); + } + } + + return positions; + } + + public static int getManhattanDistance(Position p1, Position p2) { + return Math.abs(p1.x() - p2.x()) + Math.abs(p1.y() - p2.y()); + } + } \ No newline at end of file -- GitLab