Skip to content
Snippets Groups Projects
Commit daf3602c authored by BACHTARZI Imed eddine's avatar BACHTARZI Imed eddine
Browse files

made test for some classes.

made the javaDoc for all interfaces and some classes.
modified the UML diagrams.
Final commit.
parent 65dbe78a
No related branches found
No related tags found
No related merge requests found
Showing
with 492 additions and 75 deletions
......@@ -10,25 +10,76 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Classe responsable du remplissage du plateau de jeu avec les éléments spécifiés.
* <p>
* Cette classe gère le placement des éléments du jeu sur le plateau en fonction du nombre d'éléments à placer
* (indiqué par le tableau {@code counter}). Chaque élément est instancié à une position aléatoire parmi les
* positions disponibles. Certains éléments, comme ceux de type {@link ConnexElement}, influencent les positions
* où d'autres éléments peuvent être placés.
* </p>
*/
public class FFboardFiller {
Random random=new Random();
/** Objet pour générer des positions aléatoires. */
private Random random = new Random();
/**
* Remplie le plateau de jeu avec les éléments spécifiés dans {@code counter}.
* <p>
* Cette méthode parcourt les éléments définis dans {@link ViewElement}, instancie chaque élément à une position
* aléatoire parmi les positions disponibles sur le plateau, et les place sur le plateau en utilisant la méthode
* {@link BoardData#addElement(Element)}.
* </p>
* <p>
* Le tableau {@code counter} spécifie le nombre d'éléments de chaque type à placer. Après chaque placement,
* le compteur correspondant est décrémenté.
* </p>
*
* @param boardData L'état actuel du plateau de jeu utilisé pour ajouter les éléments.
* @param counter Tableau représentant le nombre d'éléments à placer pour chaque type d'élément (indexé par {@link ViewElement#ordinal()} ou :
* //roads
* //forests
* //rocks
* //mountains
* //firefighter
* //motorized firefighter
* //motorized firefighter (AKA superman)
* //clouds
* //fires
*/
public void fillBoard(BoardData boardData, int[] counter) {
List<Position> positions = new ArrayList<>(List.copyOf(boardData.getNeighbors().keySet()));
// Parcours de chaque élément possible dans l'énumération ViewElement
for (ViewElement ve : ViewElement.values()) {
if (ve!=ViewElement.EMPTY)
// On ne place pas d'élément de type EMPTY
if (ve != ViewElement.EMPTY) {
// Tant qu'il y a des éléments à placer pour ce type
while (counter[ve.ordinal()] > 0) {
Element element;
Position p;
do {
// Choisit une position aléatoire parmi les positions disponibles
p = positions.get(random.nextInt(positions.size()));
// Crée l'élément correspondant à la position choisie
element = ve.instanciate(boardData, p);
}while (!boardData.addElement(element));
} while (!boardData.addElement(element)); // Réessaye si la position est invalide
// Si l'élément est un ConnexElement, retire les positions occupées par ses voisins
if (element instanceof ConnexElement) {
positions.removeAll(boardData.getElements().get(element.getType().ordinal()).stream().map(x ->x.getPosition()).toList());
positions.removeAll(boardData.getElements().get(element.getType().ordinal()).stream()
.map(x -> x.getPosition())
.toList());
}
// Retire la position utilisée
positions.remove(p);
// Décrémente le compteur pour ce type d'élément
counter[ve.ordinal()]--;
}
}
}
}
}
......@@ -9,59 +9,118 @@ import util.Position;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
/**
* Enumération représentant les différents types d'éléments du modèle dans un jeu de lutte contre les incendies.
* Chaque valeur de l'énumération correspond à un type d'élément spécifique du jeu, comme un feu, un pompier,
* une forêt, ou une montagne. L'énumération contient des méthodes pour vérifier si un élément est imprimable ou
* mise à jour, ainsi qu'une méthode pour instancier l'élément correspondant à partir de sa position.
*/
public enum ModelElement {
/** Représente un feu standard. */
FIRE(StandardFire.class),
/** Représente un feu rapide. */
SLOWFIRE(QuickFire.class),
/** Représente un pompier standard. */
FIREFIGHTER(StandardFireFighter.class),
/** Représente un pompier motorisé. */
MOTORIZEDFIREFIGHTER(MotorizedFireFighter.class),
/** Représente un pompier industriel. */
INDUSTRIALFIREFIGHTER(IndustrialFireFighter.class),
/** Représente un nuage. */
CLOUD(Cloud.class),
/** Représente une montagne. */
MOUNTAIN(Mountain.class),
/** Représente une route. */
ROAD(Road.class),
/** Représente une forêt. */
FOREST(Forest.class),
ROCK(Rock.class);
/** Représente un rocher. */
ROCK(Rock.class);
/** La classe associée à l'élément du modèle. */
public final Class<?> c;
/**
* Constructeur pour associer une classe spécifique à chaque type d'élément du modèle.
*
* @param c La classe de l'élément correspondant.
*/
ModelElement(Class<?> c) {
this.c = c;
}
/**
* Vérifie si l'élément du modèle peut être mis à jour.
*
* @return {@code true} si l'élément est de type {@link Updatable}, sinon {@code false}.
*/
public boolean isUpdatable() {
Class<?> currentClass = c;
while (!currentClass.equals(Object.class)) {
if (Arrays.asList(currentClass.getInterfaces()).contains(Updatable.class)) return true;
if (Arrays.asList(currentClass.getInterfaces()).contains(Updatable.class)) {
return true;
}
currentClass = currentClass.getSuperclass();
}
return false;
}
/**
* Vérifie si l'élément du modèle peut être imprimé.
*
* @return {@code true} si l'élément est de type {@link Printable}, sinon {@code false}.
*/
public boolean isPrintable() {
Class<?> currentClass = c;
while (!currentClass.equals(Object.class)) {
if (Arrays.asList(currentClass.getInterfaces()).contains(Printable.class)) return true;
if (Arrays.asList(currentClass.getInterfaces()).contains(Printable.class)) {
return true;
}
currentClass = currentClass.getSuperclass();
}
return false;
}
/**
* Vérifie si l'élément du modèle est une instance de la classe spécifiée.
*
* @param classe La classe à comparer.
* @return {@code true} si l'élément est une instance de la classe spécifiée, sinon {@code false}.
*/
public boolean isInstanceOf(Class<?> classe) {
Class<?> currentClass = c;
while (!currentClass.equals(Object.class)) {
if (currentClass.equals(classe)) return true;
if (currentClass.equals(classe)) {
return true;
}
currentClass = currentClass.getSuperclass();
}
return false;
}
/**
* Instancie un nouvel élément à partir de la classe associée et de la position spécifiée.
*
* @param position La position de l'élément à instancier sur le plateau.
* @return Une nouvelle instance de l'élément correspondant à ce modèle, positionnée à l'emplacement donné.
* @throws RuntimeException Si une erreur se produit lors de la création de l'élément.
*/
public Element instanciate(Position position) {
Class<?>[] cs = new Class<?>[] { Position.class };
Element e = null;
try {
e = (Element) c.getDeclaredConstructor(cs).newInstance(position);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
} catch (NoSuchMethodException ex) {
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
return e;
......
......@@ -19,7 +19,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class IndustrialFireFighterBehavior extends FireFighterBehavior implements TangibleBehavior<ModelElement>, RemoverBehavior<ModelElement>, ChargerBehavior<ModelElement> {
public class IndustrialFireFighterBehavior extends FireFighterBehavior {
private TargetStrategy ts=new TargetStrategy();
......
......@@ -19,7 +19,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NormalFireFighterBehavior extends FireFighterBehavior implements TangibleBehavior<ModelElement>, RemoverBehavior<ModelElement>, ChargerBehavior<ModelElement> {
public class NormalFireFighterBehavior extends FireFighterBehavior {
private TargetStrategy ts=new TargetStrategy();
......
......@@ -4,7 +4,7 @@ import model.Element;
import model.firefighter.ModelElement;
import util.Position;
public class Forest extends Land implements Element {
public class Forest extends Land {
//explanation : while reading the subject, I thought that any FIRE that was ON a ROCK took 4 turns instead of 2 (i changed slowfire into quickfire (1 turn) and did the forest);
public Forest(Position position) {
super(position);
......
......@@ -4,7 +4,7 @@ import model.Element;
import model.firefighter.ModelElement;
import util.Position;
public class Mountain extends Land implements Element {
public class Mountain extends Land {
public Mountain(Position position) {
super(position);
type= ModelElement.MOUNTAIN;
......
......@@ -4,7 +4,7 @@ import model.elementTokens.Updatable;
import model.firefighter.ModelElement;
import util.Position;
public class QuickFire extends Fire implements Updatable {
public class QuickFire extends Fire {
public QuickFire(Position position) {
super(1, ModelElement.SLOWFIRE, position);
}
......
......@@ -7,7 +7,7 @@ import model.firefighter.ModelElement;
import model.firefighter.factories.RoadFactory;
import util.Position;
public class Road extends Land implements Element, ConnexElement {
public class Road extends Land implements ConnexElement {
public static ElementFactory factory=new RoadFactory();
public Road(Position position) {
super(position);
......
......@@ -5,7 +5,27 @@ import model.elementTokens.ChargeTarget;
import java.util.List;
/**
* Interface representing the behavior of an element that can charge other elements.
* This interface extends the {@link Behavior} interface and defines methods for handling
* chargeable targets and determining their charge state.
*
* @param <E> The type of element that can be charged.
*/
public interface ChargerBehavior<E> extends Behavior {
/**
* Get the list of charge targets for the current charger.
*
* @return A list of chargeable elements that this element can charge.
*/
public List<E> getChargeTarget();
/**
* Check if the given charge target is fully charged.
*
* @param chargeTarget The charge target to check.
* @return {@code true} if the charge target is fully charged, {@code false} otherwise.
*/
public Boolean isCharged(ChargeTarget chargeTarget);
}
......@@ -6,7 +6,20 @@ import util.Position;
import java.util.List;
/**
* Interface representing the behavior of an element that can remove or extinguish other elements.
* This interface extends the {@link Behavior} interface and defines a method for removing elements
* from the board based on their position.
*
* @param <E> The type of element that can be removed or extinguished.
*/
public interface RemoverBehavior<E> extends Behavior {
public void extinguish(BoardData boardData, Position position);
/**
* Remove or extinguish the element located at the given position on the board.
*
* @param boardData The current state of the board.
* @param position The position of the element to be removed.
*/
public void extinguish(BoardData boardData, Position position);
}
......@@ -6,7 +6,28 @@ import util.Position;
import java.util.List;
/**
* Interface representing the behavior of an element that interacts with tangible objects on the board.
* This interface extends the {@link Behavior} interface and defines methods for retrieving obstacles
* and checking the legality of a given position on the board.
*
* @param <E> The type of element that can interact with tangible objects.
*/
public interface TangibleBehavior<E> extends Behavior {
/**
* Get the list of obstacles that this element interacts with.
*
* @return A list of obstacles (elements) that can block or affect the movement of this element.
*/
public List<E> getObstacles();
/**
* Check if the given position is legal for the element to occupy.
*
* @param boardData The current state of the board.
* @param position The position to check for legality.
* @return {@code true} if the position is legal (e.g., not blocked by obstacles), {@code false} otherwise.
*/
public Boolean isLegal(BoardData boardData, Position position);
}
......@@ -7,7 +7,16 @@ import util.Position;
import java.lang.reflect.InvocationTargetException;
/**
* Enumération représentant les éléments visibles sur le plateau de jeu.
* <p>
* Cette énumération associe une couleur et une classe d'élément (ou une fabrique d'éléments) à chaque type d'élément
* qui peut être affiché dans la vue. Elle permet de gérer la création d'éléments visibles ainsi que leurs
* représentations graphiques.
* </p>
*/
public enum ViewElement {
ROAD(Color.BLACK, Road.class, Road.factory),
FOREST(Color.color(0.0, 0.2, 0.0), Forest.class),
ROCK(Color.GREEN, Rock.class),
......@@ -17,37 +26,63 @@ public enum ViewElement {
INDUSTRIALFIREFIGHTER(Color.DARKBLUE, IndustrialFireFighter.class),
CLOUD(Color.gray(0.8), Cloud.class),
FIRE(Color.RED, Fire.class, Fire.factory),
EMPTY(Color.WHITE, null);
/** La couleur associée à l'élément. */
final Color color;
/** La classe Java de l'élément associé. */
public final Class<?> c;
/** La fabrique d'éléments associée à l'élément (si présente). */
final ElementFactory elementFactory;
/**
* Constructeur pour l'élément sans fabrique spécifique.
*
* @param color La couleur associée à l'élément.
* @param c La classe de l'élément.
*/
ViewElement(Color color, Class<?> c) {
this.color = color;
this.c = c;
this.elementFactory = null;
}
/**
* Constructeur pour l'élément avec une fabrique spécifique.
*
* @param color La couleur associée à l'élément.
* @param c La classe de l'élément.
* @param elementFactory La fabrique utilisée pour créer des éléments.
*/
ViewElement(Color color, Class<?> c, ElementFactory elementFactory) {
this.color = color;
this.c = c;
this.elementFactory = elementFactory;
}
/**
* Instancie un élément à la position spécifiée sur le plateau de jeu.
* <p>
* Si l'élément a une fabrique associée, la fabrique est utilisée pour créer l'élément.
* Sinon, la classe de l'élément est instanciée directement avec la position.
* </p>
*
* @param boardData Les données du plateau de jeu.
* @param position La position de l'élément sur le plateau.
* @return L'élément créé.
* @throws RuntimeException si une erreur se produit lors de la création de l'élément.
*/
public Element instanciate(BoardData boardData, Position position) {
Element element;
Class<?>[] arg1 = new Class[]{Position.class};
if (elementFactory != null) {
element = elementFactory.getNewElement(boardData, position);
}
else {
} else {
try {
element = (Element) this.c.getDeclaredConstructor(arg1).newInstance(position);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
......
package model;
import model.elementTokens.Updatable;
import model.firefighter.FFBoardData;
import model.firefighter.ModelElement;
import model.firefighter.elements.QuickFire;
import model.firefighter.elements.Rock;
import model.firefighter.elements.StandardFire;
import org.junit.jupiter.api.Test;
import util.Position;
import static org.assertj.core.api.Assertions.assertThat;
public class ChargerBehaviorTest {
@Test
void testChargerBehaviorForOneFire(){
Position p1 = new Position(0,0);
Position p2 = new Position(0,1);
Position p3 = new Position(0,2);
BoardData b1 = new FFBoardData(2,1);
Element r= new Rock(p2);
b1.addElement(r);
Element f= new StandardFire(p1);
b1.addElement(f);
//we have a fire and a rock in a 2x1 board;
//we need 4 hits so 8 turns
for (int i = 0; i < 8; i++) {
assertThat(b1.getElements().get(f.getType().ordinal()).size()==1).isEqualTo(true);
((Updatable)f).updateSelf(b1);
((Updatable)r).updateSelf(b1);
}
assertThat(b1.getElements().get(f.getType().ordinal()).size()==2).isEqualTo(true);
}
@Test
void testChargerBehaviorForOneQuickFire(){
Position p1 = new Position(0,0);
Position p2 = new Position(0,1);
Position p3 = new Position(0,2);
BoardData b1 = new FFBoardData(2,1);
Element r= new Rock(p2);
b1.addElement(r);
Element f= new QuickFire(p1);
b1.addElement(f);
//we have a fire and a rock in a 2x1 board;
//we need 4 hits so 4 turns with QuickFire
for (int i = 0; i < 4; i++) {
assertThat(b1.getElements().get(ModelElement.FIRE.ordinal()).isEmpty()).isEqualTo(true);
assertThat(b1.getElements().get(ModelElement.SLOWFIRE.ordinal()).size()==1).isEqualTo(true);
((Updatable)f).updateSelf(b1);
((Updatable)r).updateSelf(b1);
}
assertThat(b1.getElements().get(ModelElement.FIRE.ordinal()).size()==1).isEqualTo(true);
assertThat(b1.getElements().get(ModelElement.SLOWFIRE.ordinal()).size()==1).isEqualTo(true);
}
@Test
void testChargerBehaviorForTwoFires(){
Position p1 = new Position(0,0);
Position p2 = new Position(0,1);
Position p3 = new Position(0,2);
BoardData b1 = new FFBoardData(3,1);
Element f1= new StandardFire(p1);
b1.addElement(f1);
Element r= new Rock(p2);
b1.addElement(r);
Element f3= new StandardFire(p3);
b1.addElement(f3);
//we have a fire , a rock and then another fire in a 3x1 board;
//we need 4 hits so 4 turns with QuickFire
for (int i = 0; i < 4; i++) {
assertThat(b1.getElements().get(ModelElement.FIRE.ordinal()).size()==2).isEqualTo(true);
((Updatable)f1).updateSelf(b1);
((Updatable)f3).updateSelf(b1);
((Updatable)r).updateSelf(b1);
}
assertThat(b1.getElements().get(ModelElement.FIRE.ordinal()).size()==3).isEqualTo(true);
}
}
package model;
import model.firefighter.FFBoardData;
import model.firefighter.elements.StandardFire;
import org.junit.jupiter.api.Test;
import util.Position;
import view.ViewElement;
import java.util.Random;
import static org.assertj.core.api.Assertions.assertThat;
public class FFBoardDataTest {
@Test
void testAddANDRemove(){
Random r=new Random();
Position p;
p = new Position(r.nextInt(5),r.nextInt(5));
BoardData boardData = new FFBoardData(5,5);
Element e = new StandardFire(p);
boardData.addElement(e);
assertThat(boardData.getCell(p).Content.contains(e)).isEqualTo(true);
assertThat(boardData.getElements().get(e.getType().ordinal()).contains(e)).isEqualTo(true);
boardData.removeElement(e);
assertThat(boardData.getCell(p).Content.contains(e)).isEqualTo(false);
assertThat(boardData.getElements().get(e.getType().ordinal()).contains(e)).isEqualTo(false);
assertThat(e.getPosition()).isEqualTo(p);
}
}
package model;
import model.firefighter.FFBoardData;
import model.firefighter.elements.*;
import org.junit.jupiter.api.Test;
import util.Position;
import java.util.Random;
import static org.assertj.core.api.Assertions.assertThat;
public class FireFactoryTest {
@Test
void testFactoryReturns(){
Position p1 = new Position(0,0);
Position p2 = new Position(0,1);
BoardData boardData = new FFBoardData(2,1);
boardData.addElement(new Forest(p2));
Fire f1= (Fire) Fire.factory.getNewElement(boardData,p1);
Fire f2= (Fire) Fire.factory.getNewElement(boardData,p2);
boardData.addElement(f1);
boardData.addElement(f2);
assertThat(f1 instanceof StandardFire).isEqualTo(true);
assertThat(f2 instanceof QuickFire).isEqualTo(true);
}
}
package model;
import model.firefighter.FFBoard;
import model.firefighter.ModelElement;
import org.junit.jupiter.api.Test;
import util.Position;
import java.util.List;
import java.util.Random;
import static org.assertj.core.api.Assertions.assertThat;
public class ModelElementTest {
@Test
void testInstanciate(){
Random r=new Random();
Position p;
for (ModelElement me:ModelElement.values()) {
p=new Position(r.nextInt(),r.nextInt());
Element e=me.instanciate(p);
assertThat(e.getType()).isEqualTo(me);
assertThat(e.getClass()).isEqualTo(me.c);
assertThat(e.getPosition()).isEqualTo(p);
}
}
}
package model;
import model.elementTokens.Updatable;
import model.firefighter.FFBoardData;
import model.firefighter.elements.*;
import org.junit.jupiter.api.Test;
import util.Position;
import static org.assertj.core.api.Assertions.assertThat;
public class TangibleBehaviorTest {
@Test
void testTangibleBehavior(){
Position p1 = new Position(0,0);
Position p2 = new Position(0,1);
BoardData b1 = new FFBoardData(2,1);
b1.addElement(new Mountain(p2));
Element f= new StandardFire(p1);
b1.addElement(f);
//we have a fire and a mountain in a 2x1 board;
assertThat(f.getBehavior().legalNeighbors(b1, f.getPosition()).isEmpty()).isEqualTo(true);
assertThat(b1.getElements().get(f.getType().ordinal()).size()==1).isEqualTo(true);
((Updatable)f).updateSelf(b1);
((Updatable)f).updateSelf(b1);
assertThat(b1.getElements().get(f.getType().ordinal()).size()==1).isEqualTo(true);
}
}
package view;
import model.BoardData;
import model.Element;
import model.firefighter.FFBoardData;
import model.firefighter.ModelElement;
import org.junit.jupiter.api.Test;
import util.Position;
import view.ViewElement;
import java.util.Random;
import static org.assertj.core.api.Assertions.assertThat;
public class ViewElementTest {
@Test
void testInstanciate(){
Random r=new Random();
Position p;
for (ViewElement ve:ViewElement.values()) {
if (ve!=ViewElement.EMPTY) {
p = new Position(0, ve.ordinal());
BoardData boardData = new FFBoardData(ViewElement.values().length, 1);
Element e = ve.instanciate(boardData, p);
assertThat(e.getType().isInstanceOf(ve.c)).isEqualTo(true);
assertThat(e.getPosition()).isEqualTo(p);
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment