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
Loading items

Target

Select target project
  • l22015417/firefighterstarter
  • 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
24 results
Select Git revision
Loading items
Show changes
Showing
with 627 additions and 69 deletions
package util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import model.Board;
public class PathGenerator {
private Board<?> board;
private final Random random = new Random();
private final int maxStepsInDirection;
private final int minimumRoadLength;
private final Set<Direction> initialExcludedDirections = new HashSet<>();
private final Position anchor;
private Position currentPosition;
private Direction currentDirection;
private Direction excludedDirection = null;
private Direction lastDirection = null;
private int stepsInCurrentDirection = 0;
private int roadLength = 1;
private final List<Position> path = new ArrayList<>();
/**
* Constructeur de PathGenerator.
*
* @param board Le plateau de jeu.
* @param anchor La position de départ.
* @param maxStepsInDirection Nombre maximal de pas dans une direction avant de changer.
* @param minimumRoadLength Longueur minimale du chemin.
*/
public PathGenerator(Board<?> board, Position anchor, int maxStepsInDirection, int minimumRoadLength) {
this.board = board;
this.anchor = anchor;
this.maxStepsInDirection = maxStepsInDirection;
this.minimumRoadLength = minimumRoadLength;
initializePath();
}
/**
* Génère le chemin en respectant les contraintes.
*
* @return Liste des positions formant le chemin.
*/
public List<Position> generate() {
while (true) {
if (canMoveInCurrentDirection()) {
moveInCurrentDirection();
if (shouldChangeDirection()) {
if (!changeDirection(false)) break;
}
} else {
if (!handleObstacle()) break;
}
}
return roadLength >= minimumRoadLength ? path : regeneratePath();
}
public void setBoard(Board<?> board){
this.board = board;
}
/** Initialise le chemin avec l'ancre et choisit la première direction. */
private void initializePath() {
path.clear();
roadLength = 1;
stepsInCurrentDirection = 0;
currentPosition = anchor;
path.add(anchor);
currentDirection = DirectionUtils.getRandomDirection();
initialExcludedDirections.clear();
initialExcludedDirections.add(currentDirection);
lastDirection = currentDirection;
excludedDirection = null;
}
/** Vérifie si le mouvement dans la direction actuelle est possible. */
private boolean canMoveInCurrentDirection() {
Position nextPosition = currentPosition.move(currentDirection);
return board.doesPositionExist(nextPosition);
}
/** Effectue le mouvement dans la direction actuelle. */
private void moveInCurrentDirection() {
currentPosition = currentPosition.move(currentDirection);
path.add(currentPosition);
roadLength++;
stepsInCurrentDirection++;
excludedDirection = DirectionUtils.getOpposite(currentDirection);
}
/** Détermine si un changement de direction est nécessaire. */
private boolean shouldChangeDirection() {
return stepsInCurrentDirection >= maxStepsInDirection;
}
/**
* Change la direction actuelle.
*
* @param mustContinue Si true, la nouvelle direction doit permettre de continuer le chemin.
* @return true si la direction a été changée avec succès, sinon false.
*/
private boolean changeDirection(boolean mustContinue) {
Direction newDirection = chooseNewDirection(mustContinue);
if (newDirection == null) return false;
updateDirection(newDirection);
return true;
}
/** Gère le cas où le mouvement n'est pas possible (obstacle ou bord du plateau). */
private boolean handleObstacle() {
if (roadLength < minimumRoadLength) {
return changeDirection(true);
}
return false;
}
/** Réinitialise et génère à nouveau le chemin. */
private List<Position> regeneratePath() {
initializePath();
return generate();
}
/** Met à jour la direction actuelle et les compteurs associés. */
private void updateDirection(Direction newDirection) {
currentDirection = newDirection;
stepsInCurrentDirection = 0;
lastDirection = newDirection;
excludedDirection = DirectionUtils.getOpposite(newDirection);
}
/**
* Choisit une nouvelle direction valide en tenant compte des exclusions.
*
* @param mustContinue Si true, la direction doit permettre de continuer le chemin.
* @return La nouvelle direction choisie ou null si aucune n'est valide.
*/
private Direction chooseNewDirection(boolean mustContinue) {
Set<Direction> exclusions = new HashSet<>(initialExcludedDirections);
Collections.addAll(exclusions, excludedDirection, lastDirection);
List<Direction> validDirections = getValidDirections(exclusions, currentPosition);
if (mustContinue) {
validDirections = filterDirectionsToContinue(validDirections, currentPosition);
}
return validDirections.isEmpty() ? null : validDirections.get(random.nextInt(validDirections.size()));
}
/**
* Obtient les directions valides à partir de la position actuelle.
*
* @param exclusions Les directions à exclure.
* @param currentPosition La position actuelle.
* @return Liste des directions valides.
*/
private List<Direction> getValidDirections(Set<Direction> exclusions, Position currentPosition) {
List<Direction> validDirections = new ArrayList<>();
for (Direction dir : Direction.values()) {
if (!exclusions.contains(dir)) {
Position nextPos = currentPosition.move(dir);
if (board.doesPositionExist(nextPos)) {
validDirections.add(dir);
}
}
}
return validDirections;
}
/**
* Filtre les directions pour s'assurer qu'elles permettent de continuer le chemin.
*
* @param directions Liste des directions valides.
* @param currentPosition La position actuelle.
* @return Liste des directions permettant de continuer.
*/
private List<Direction> filterDirectionsToContinue(List<Direction> directions, Position currentPosition) {
List<Direction> filtered = new ArrayList<>();
for (Direction dir : directions) {
Position nextPos = currentPosition.move(dir);
Set<Direction> futureExclusions = new HashSet<>(initialExcludedDirections);
futureExclusions.add(DirectionUtils.getOpposite(dir));
if (!getValidDirections(futureExclusions, nextPos).isEmpty()) {
filtered.add(dir);
}
}
return filtered;
}
}
package util;
public record Position(int row, int column) {
public record Position(int x, int y) {
// Méthode pour déplacer la position dans une direction donnée
public Position move(Direction direction) {
int newX = this.x + DirectionUtils.getXIncrement(direction);
int newY = this.y + DirectionUtils.getYIncrement(direction);
return new Position(newX, newY);
}
}
package util;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import model.Board;
import model.Square;
import model.firefighterscenario.FireFighter;
import model.firefighterscenario.Mountain;
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();
int y0 = fromPos.y();
// Générer toutes les positions à une distance de Manhattan donnée
for (int dx = -distance; dx <= distance; dx++) {
int dy = distance - Math.abs(dx);
int[] dyOptions = { dy, -dy };
for (int deltaY : dyOptions) {
int x = x0 + dx;
int y = y0 + deltaY;
// Vérifier si la position est dans les limites de la matrice
if (x >= 0 && x < rows && y >= 0 && y < cols) {
positions.add(new Position(x, y));
}
}
}
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<Square> 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());
}
public static List<Position> generateAdjacentPositions(Position position, Board<Square> board, int distance) {
List<Position> positions = new ArrayList<Position>();
for(int i = 0; i < 4; i++){
}
return positions;
}
// Méthode pour générer toutes les positions adjacentes (y compris les
// diagonales)
public static List<Position> generateAllAdjacentPositions(Position position, Board<Square> 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());
}
/**
* Generates all positions within a specified radius from a center position.
* It uses Manhattan distance by default.
*
* @param center The center position.
* @param radius The radius (distance) from the center position.
* @param board The board to consider boundaries.
* @return A list of positions within the radius.
*/
public static List<Position> getPositionsInRadius(Position center, int radius, Board<Square> board) {
List<Position> positions = new ArrayList<>();
int startX = center.x() - radius;
int endX = center.x() + radius;
int startY = center.y() - radius;
int endY = center.y() + radius;
for (int x = startX; x <= endX; x++) {
for (int y = startY; y <= endY; y++) {
Position pos = new Position(x, y);
if (board.doesPositionExist(pos)) {
// Calculate Manhattan distance from the center
int distance = Math.abs(center.x() - x) + Math.abs(center.y() - y);
if (distance <= radius) {
positions.add(pos);
}
}
}
}
return positions;
}
public static Position getNextPositionTowards(Position currentPos, Position targetPos, Board<Square> b) {
// Generate adjacent positions
List<Position> possibleMoves = PositionUtil.generateAllAdjacentPositions(currentPos, b);
// Filter out positions that are not empty or contain obstacles
possibleMoves.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
// If no possible moves, return null
if (possibleMoves.isEmpty()) {
return null;
}
// Calculate the current distance to the target
int currentDistance = PositionUtil.getManhattanDistance(currentPos, targetPos);
// Initialize variables to find the best moves
int minDistance = Integer.MAX_VALUE;
List<Position> bestMoves = new ArrayList<>();
for (Position move : possibleMoves) {
int distance = PositionUtil.getManhattanDistance(move, targetPos);
// Skip positions occupied by other firefighters
if (b.doesSquareContainEntity(move, FireFighter.class)) {
continue;
}
// Find positions that minimize the distance
if (distance < minDistance) {
minDistance = distance;
bestMoves.clear();
bestMoves.add(move);
} else if (distance == minDistance) {
bestMoves.add(move);
}
}
// If no better move is found, consider moves that maintain the same distance
if (bestMoves.isEmpty()) {
minDistance = currentDistance;
for (Position move : possibleMoves) {
int distance = PositionUtil.getManhattanDistance(move, targetPos);
if (distance == minDistance) {
bestMoves.add(move);
}
}
}
// If still no move is found, stay in the current position
if (bestMoves.isEmpty()) {
return currentPos;
}
// Select a move from the best moves (e.g., randomly or based on additional criteria)
Random r = new Random();
Position nextMove = bestMoves.get(r.nextInt(bestMoves.size()));
return nextMove;
}
public static Position getNextPositionAwayFrom(Position currentPos, Position targetPos, Board<Square> b) {
// Générer les positions adjacentes
List<Position> possibleMoves = PositionUtil.generateAllAdjacentPositions(currentPos, b);
// Filtrer les positions qui ne sont pas vides ou contiennent des obstacles
possibleMoves.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
// Si aucune possibilité de déplacement, retourner null
if (possibleMoves.isEmpty()) {
return null;
}
// Calculer la distance actuelle par rapport à la cible
int currentDistance = PositionUtil.getManhattanDistance(currentPos, targetPos);
// Initialiser les variables pour trouver les meilleurs déplacements
int maxDistance = Integer.MIN_VALUE;
List<Position> bestMoves = new ArrayList<>();
for (Position move : possibleMoves) {
int distance = PositionUtil.getManhattanDistance(move, targetPos);
// Ignorer les positions occupées par d'autres entités, comme les pompiers
if (b.doesSquareContainEntity(move, FireFighter.class)) {
continue;
}
// Trouver les positions qui maximisent la distance
if (distance > maxDistance) {
maxDistance = distance;
bestMoves.clear();
bestMoves.add(move);
} else if (distance == maxDistance) {
bestMoves.add(move);
}
}
// Si aucun meilleur déplacement n'est trouvé, considérer les mouvements qui maintiennent la même distance
if (bestMoves.isEmpty()) {
maxDistance = currentDistance;
for (Position move : possibleMoves) {
int distance = PositionUtil.getManhattanDistance(move, targetPos);
if (distance == maxDistance) {
bestMoves.add(move);
}
}
}
// Si toujours aucun mouvement n'est trouvé, rester à la position actuelle
if (bestMoves.isEmpty()) {
return currentPos;
}
// Sélectionner un mouvement parmi les meilleurs mouvements (par exemple aléatoirement ou selon des critères supplémentaires)
Random r = new Random();
Position nextMove = bestMoves.get(r.nextInt(bestMoves.size()));
return nextMove;
}
public static Direction getOppositeDirection(Direction direction) {
switch (direction) {
case NORTH: return Direction.SOUTH;
case SOUTH: return Direction.NORTH;
case EAST: return Direction.WEST;
case WEST: return Direction.EAST;
default: throw new IllegalArgumentException("Direction non supportée : " + direction);
}
}
/**
* Détermine la direction principale (NORTH, SOUTH, EAST, WEST) de toPos par rapport à fromPos.
*
* @param fromPos la position de départ.
* @param toPos la position de destination.
* @return la direction principale de toPos par rapport à fromPos.
*/
public static Direction getDirectionFromTwoPoints(Position fromPos, Position toPos) {
int deltaX = toPos.x() - fromPos.x();
int deltaY = toPos.y() - fromPos.y();
if (deltaX == 0 && deltaY == 0) {
return null; // Les positions sont identiques
}
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// Mouvement principalement vers l'Est ou l'Ouest
if (deltaX > 0) {
return Direction.EAST;
} else {
return Direction.WEST;
}
} else {
// Mouvement principalement vers le Nord ou le Sud
if (deltaY > 0) {
return Direction.SOUTH;
} else {
return Direction.NORTH;
}
}
}
}
\ No newline at end of file
package model;
package util;
import util.Position;
import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
public class TargetStrategy {
......@@ -12,7 +17,7 @@ public class TargetStrategy {
* @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,
public 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>();
......
package view;
import java.util.List;
import javafx.scene.canvas.Canvas;
import javafx.scene.image.Image;
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.x(), position.y(), element.getColor());
//}
private void paintElementAtPosition(ViewElement element, Position position) {
paintBox(position.row(), position.column(), element.color);
// Efface la case pour éviter les superpositions
clearBox(position.x(), position.y());
// Vérifie si une image est définie dans l'élément
if (element.getImage() != null) {
Image image = element.getImage();
getGraphicsContext2D().drawImage(image, position.y() * boxWidth, position.x() * boxHeight, boxWidth, boxHeight);
} else {
paintBox(position.x(), position.y(), element.getColor());
}
}
private int boxWidth;
private int boxHeight;
private int columnCount;
......@@ -27,7 +42,7 @@ public class FirefighterGrid extends Canvas implements Grid<ViewElement>{
private void clear(List<Pair<Position, ViewElement>> positionedElements) {
for (Pair<Position, ViewElement> positionElement : positionedElements) {
Position position = positionElement.getKey();
clearBox(position.row(), position.column());
clearBox(position.x(), position.y());
}
}
......
package view;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
public enum ViewElement {
FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE);
final Color color;
ViewElement(Color color) {
public class ViewElement {
private final Color color;
private final Image image;
// Constructeur avec couleur uniquement
public ViewElement(Color color) {
this.color = color;
this.image = null;
}
// Constructeur avec image
public ViewElement(Image image) {
this.color = null;
this.image = image;
}
public Color getColor() {
return color;
}
public Image getImage() {
return image;
}
}
......@@ -113,7 +113,7 @@
-fx-background-color: #3a3a3a;
}
.button:pressed, .button:default:hover:pressed {
.button:default:hover:pressed {
-fx-background-color: white;
-fx-text-fill: #1d1d1d;
}
......
src/main/resources/view/icons/fire/avion.png

26.4 KiB

src/main/resources/view/icons/fire/camion.png

24.6 KiB

src/main/resources/view/icons/fire/flamme.png

19.2 KiB

src/main/resources/view/icons/fire/img.png

356 B

src/main/resources/view/icons/fire/montagne.png

37.8 KiB

src/main/resources/view/icons/fire/nuage.png

66.7 KiB

src/main/resources/view/icons/fire/rochers.png

46.3 KiB

src/main/resources/view/icons/fire/route.png

2.18 KiB

src/main/resources/view/icons/fire/sapeur-pompier.png

26.9 KiB

src/main/resources/view/icons/pfc/cis.png

21.6 KiB

src/main/resources/view/icons/pfc/paper.png

9.57 KiB

src/main/resources/view/icons/pfc/rock.png

28.3 KiB