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 2628 additions and 1 deletion
package model.doctorviruspatient;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import model.firefighterscenario.Cloud;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Doctor implements Entity {
private final int priority = 1;
private Position position;
private int age;
private final Color viewColor = Color.RED;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/virus/docteur.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
// Statique car les médecins partagent les connaissances et les recherches
private static List<Integer> knownVirusVariant = new ArrayList<Integer>();
private static Map<Integer, Double> currentResearch = new HashMap<>(); // Map<variantId, % de recherche>
public Doctor(Position p) {
this.position = p;
}
public Doctor(Position p, int age) {
this.position = p;
this.age = age;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
// Mettre à jour les recherches en cours
updateCurrentResearch();
// Interagir avec les positions adjacentes
interactWithAdjacentPositions(PositionUtil.generateAllAdjacentPositions(position, board), board);
return List.of();
}
/**
* Met à jour toutes les recherches en cours en augmentant leur avancement de x%.
* Si une recherche atteint ou dépasse 100%, elle est terminée.
*/
private void updateCurrentResearch() {
List<Integer> completedResearch = new ArrayList<>();
for (Map.Entry<Integer, Double> entry : currentResearch.entrySet()) {
int variantId = entry.getKey();
double progress = entry.getValue() + 2.0;
if (progress >= 100.0) {
progress = 100.0;
completedResearch.add(variantId);
}
currentResearch.put(variantId, progress);
}
// Traiter les recherches complétées
for (int variantId : completedResearch) {
currentResearch.remove(variantId);
knownVirusVariant.add(variantId);
System.out.println("Recherche terminée pour le variant ID: " + variantId);
}
}
private List<Position> interactWithAdjacentPositions(List<Position> adjacentPositions, Board<Square> board) {
List<Position> result = new ArrayList<>();
for (Position p : adjacentPositions) {
if (board.doesSquareContainEntity(p, Patient.class)) {
handleEncounterWithPatient(p, board);
}
}
return result;
}
private void handleEncounterWithPatient(Position p, Board<Square> board) {
if (board.doesSquareContainEntity(p, Patient.class)) {
Patient patient = (Patient) board.getStates(p).getEntities().stream()
.filter(e -> e instanceof Patient)
.findFirst()
.orElse(null);
if (patient != null && patient.isInfected()) {
Virus virus = patient.getVirus();
if (virus != null) {
int variantId = virus.getVariantId();
if (knownVirusVariant.contains(variantId)) {
patient.cure();
} else {
// Si la variante n'est pas connue et pas en cours de recherche, l'ajouter à la recherche
if (!currentResearch.containsKey(variantId)) {
currentResearch.put(variantId, 0.0);
System.out.println("Nouvelle variante détectée! Variant ID: " + variantId + ". Recherche commencée.");
}
}
}
}
}
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Doctor) {
Doctor other = (Doctor) obj;
return this.position.equals(other.getPosition());
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(position);
}
@Override
public ViewElement getViewElement() {
return new ViewElement (cloudImage);
}
}
package model.doctorviruspatient;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import model.Board;
import model.Entity;
import model.EntityFactory;
import model.Model;
import model.Scenario;
import model.Square;
import util.Position;
public class DoctorVirusPatientScenario extends Scenario implements Model{
public DoctorVirusPatientScenario(int columns, int rows, Map<EntityFactory, Integer> initialMap) {
super(columns, rows, initialMap);
}
public List<Position> updateToNextGeneration() {
ArrayList<Position> changedPositions = new ArrayList<>();
Iterator<Square> iterator = getMatrix().iterator();
while (iterator.hasNext()) {
Square s = iterator.next();
if (s.isEmpty())
continue;
if (s.getMaxAge() == 0) {
s.incrementAllAges();
continue;
}
if(s.getMaxAge()>stepNumber()+1){
continue;
}
List<Entity> entities = new ArrayList<>(s.getEntities());
for (Entity e : entities) {
e.incrementAge();
changedPositions.addAll(e.nextTurn(this));
}
}
// Increment the step counter
this.step = this.step + 1;
return changedPositions;
}
@Override
public Board<Square> getBoard() {
return this;
}
}
package model.doctorviruspatient;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import model.firefighterscenario.Cloud;
import util.PathGenerator;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Patient implements Entity {
private final int priority = 1;
private Position position;
private int age;
private final Color viewColor = Color.BLUE;
private Virus carriedVirus;
private List<Entity> visitedPatients;
private static int patientsCount = 0;
private int patientID;
private Position ennemy;
private boolean isAsymptomatic;
private boolean wandering;
private static javafx.scene.image.Image healthyImage;
private static javafx.scene.image.Image infectedImage;
static {
try {
healthyImage = new javafx.scene.image.Image(Patient.class.getResource("/view/icons/virus/humain.png").toExternalForm());
infectedImage = new javafx.scene.image.Image(Patient.class.getResource("/view/icons/virus/patient.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
// Attributs pour le chemin
private List<Position> path;
private int pathIndex;
private static final int MAX_STEPS_IN_DIRECTION = 5;
private static final int MINIMUM_ROAD_LENGTH = 10;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/virus/humain.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Patient(Position p) {
this.wandering = true;
patientID = patientsCount;
patientsCount += 1;
this.visitedPatients = new ArrayList<>();
this.position = p;
Random r = new Random();
int randomNumber = r.nextInt(10);
this.isAsymptomatic = randomNumber == 1;
// Initialiser le chemin
this.path = new ArrayList<>();
this.pathIndex = 0;
}
public Patient(Position p, int age) {
this.wandering = true;
patientID = patientsCount;
patientsCount += 1;
this.visitedPatients = new ArrayList<>();
this.position = p;
this.age = age;
Random r = new Random();
int randomNumber = r.nextInt(10);
this.isAsymptomatic = randomNumber == 1;
// Initialiser le chemin
this.path = new ArrayList<>();
this.pathIndex = 0;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
if (isInfected() && !isAsymptomatic) {
return moveToDoctor(board);
}
updateWanderingStatus(board);
if (wandering) {
return performWandering(board);
}
resetVisitedPatientsIfNecessary();
Position target = determineTarget(board);
if (target == null) {
visitedPatients.clear();
return List.of();
}
Position nextPos = determineNextPosition(target, board);
if (nextPos != null && board.doesPositionExist(nextPos)) {
List<Position> adjacentPositions = PositionUtil.generateAllAdjacentPositions(nextPos, board);
List<Position> result = interactWithAdjacentPositions(adjacentPositions, board);
result.addAll(moveToPosition(nextPos, board));
result.addAll(adjacentPositions);
result.add(position);
return result;
}
return List.of();
}
private void updateWanderingStatus(Board<Square> board) {
if (board.getStepNumber() % 8 == 0) {
wandering = false;
// Réinitialiser le chemin lorsque le patient arrête d'errer
this.path.clear();
this.pathIndex = 0;
}
}
private List<Position> moveToDoctor(Board<Square> board) {
for (Position p : PositionUtil.generateAllAdjacentPositions(position, board)) {
if (!board.doesPositionExist(p)) continue;
if (board.doesSquareContainEntity(p, Doctor.class)) return List.of();
}
Position nearestDoctor = board.getNearestEntity(position, Doctor.class, null);
Position nextPos = PositionUtil.getNextPositionTowards(position, nearestDoctor, board);
if (nextPos == null) return List.of();
List<Position> changedPositions = new ArrayList<>();
changedPositions.addAll(moveToPosition(nextPos, board));
return changedPositions;
}
private List<Position> performWandering(Board<Square> board) {
if (path == null || path.isEmpty() || pathIndex >= path.size()) {
generateNewPath(board);
if (path.isEmpty()) {
return List.of();
}
}
Position nextPosition = path.get(pathIndex);
if (board.doesPositionExist(nextPosition) && board.isPositionFree(nextPosition, priority)) {
List<Position> changedPositions = moveSelfOnBoard(nextPosition, board);
pathIndex++;
return changedPositions;
} else {
// Si la position n'est pas libre ou n'existe pas, générer un nouveau chemin
generateNewPath(board);
return List.of();
}
}
private void generateNewPath(Board<Square> board) {
PathGenerator pathGenerator = new PathGenerator(board, position, MAX_STEPS_IN_DIRECTION, MINIMUM_ROAD_LENGTH);
this.path = pathGenerator.generate();
// Supprimer la position actuelle du chemin si elle est présente
if (!path.isEmpty() && path.get(0).equals(position)) {
path.remove(0);
}
this.pathIndex = 0;
}
private void resetVisitedPatientsIfNecessary() {
if (visitedPatients.size() - 1 >= patientsCount) {
visitedPatients.clear();
}
}
private Position determineTarget(Board<Square> board) {
return board.getNearestEntity(position, Patient.class, getVisitedPatients());
}
private Position determineNextPosition(Position target, Board<Square> board) {
int enemyDistance = PositionUtil.getManhattanDistance(target, position);
if (ennemy != null && enemyDistance < 2) {
return PositionUtil.getNextPositionAwayFrom(position, target, board);
} else if (target != null) {
return PositionUtil.getNextPositionTowards(position, target, board);
}
return null;
}
private List<Position> moveToPosition(Position nextPos, Board<Square> board) {
List<Position> changedPosition = new ArrayList<>();
if (!board.isPositionFree(nextPos, priority)) {
nextPos = findAlternativePosition(nextPos, board);
}
if (nextPos != null) {
changedPosition.addAll(moveSelfOnBoard(nextPos, board));
}
return changedPosition;
}
private Position findAlternativePosition(Position currentPos, Board<Square> board) {
List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, board);
for (Position p : adjacentPositions) {
if (ennemy != null) {
Position awayPos = PositionUtil.getNextPositionAwayFrom(p, ennemy, board);
if (p.equals(awayPos)) {
continue;
}
}
if (board.isPositionFree(p, priority)) {
return p;
}
}
return null;
}
private List<Position> moveSelfOnBoard(Position newPosition, Board<Square> board) {
if(!board.isPositionFree(newPosition, priority))return List.of();
Position oldPosition = new Position(this.position.x(), this.position.y());
board.clearCaseFrom(this, oldPosition);
board.addEntityAtSquare(this, newPosition);
this.position = newPosition;
return List.of(oldPosition, this.position);
}
private List<Position> interactWithAdjacentPositions(List<Position> adjacentPositions, Board<Square> board) {
List<Position> result = new ArrayList<>();
for (Position p : adjacentPositions) {
if (board.doesSquareContainEntity(p, Patient.class)) {
handleEncounterWithPatient(p, board);
if (isInfected()) {
result.addAll(adjacentPositions);
}
}
}
return result;
}
private void handleEncounterWithPatient(Position p, Board<Square> board) {
this.wandering = true;
// Réinitialiser le chemin lorsqu'un patient est rencontré
this.path.clear();
this.pathIndex = 0;
Patient patient = (Patient) board.getStates(p).getEntities().stream()
.filter(entity -> entity instanceof Patient)
.findFirst()
.orElse(null);
if (isInfected()) {
patient.infect(carriedVirus);
}
if (patient != null) {
this.ennemy = patient.getPosition();
visitedPatients.add(patient);
}
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return isInfected() ? Color.CYAN : this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
public boolean isInfected() {
return this.carriedVirus != null;
}
public void infect(Virus virus) {
if (this.carriedVirus != null) return;
this.carriedVirus = virus;
}
public Virus getVirus() {
return this.carriedVirus;
}
public List<Entity> getVisitedPatients() {
return this.visitedPatients;
}
public boolean hasVisited(Patient patient) {
return this.getVisitedPatients().contains(patient);
}
public int getPatientId() {
return this.patientID;
}
public void cure() {
if (this.carriedVirus.tryToKill()) {
this.carriedVirus = null;
}
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Patient) {
Patient other = (Patient) obj;
return this.patientID == other.getPatientId();
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(patientID);
}
@Override
public ViewElement getViewElement() {
return isInfected() ? new ViewElement(infectedImage) : new ViewElement(healthyImage);
}
}
package model.doctorviruspatient;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import model.firefighterscenario.Cloud;
import util.PathGenerator;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Virus implements Entity {
private final int priority = 2;
private Position position;
private int age;
private final Color viewColor = Color.LIMEGREEN;
private List<Position> path;
private int pathIndex;
private static final int MAX_STEPS_IN_DIRECTION = 5;
private static final int MINIMUM_ROAD_LENGTH = 10;
private int health;
private int variantId;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/virus/virus.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Virus(Position p) {
this.variantId = 0;
this.health = 50;
this.position = p;
this.path = new ArrayList<>();
this.age = 0;
this.pathIndex = 0;
}
public Virus(Position p, int age) {
this.health = 8;
this.position = p;
this.age = age;
this.path = new ArrayList<>();
this.pathIndex = 0;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
if(board.getStepNumber() % 100 == 0){
evolve();
}
// Génère un nouveau chemin si nécessaire
if (path == null || path.isEmpty() || pathIndex >= path.size()) {
generateNewPath(board);
if (path.isEmpty()) {
return List.of();
}
}
List<Position> adjacentPosition = PositionUtil.generateAllAdjacentPositions(position, board);
for(Position p : adjacentPosition){
if(board.doesSquareContainEntity(p, Patient.class)){
Patient patient = (Patient) board.getStates(p).getEntities().stream().filter(e -> e instanceof Patient).findFirst().get();
patient.infect(this);
}
}
// Se déplace vers la prochaine position du chemin
Position nextPosition = path.get(pathIndex);
if (board.doesPositionExist(nextPosition)) {
// Vérifier si la position est libre
if (board.isPositionFree(nextPosition, priority)) {
Position oldPosition = position;
position = nextPosition;
board.clearCaseFrom(this, oldPosition);
board.addEntityAtSquare(this, position);
pathIndex = pathIndex + 1;
return List.of(oldPosition, position);
} else {
// Si la position n'est pas libre, génère un nouveau chemin
generateNewPath(board);
return List.of();
}
} else {
// Si la prochaine position n'existe pas, génère un nouveau chemin
generateNewPath(board);
return List.of();
}
}
private void generateNewPath(Board<Square> board) {
PathGenerator pathGenerator = new PathGenerator(board, position, MAX_STEPS_IN_DIRECTION, MINIMUM_ROAD_LENGTH);
this.path = pathGenerator.generate();
// Supprime la position actuelle du chemin si elle est présente au début
if (!path.isEmpty() && path.get(0).equals(position)) {
path.remove(0);
}
this.pathIndex = 0; // Réinitialise l'index du chemin
}
// Les autres méthodes restent inchangées
private void evolve(){
this.variantId++;
Random r = new Random();
this.health = r.nextInt(100);
}
public int getVariantId(){
return this.variantId;
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
public boolean tryToKill(){
if(health <= 0){
return true;
}
health--;
return false;
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.firefighterscenario;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import util.Direction;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class AirTanker implements Entity{
private final Color viewColor = Color.GOLD;
private Direction direction; // Direction in which the AirTanker moves
private int age;
private Position position;
private int priority = 3;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/fire/avion.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public AirTanker(Position position, Board<Square> b, int age) {
this.age = age;
this.position = position;
determineDirection(b);
extinguish(position,b);
}
@Override
public int getPriority() {
return this.priority;
}
private void determineDirection(Board<Square> b) {
int rowCount = b.rowCount();
int columnCount = b.columnCount();
if (position.x() == 0) {
direction = Direction.EAST; // Move east if on left edge
} else if (position.x() == columnCount - 1) {
direction = Direction.WEST; // Move west if on right edge
} else if (position.y() == 0) {
direction = Direction.SOUTH; // Move south if on top edge
} else if (position.y() == rowCount - 1) {
direction = Direction.NORTH; // Move north if on bottom edge
} else {
// Not on an edge; default to moving east or choose a random direction
direction = Direction.EAST;
}
}
@Override
public List<Position> nextTurn(Board<Square> b) {
List<Position> positions = new ArrayList<>();
// Move in the determined direction
Position nextPos = getNextPosition(position, direction, b);
if (nextPos == null || !b.doesPositionExist(nextPos)) {
// Reached the edge; remove AirTanker from the board
b.clearCaseFrom(this, position);
positions.add(position);
return positions;
} else {
// Extinguish fires within a 3-square radius
positions.addAll(extinguish(position, b));
// Move to the next position
b.clearCaseFrom(this, position);
positions.add(new Position(position.x(), position.y())); // Old position
this.position = nextPos;
b.addEntityAtSquare(this, nextPos);
positions.add(nextPos); // New position
return positions;
}
}
protected List<Position> extinguish(Position position, Board<Square> b){
List<Position> positions = new ArrayList<Position>();
List<Position> positionsInRange = PositionUtil.getPositionsInRadius(position, 3, b);
for (Position p : positionsInRange) {
if (b.doesSquareContainEntity(p, Fire.class)) {
b.getStates(p).getEntities().removeIf(e -> e instanceof Fire);
positions.add(p); // Add position where fire was extinguished
}
}
return positions;
}
private Position getNextPosition(Position currentPosition, Direction direction, Board<Square> b) {
int x = currentPosition.x();
int y = currentPosition.y();
switch (direction) {
case NORTH:
y -= 1;
break;
case SOUTH:
y += 1;
break;
case EAST:
x += 1;
break;
case WEST:
x -= 1;
break;
default:
break; // Only handling cardinal directions
}
Position newPos = new Position(x, y);
if (b.doesPositionExist(newPos)) {
return newPos;
} else {
return null; // Reached the edge
}
}
public Direction getDirection(){
return this.direction;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void incrementAge() {
this.age++;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // Check if same object
if (obj == null || getClass() != obj.getClass()) return false; // Check for null and class match
AirTanker airTanker = (AirTanker) obj; // Cast to Fire
return age == airTanker.age && position.equals(airTanker.position); // Compare age and position
}
@Override
public int hashCode() {
return Objects.hash(position, age);
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.firefighterscenario;
import java.util.List;
import java.util.Random;
import javafx.scene.paint.Color;
import model.Board;
import model.EmptySquare;
import model.Entity;
import model.Square;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Cloud implements Entity{
private int age;
private Position position;
private final Color viewColor = Color.GRAY;
private final int priority = 2;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/fire/nuage.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Cloud(Position position, Board<Square> b){
this.age = 0;
this.position = position;
}
public Cloud(Position position, Board<Square> b, int age){
this.age = age;
this.position = position;
}
@Override
public List<Position> nextTurn(Board<Square> b) {
List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, b);
adjacentPositions.removeIf( p -> b.doesSquareContainEntity(p, Cloud.class));
adjacentPositions.removeIf( p -> b.doesSquareContainEntity(p, Mountain.class));
// Filtrer pour obtenir uniquement les positions qui ne contiennent pas de pompier
adjacentPositions.removeIf(p -> b.doesSquareContainEntity(p, FireFighter.class));
// Choisir une position aléatoire parmi les mouvements possibles
if(adjacentPositions.size() < 0){
return List.of();
}
Position next_position = adjacentPositions.get(new Random().nextInt(adjacentPositions.size()));
// Si la nouvelle position contient un feu, éteindre le feu
if (b.getStates(next_position).getEntities().stream().anyMatch(element -> element instanceof Fire) ){
extinguish(next_position, b);
}
Position old_position = this.position;
this.position = next_position;
b.addEntityAtSquare(this, next_position);
b.clearCaseFrom(this, old_position);
return List.of(old_position, this.position);
}
private Position extinguish(Position p, Board<Square> b) {
b.getStates(p).getEntities().removeIf(element -> element instanceof Fire);
List<Entity> entities = b.getStates(p).getEntities();
for (Entity e : entities) {
if (e instanceof EmptySquare) {
e.setAge(b.stepNumber() + 1);
}
}
return p;
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age =age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority(){
return this.priority;
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.firefighterscenario;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Road;
import model.Square;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Fire implements Entity {
private Position position;
private final Color viewColor = Color.RED;
private int age;
private final int priority = 1;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/fire/flamme.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Fire(Position position) {
this.position = position;
this.age = 0;
}
public Fire(Position position, int age) {
this.position = position;
this.age = age;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
List<Position> newFirePositions = new ArrayList<>();
if(board.getStepNumber() <= 1){
return newFirePositions;
}
// Fire propagates every 2 turns
if (age % 2 != 0) {
return newFirePositions; // No propagation this turn
}
// Generate adjacent positions
List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, board);
for (Position p : adjacentPositions) {
// Skip if position does not exist
if (!board.doesPositionExist(p)) {
continue;
}
// Skip if the position contains a Mountain
if (board.doesSquareContainEntity(p, Mountain.class)) {
continue;
}
// Skip if the position already contains a Fire
if (board.doesSquareContainEntity(p, Fire.class)) {
continue;
}
// Skip if the position contains a Cloud (if clouds prevent fire spread)
if (board.doesSquareContainEntity(p, Road.class)) {
continue;
}
if (board.doesSquareContainEntity(p, Rockery.class)) {
Optional<Entity> e = board.getStates(p).getEntities().stream().findFirst();
if(e != null && e.isPresent() && e.get() instanceof Rockery){
Rockery rockery = (Rockery) e.get();
if(rockery.getBurn() < 4){
rockery.incrementBurn();
continue;
}
}
}
// Add new Fire to the board
board.addEntityAtSquare(new Fire(p), p);
newFirePositions.add(p); // Keep track of new fires for updates
}
return newFirePositions;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void incrementAge() {
this.age++;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public int getPriority() {
return this.priority;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // Check if same object
if (obj == null || getClass() != obj.getClass()) return false; // Check for null and class match
Fire fire = (Fire) obj; // Cast to Fire
return age == fire.age && position.equals(fire.position); // Compare age and position
}
@Override
public int hashCode() {
return Objects.hash(position, age);
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.firefighterscenario;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.scene.paint.Color;
import model.Board;
import model.EmptySquare;
import model.Entity;
import model.Square;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class FireFighter implements Entity {
private int age;
private Position position;
private final Color viewColor = Color.BLUE;
private final int priority = 1;
protected List<Position> lastThreePosition;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/fire/sapeur-pompier.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public FireFighter(Position position, Board<Square> b) {
this.position = position;
this.age = 0;
this.lastThreePosition = new ArrayList<Position>();
}
public FireFighter(Position position, Board<Square> b, int age) {
this.position = position;
this.age = age;
this.lastThreePosition = new ArrayList<Position>();
}
public List<Position> nextTurn(Board<Square> b) {
List<Position> positions = new ArrayList<>();
// Generate adjacent positions, excluding mountains
List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, b);
adjacentPositions.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
// Check if there is fire in any adjacent positions
boolean hasFire = adjacentPositions.stream()
.anyMatch(p -> b.doesSquareContainEntity(p, Fire.class));
boolean isStuck = isStuck();
if (hasFire) {
// Extinguish fires in adjacent positions
positions.addAll(extinguish(adjacentPositions, b));
if (isStuck) {
// If stuck, attempt to move and then extinguish fires
positions.addAll(moveAndExtinguish(b));
}
} else {
// No fire adjacent; move and attempt to extinguish fires
positions.addAll(moveAndExtinguish(b));
}
// Update last three positions
updateLastPositions();
return positions;
}
protected boolean isStuck() {
if (lastThreePosition.size() < 3) {
return false;
}
Position first = lastThreePosition.get(lastThreePosition.size() - 1);
return lastThreePosition.stream().allMatch(pos -> pos.equals(first));
}
private void updateLastPositions() {
if (lastThreePosition.size() >= 3) {
lastThreePosition.remove(0);
}
lastThreePosition.add(this.position);
}
protected List<Position> extinguish(List<Position> adjacentPositions, Board<Square> b) {
List<Position> extinguishedPositions = new ArrayList<>();
for (Position p : adjacentPositions) {
if (b.doesSquareContainEntity(p, Fire.class)) {
if(b.doesSquareContainEntity(p, Rockery.class)){
Rockery rockery = (Rockery) b.getStates(p).getEntities().stream()
.filter(Rockery.class::isInstance)
.findFirst().get();
rockery.resetBurn();
}
b.getStates(p).getEntities().removeIf(element -> element instanceof Fire);
// Update age for EmptyEntity if needed
b.getStates(p).getEntities().forEach(e -> {
if (e instanceof EmptySquare) {
e.setAge(b.stepNumber() + 1);
}
});
extinguishedPositions.add(p); // Add position where fire was extinguished
}
}
return extinguishedPositions;
}
protected List<Position> moveAndExtinguish(Board<Square> b) {
List<Position> positions = new ArrayList<>();
// Find the nearest fire
Position nearestFirePos;
try {
nearestFirePos = b.getNearestEntity(position, Fire.class, null);
} catch (Exception e) {
return List.of();
}
if (nearestFirePos != null) {
// Get the next position towards the fire
Position nextPos = getNextPositionTowards(position, nearestFirePos, b);
if (nextPos != null && !nextPos.equals(position)) {
// Move the firefighter
b.clearCaseFrom(this, position); // Clear old position
positions.add(new Position(position.x(), position.y())); // Add old position
this.position = nextPos;
b.addEntityAtSquare(this, nextPos); // Add to new position
positions.add(nextPos); // Add new position
// After moving, attempt to extinguish fires adjacent to new position
List<Position> newAdjacentPositions = PositionUtil.generateAdjacentPositions(nextPos, b);
newAdjacentPositions.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
positions.addAll(extinguish(newAdjacentPositions, b));
}
}
return positions;
}
protected 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;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public Position getPosition() {
return this.position;
}
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void incrementAge() {
this.age = age + 1;
}
@Override
public void setAge(int age) {
this.age = age;
}
public int getPriority(){ return this.priority;}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.firefighterscenario;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import model.Board;
import model.Entity;
import model.EntityFactory;
import model.Model;
import model.Road;
import model.Scenario;
import model.Square;
import util.PathGenerator;
import util.Position;
public class FireFighterScenario extends Scenario implements Model{
public FireFighterScenario(int columns, int rows, Map<EntityFactory, Integer> initialMap) {
super(columns, rows, initialMap);
generateRoads();
}
public List<Position> updateToNextGeneration() {
ArrayList<Position> changedPositions = new ArrayList<>();
Iterator<Square> iterator = getMatrix().iterator();
List<Entity> updatedEntities = new ArrayList<Entity>();
while (iterator.hasNext()) {
Square s = iterator.next();
if (s.isEmpty())
continue;
if (s.getMaxAge() == 0) {
s.incrementAllAges();
continue;
}
if (s.getMaxAge() == step + 1) {
continue;
}
List<Entity> entities = new ArrayList<>(s.getEntities());
for (Entity e : entities) {
if(updatedEntities.contains(e))continue;
if (e.getAge() >= stepNumber() - 1) {
continue;
}
e.incrementAge();
updatedEntities.add(e);
changedPositions.addAll(e.nextTurn(this));
}
}
// Increment the step counter
this.step = this.step + 1;
// Check if it's time to spawn an AirTanker
if (this.step % this.turnsToSpawnAirTanker == 0) {
// Spawn an AirTanker at a random edge position
spawnAirTanker(changedPositions);
}
return changedPositions;
}
// Helper method to spawn an AirTanker
private void spawnAirTanker(List<Position> changedPositions) {
Random rand = new Random();
int edge = rand.nextInt(4); // 0: top, 1: bottom, 2: left, 3: right
Position position = null;
if (edge == 0) { // Top edge (x == 0)
int y = rand.nextInt(columnCount() - 1);
position = new Position(0, y);
} else if (edge == 1) { // Bottom edge (x == rowCount() - 1)
int y = rand.nextInt(columnCount());
position = new Position(rowCount() - 1, y);
} else if (edge == 2) { // Left edge (y == 0)
int x = rand.nextInt(rowCount() - 1);
position = new Position(x, 0);
} else if (edge == 3) { // Right edge (y == columnCount() - 1)
int x = rand.nextInt(rowCount() - 1);
position = new Position(x, columnCount() - 1);
} else {
// This else block is technically not necessary because edge will always be
// between 0 and 3
throw new IllegalStateException("Unexpected edge value: " + edge);
}
// Create a new AirTanker
AirTanker airTanker = new AirTanker(position, this, getStepNumber());
// Add the AirTanker to the board
addEntityAtSquare(airTanker, position);
// Record the changed position
changedPositions.add(position);
}
private void generateRoads() {
if(columnCount() < 10 || rowCount() < 10){
return;
}
Random random = new Random();
// Get board dimensions
int rowCount = rowCount(); // Number of rows (vertical axis)
int columnCount = columnCount(); // Number of columns (horizontal axis)
// Decide randomly whether to set x or y to 0
boolean setXToZero = random.nextBoolean();
int x = 0;
int y = 0;
if (setXToZero) {
// x is set to 0, y is random within column bounds
x = 0;
y = random.nextInt(columnCount);
} else {
// y is set to 0, x is random within row bounds
x = random.nextInt(rowCount);
y = 0;
}
Position startPosition = new Position(x, y);
PathGenerator pathGenerator = new PathGenerator(this, startPosition, 4, columnCount());
// Call generateEntitiesInLine to place the roads
List<Position> snake = pathGenerator.generate();
for(Position p : snake){
List<Entity> entitiesAtSquare = List.copyOf(getStates(p).getEntities());
for(Entity e: entitiesAtSquare){
if(e instanceof Mountain || e instanceof Rockery || e instanceof Fire){
clearCaseFrom(e, e.getPosition());
}
}
addEntityAtSquare(new Road(p), p);
}
}
@Override
public Board<Square> getBoard() {
return this;
}
public void reset() {
step = 0;
super.getMatrix().clear();
initScenario(super.getMatrix());
placeInitialEntities(initialMap);
generateRoads();
}
}
package model.firefighterscenario;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.paint.Color;
import model.Board;
import model.Square;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class MotorizedFireFighter extends FireFighter {
private final Color viewColor = Color.CYAN;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/fire/camion.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public MotorizedFireFighter(Position position, Board<Square> b) {
super(position, b);
}
@Override
public List<Position> nextTurn(Board<Square> b) {
List<Position> positions = new ArrayList<>();
// Generate adjacent positions excluding mountains
List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(getPosition(), b);
adjacentPositions.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
// Check if there is fire in any adjacent positions
boolean hasFire = adjacentPositions.stream()
.anyMatch(p -> b.doesSquareContainEntity(p, Fire.class));
boolean isStuck = isStuck();
if (hasFire) {
// Extinguish fires in adjacent positions
positions.addAll(extinguish(adjacentPositions, b));
if (isStuck) {
// If stuck, attempt to move and extinguish after moving
positions.addAll(moveAndExtinguish(b));
}
} else {
// No fire adjacent; move and attempt to extinguish fires
positions.addAll(moveAndExtinguish(b));
}
// Update last positions for stuck detection
updateLastPositions();
return positions;
}
@Override
protected List<Position> moveAndExtinguish(Board<Square> b) {
List<Position> positions = new ArrayList<>();
// Find the nearest fire
Position nearestFirePos;
try {
nearestFirePos = b.getNearestEntity(getPosition(), Fire.class, null);
} catch (Exception e) {
return List.of();
}
if (nearestFirePos != null) {
// Get the next position after moving up to two steps towards the fire
Position nextPos = getNextPositionTowards(getPosition(), nearestFirePos, b, 2);
if (nextPos != null && !nextPos.equals(getPosition())) {
// Move the firefighter
b.clearCaseFrom(this, getPosition()); // Clear old position
positions.add(new Position(getPosition().x(), getPosition().y())); // Add old position
setPosition(nextPos);
b.addEntityAtSquare(this, nextPos); // Add to new position
positions.add(nextPos); // Add new position
// After moving, attempt to extinguish fires adjacent to new position
List<Position> newAdjacentPositions = PositionUtil.generateAdjacentPositions(nextPos, b);
newAdjacentPositions.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
positions.addAll(extinguish(newAdjacentPositions, b));
}
}
return positions;
}
// Overloaded method to handle multiple steps
protected Position getNextPositionTowards(Position currentPos, Position targetPos, Board<Square> b, int steps) {
Position nextPos = currentPos;
for (int i = 0; i < steps; i++) {
Position stepPos = super.getNextPositionTowards(nextPos, targetPos, b);
if (stepPos == null || stepPos.equals(nextPos)) {
// Can't move further
break;
}
nextPos = stepPos;
}
return nextPos;
}
// Override to ensure correct color
@Override
public Color getViewColor() {
return this.viewColor;
}
// Ensure the last positions are updated correctly
protected void updateLastPositions() {
if (lastThreePosition.size() >= 3) {
lastThreePosition.remove(0);
}
lastThreePosition.add(this.getPosition());
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
\ No newline at end of file
package model.firefighterscenario;
import java.util.List;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import util.Position;
import view.ViewElement;
public class Mountain implements Entity{
private final int priority = 0;
Position position;
private int age;
private final Color viewColor = Color.CHOCOLATE;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/fire/montagne.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Mountain(Position p ){
this.position = p;
}
public Mountain(Position p , int age){
this.position = p;
this.age = age;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
return List.of();
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.firefighterscenario;
import java.util.List;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import util.Position;
import view.ViewElement;
public class Rockery implements Entity{
private final int priority = 0;
Position position;
private int age;
private int burn;
private final Color viewColor = Color.LIMEGREEN;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/fire/rochers.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Rockery(Position p ){
this.position = p;
this.burn = 0;
}
public Rockery(Position p , int age){
System.out.println("age : " + age);
this.position = p;
this.age = age;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
return List.of();
}
@Override
public Position getPosition() {
return this.position;
}
public int getBurn(){
return this.burn;
}
public void incrementBurn(){
this.burn = burn + 1;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
public void resetBurn() {
this.burn = 0;
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.rockpapercisor;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import model.firefighterscenario.Cloud;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Cisor implements Entity {
private final int priority = 0;
Position position;
private int age;
private final Color viewColor = Color.RED;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/pfc/cis.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Cisor(Position p) {
this.position = p;
}
public Cisor(Position p, int age) {
this.position = p;
this.age = age;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
Position target = null;
target = board.getNearestEntity(position, Paper.class, null);
Position ennemy = null;
ennemy = board.getNearestEntity(position, Rock.class, null);
if(ennemy == null && target == null){
return List.of();
}
Position nextPos = null;
// Vérifier la proximité d'un ennemi avant de choisir la direction.
if (ennemy != null && PositionUtil.getManhattanDistance(position, ennemy) < 5) {
nextPos = PositionUtil.getNextPositionAwayFrom(position, ennemy, board);
} else if(target != null){
nextPos = PositionUtil.getNextPositionTowards(position, target, board);
}
if (nextPos != null && board.doesPositionExist(nextPos)) {
board.addEntityAtSquare(this, nextPos);
board.clearCaseFrom(this, position);
Position oldPosition = new Position(position.x(), position.y());
this.position = nextPos;
if (board.doesSquareContainEntity(nextPos, Paper.class)) {
List<Entity> entities = board.getStates(nextPos).getEntities();
entities.removeIf(p -> p instanceof Paper);
}
List<Position> result = new ArrayList<>();
if (target != null)
result.add(target);
if (oldPosition != null)
result.add(oldPosition);
if (position != null)
result.add(position);
if (ennemy != null)
result.add(ennemy);
return result;
}
return List.of();
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Cisor cisor = (Cisor) obj;
return age == cisor.age &&
Objects.equals(position, cisor.position);
}
@Override
public int hashCode() {
return Objects.hash(position, age);
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.rockpapercisor;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import model.firefighterscenario.Cloud;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Paper implements Entity {
private final int priority = 0;
Position position;
private int age;
private final Color viewColor = Color.GRAY;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/pfc/paper.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Paper(Position p) {
this.position = p;
}
public Paper(Position p, int age) {
this.position = p;
this.age = age;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
Position target = null;
target = board.getNearestEntity(position, Rock.class, null);
Position ennemy = null;
ennemy = board.getNearestEntity(position, Cisor.class, null);
if(ennemy == null && target == null){
return List.of();
}
Position nextPos = null;
// Vérifier la proximité d'un ennemi avant de choisir la direction.
if (ennemy != null && PositionUtil.getManhattanDistance(position, ennemy) < 5) {
nextPos = PositionUtil.getNextPositionAwayFrom(position, ennemy, board);
} else if(target != null){
nextPos = PositionUtil.getNextPositionTowards(position, target, board);
}
if (nextPos != null && board.doesPositionExist(nextPos)) {
board.addEntityAtSquare(this, nextPos);
board.clearCaseFrom(this, position);
Position oldPosition = new Position(position.x(), position.y());
this.position = nextPos;
if (board.doesSquareContainEntity(nextPos, Rock.class)) {
List<Entity> entities = board.getStates(nextPos).getEntities();
entities.removeIf(p -> p instanceof Rock);
}
List<Position> result = new ArrayList<>();
if (target != null)
result.add(target);
if (oldPosition != null)
result.add(oldPosition);
if (position != null)
result.add(position);
if (ennemy != null)
result.add(ennemy);
return result;
}
return List.of();
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
@Override
public ViewElement getViewElement() {
return new ViewElement(cloudImage);
}
}
package model.rockpapercisor;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import model.firefighterscenario.Cloud;
import util.Position;
import util.PositionUtil;
import view.ViewElement;
public class Rock implements Entity {
private final int priority = 0;
Position position;
private int age;
private final Color viewColor = Color.CHOCOLATE;
private static javafx.scene.image.Image cloudImage;
static {
try {
cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/pfc/rock.png").toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
}
public Rock(Position p) {
this.position = p;
}
public Rock(Position p, int age) {
this.position = p;
this.age = age;
}
@Override
public List<Position> nextTurn(Board<Square> board) {
Position target = null;
target = board.getNearestEntity(position, Cisor.class, null);
Position ennemy = null;
ennemy = board.getNearestEntity(position, Paper.class, null);
if(ennemy == null && target == null){
return List.of();
}
Position nextPos = null;
// Vérifier la proximité d'un ennemi avant de choisir la direction.
if (ennemy != null && PositionUtil.getManhattanDistance(position, ennemy) < 5) {
nextPos = PositionUtil.getNextPositionAwayFrom(position, ennemy, board);
} else if(target != null){
nextPos = PositionUtil.getNextPositionTowards(position, target, board);
}
if (nextPos != null && board.doesPositionExist(nextPos)) {
board.addEntityAtSquare(this, nextPos);
board.clearCaseFrom(this, position);
Position oldPosition = new Position(position.x(), position.y());
this.position = nextPos;
if (board.doesSquareContainEntity(nextPos, Cisor.class)) {
List<Entity> entities = board.getStates(nextPos).getEntities();
entities.removeIf(p -> p instanceof Cisor);
}
List<Position> result = new ArrayList<>();
if (target != null)
result.add(target);
if (oldPosition != null)
result.add(oldPosition);
if (position != null)
result.add(position);
if (ennemy != null)
result.add(ennemy);
return result;
}
return List.of();
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public void setPosition(Position p) {
this.position = p;
}
@Override
public int getAge() {
return this.age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void incrementAge() {
this.age += 1;
}
@Override
public Color getViewColor() {
return this.viewColor;
}
@Override
public int getPriority() {
return this.priority;
}
@Override
public ViewElement getViewElement(){
return new ViewElement(cloudImage);
}
}
package model.rockpapercisor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import model.Board;
import model.Entity;
import model.EntityFactory;
import model.Model;
import model.Scenario;
import model.Square;
import util.Position;
public class RockPaperCisorScenario extends Scenario implements Model{
public RockPaperCisorScenario(int columns, int rows, Map<EntityFactory, Integer> initialMap) {
super(columns, rows, initialMap);
}
public List<Position> updateToNextGeneration() {
ArrayList<Position> changedPositions = new ArrayList<>();
Iterator<Square> iterator = getMatrix().iterator();
while (iterator.hasNext()) {
Square s = iterator.next();
if (s.isEmpty())
continue;
if (s.getMaxAge() == 0) {
s.incrementAllAges();
continue;
}
if(s.getMaxAge()>stepNumber()+1){
continue;
}
List<Entity> entities = new ArrayList<>(s.getEntities());
for (Entity e : entities) {
e.incrementAge();
changedPositions.addAll(e.nextTurn(this));
}
}
// Increment the step counter
this.step = this.step + 1;
return changedPositions;
}
@Override
public Board<Square> getBoard() {
return this;
}
}
...@@ -2,6 +2,7 @@ module firefighter { ...@@ -2,6 +2,7 @@ module firefighter {
requires javafx.controls; requires javafx.controls;
requires javafx.fxml; requires javafx.fxml;
requires javafx.graphics; requires javafx.graphics;
requires java.sql;
opens controller to javafx.fxml; opens controller to javafx.fxml;
exports app; exports app;
opens app to javafx.fxml; opens app to javafx.fxml;
......
package util;
public enum Direction {
NORTH, EAST, WEST, SOUTH
}
package util;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
import model.Board;
import model.Square;
public class DirectionUtils {
/**
* Obtient l'incrément sur l'axe X pour une direction donnée.
*
* @param direction La direction.
* @return L'incrément sur l'axe X.
*/
public static int getXIncrement(Direction direction) {
switch (direction) {
case NORTH:
return -1;
case SOUTH:
return 1;
default:
return 0;
}
}
/**
* Obtient l'incrément sur l'axe Y pour une direction donnée.
*
* @param direction La direction.
* @return L'incrément sur l'axe Y.
*/
public static int getYIncrement(Direction direction) {
switch (direction) {
case EAST:
return 1;
case WEST:
return -1;
default:
return 0;
}
}
/**
* Obtient la direction opposée.
*
* @param direction La direction actuelle.
* @return La direction opposée.
*/
public static Direction getOpposite(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);
}
}
/**
* Choisit une direction aléatoire parmi toutes les directions disponibles.
*
* @param random Instance de Random.
* @return Une direction aléatoire.
*/
public static Direction getRandomDirection() {
Random r = new Random();
Direction[] directions = Direction.values();
return directions[r.nextInt(directions.length)];
}
/**
* Obtient les directions valides en fonction des exclusions et de la position actuelle.
*
* @param currentDirection La direction actuelle.
* @param permanentlyExcludedDirections Les directions définitivement exclues.
* @param temporarilyExcludedDirections Les directions temporairement exclues.
* @param board Le plateau de jeu.
* @param currentPosition La position actuelle.
* @return Une liste de directions valides.
*/
public static List<Direction> getValidDirections(
Direction currentDirection,
Set<Direction> permanentlyExcludedDirections,
Set<Direction> temporarilyExcludedDirections,
Board<Square> board,
Position currentPosition
) {
return Arrays.stream(Direction.values())
.filter(dir -> dir != currentDirection)
.filter(dir -> dir != getOpposite(currentDirection))
.filter(dir -> !permanentlyExcludedDirections.contains(dir))
.filter(dir -> !temporarilyExcludedDirections.contains(dir))
.filter(dir -> {
Position nextPos = currentPosition.move(dir);
return board.doesPositionExist(nextPos);
})
.collect(Collectors.toList());
}
}
package util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
import model.Square;
import model.doctorviruspatient.Patient;
import model.firefighterscenario.Fire;
import model.firefighterscenario.FireFighter;
public class Matrix<E> implements Iterable<E> {
private ArrayList<ArrayList<E>> matrix;
private final int rows;
private final int columns;
public Matrix(int rows, int columns) {
this.rows = rows;
this.columns = columns;
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);
}
this.matrix.add(row);
}
}
public E get(int x, int y) {
validateIndex(x, y);
return matrix.get(x).get(y);
}
public E set(int x, int y, E object) {
validateIndex(x, y);
return matrix.get(x).set(y, object);
}
public void 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);
}
this.matrix.add(row);
}
}
public int size() {
return rows * columns;
}
public int getColumns(){
return this.columns;
}
public int getRows(){
return this.rows;
}
public void displayMatrix() {
System.out.print(" ");
for (int j = 0; j < columns; j++) {
System.out.print("___ ");
}
System.out.println();
for (int i = 0; i < rows; i++) {
System.out.print("| ");
for (int j = 0; j < columns; j++) {
if (matrix.get(i).get(j) != null) {
Square s = (Square) matrix.get(i).get(j);
if(s.getEntities().stream().anyMatch(p -> p instanceof Fire)){
System.out.print(" F | ");
}
else if(s.getEntities().stream().anyMatch(p -> p instanceof FireFighter)){
System.out.print(" ff | ");
}
else if(s.getEntities().stream().anyMatch(p -> p instanceof Patient)){
System.out.print(" P | ");
}
else if(s.getEntities().stream().anyMatch(p -> p instanceof model.doctorviruspatient.Virus)){
System.out.print(" V | ");
}else{
System.out.print(" | ");
}
} else {
System.out.print(" | ");
}
}
System.out.println();
System.out.print(" ");
for (int j = 0; j < columns; j++) {
System.out.print("___ ");
}
System.out.println();
}
}
private void validateIndex(int x, int y) {
if (x < 0 || x >= rows || y < 0 || y >= columns) {
throw new IndexOutOfBoundsException("Indices x: "+ x + " y: " + y + " hors limites pour la matrice.");
}
}
public boolean validateIndex(Position position){
return position.x() >= 0 && position.x() < rows && position.y() >= 0 && position.y() < columns;
}
@Override
public Iterator<E> iterator() {
return new MatrixIterator();
}
private class MatrixIterator implements Iterator<E> {
private int row = 0;
private int col = 0;
@Override
public boolean hasNext() {
return row < rows && col < columns;
}
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
E element = matrix.get(row).get(col);
col++;
if (col >= columns) {
col = 0;
row++;
}
return element;
}
}
}