Skip to content
Snippets Groups Projects
Commit d87cdf72 authored by Yanis O's avatar Yanis O
Browse files

[Ajout] Scenario du Pierre Feuille Ciseaux

parent 303a6525
No related branches found
No related tags found
No related merge requests found
Pipeline #40655 failed
Showing
with 568 additions and 78 deletions
......@@ -23,12 +23,9 @@ import model.Board;
import model.EntityFactory;
import model.Model;
import model.Square;
import model.firefighterscenario.Cloud;
import model.firefighterscenario.Fire;
import model.firefighterscenario.FireFighter;
import model.firefighterscenario.MotorizedFireFighter;
import model.firefighterscenario.Mountain;
import model.firefighterscenario.Rockery;
import model.rockpapercisor.Cisor;
import model.rockpapercisor.Paper;
import model.rockpapercisor.Rock;
import model.rockpapercisor.RockPaperCisorScenario;
import util.Position;
import view.Grid;
......@@ -133,13 +130,17 @@ public class Controller {
grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight);
Map<EntityFactory, Integer> entityCounts = new HashMap<EntityFactory, Integer>();
/*
entityCounts.put((pos, b) -> new Fire(pos), initialFireCount);
entityCounts.put((pos, b) -> new FireFighter(pos,b), initialFirefighterCount);
entityCounts.put((pos, b) -> new MotorizedFireFighter(pos, b), initialMotorizedFirefightersCount);
entityCounts.put((pos, b) -> new Cloud(pos, b), initialcloudCount);
entityCounts.put((pos, b) -> new Mountain(pos), initialmountaincount);
entityCounts.put((pos, b) -> new Rockery(pos), 3);
*/
entityCounts.put((pos, b) -> new Rock(pos), 100);
entityCounts.put((pos, b) -> new Cisor(pos), 100);
entityCounts.put((pos, b) -> new Paper(pos), 100);
Model model = new RockPaperCisorScenario(columnCount, rowCount, entityCounts);
this.setModel(model);
repaintGrid();
......
......@@ -63,7 +63,7 @@ public interface Board<S> {
public void clearCaseFrom(Entity entity, Position position);
public Position getNearestEntity(Position fromPos, Class<?> entityType);
public Position getNearestEntity(Position fromPos, Class<?> entityType) throws EntityNotFoundException;
public boolean doesSquareContainEntity(Position squarePos, Class<?> entityType);
......
package model;
class EntityNotFoundException extends Exception {
public EntityNotFoundException(String message) {
super(message);
}
}
\ No newline at end of file
......@@ -3,15 +3,9 @@ package model;
import java.util.List;
import java.util.Map;
import java.util.Random;
import app.SimulatorApplication;
import model.firefighterscenario.Fire;
import model.firefighterscenario.Mountain;
import model.firefighterscenario.Road;
import model.firefighterscenario.Rockery;
import util.Matrix;
import util.PathGenerator;
import util.Position;
import util.PositionUtil;
......@@ -46,7 +40,6 @@ public class Scenario implements Board<Square>{
public void placeInitialEntities(Map<EntityFactory, Integer> initialMap) {
EntitySpawner spawner = new EntitySpawner(this);
spawner.spawnEntities(initialMap);
generateRoads();
}
......@@ -95,10 +88,9 @@ public class Scenario implements Board<Square>{
matrix.get(position.x(), position.y()).getEntities().removeIf(element -> element.equals(entity));
}
public Position getNearestEntity(Position fromPos, Class<?> entityType) {
public Position getNearestEntity(Position fromPos, Class<?> entityType) throws EntityNotFoundException {
int rows = matrix.getRows();
int cols = matrix.getColumns();
Position nearestPosition = fromPos;
// Définir la distance maximale possible
int maxDistance = rows + cols;
......@@ -110,17 +102,18 @@ public class Scenario implements Board<Square>{
Square currentSquare = matrix.get(currentPos.x(), currentPos.y());
for (Entity currentEntity : currentSquare.getEntities()) {
if (entityType.isInstance(currentEntity)) {
// Dès qu'une entité est trouvée à cette distance, elle est la plus proche
// possible
// Dès qu'une entité est trouvée à cette distance, elle est la plus proche possible
return currentPos;
}
}
}
}
return nearestPosition; // Retourne null si aucune entité n'est trouvée
// Lever une exception si aucune entité n'est trouvée
throw new EntityNotFoundException("Aucune entité de type " + entityType.getSimpleName() + " trouvée à proximité de " + fromPos);
}
public void reset() {
step = 0;
matrix.clear();
......@@ -163,45 +156,4 @@ public class Scenario implements Board<Square>{
return true;
}
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);
}
}
}
......@@ -107,7 +107,12 @@ public class FireFighter implements Entity {
List<Position> positions = new ArrayList<>();
// Find the nearest fire
Position nearestFirePos = b.getNearestEntity(position, Fire.class);
Position nearestFirePos;
try {
nearestFirePos = b.getNearestEntity(position, Fire.class);
} catch (Exception e) {
return List.of();
}
if (nearestFirePos != null) {
// Get the next position towards the fire
Position nextPos = getNextPositionTowards(position, nearestFirePos, b);
......
......@@ -24,9 +24,12 @@ public class FireFighterScenario extends Scenario implements Model{
public List<Position> updateToNextGeneration() {
ArrayList<Position> changedPositions = new ArrayList<>();
Iterator<Square> iterator = getMatrix().iterator();
List<Entity> updatedEntities = new ArrayList<Entity>();
int i = 0;
while (iterator.hasNext()) {
Square s = iterator.next();
System.out.println("i : " + i);
i++;
if (s.isEmpty())
continue;
if (s.getMaxAge() == 0) {
......@@ -38,10 +41,12 @@ public class FireFighterScenario extends Scenario implements Model{
}
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));
}
}
......
......@@ -54,7 +54,12 @@ public class MotorizedFireFighter extends FireFighter {
List<Position> positions = new ArrayList<>();
// Find the nearest fire
Position nearestFirePos = b.getNearestEntity(getPosition(), Fire.class);
Position nearestFirePos;
try {
nearestFirePos = b.getNearestEntity(getPosition(), Fire.class);
} 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);
......
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 util.Position;
import util.PositionUtil;
public class Cisor implements Entity {
private final int priority = 0;
Position position;
private int age;
private final Color viewColor = Color.RED;
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;
try {
target = board.getNearestEntity(position, Paper.class);
} catch (Exception e) {
}
Position ennemy = null;
try {
ennemy = board.getNearestEntity(position, Rock.class);
} catch (Exception ignored) {
// Si aucune entité Rock n'est trouvée, ennemy reste null.
}
if(ennemy == null && target == null){
System.err.println("all 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);
}
}
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 util.Position;
import util.PositionUtil;
public class Paper implements Entity {
private final int priority = 0;
Position position;
private int age;
private final Color viewColor = Color.GRAY;
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;
try {
target = board.getNearestEntity(position, Rock.class);
} catch (Exception e) {
}
Position ennemy = null;
try {
ennemy = board.getNearestEntity(position, Cisor.class);
} catch (Exception ignored) {
// Si aucune entité Cisor n'est trouvée, ennemy reste null.
}
if(ennemy == null && target == null){
System.err.println("all 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;
}
}
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 util.Position;
import util.PositionUtil;
public class Rock implements Entity {
private final int priority = 0;
Position position;
private int age;
private final Color viewColor = Color.CHOCOLATE;
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;
try {
target = board.getNearestEntity(position, Cisor.class);
} catch (Exception e) {
}
Position ennemy = null;
try {
ennemy = board.getNearestEntity(position, Paper.class);
} catch (Exception ignored) {
// Si aucune entité Paper n'est trouvée, ennemy reste null.
}
if(ennemy == null && target == null){
System.err.println("all 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;
}
}
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;
......@@ -16,7 +19,30 @@ public class RockPaperCisorScenario extends Scenario implements Model{
}
public List<Position> updateToNextGeneration() {
return List.of();
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;
System.out.println("-----------");
return changedPositions;
}
@Override
......
package model.rockpapercisor;
package model.virus;
import java.util.List;
......
......@@ -2,11 +2,14 @@ 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 {
/**
......@@ -153,4 +156,128 @@ public class PositionUtil {
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;
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment