feat: ajout multiple fonction et factorisation

This commit is contained in:
2025-12-10 20:44:01 +01:00
parent 21640b312a
commit 82d360b1d9
6 changed files with 527 additions and 407 deletions

View File

@@ -1,88 +1,182 @@
import java.awt.Color;
import java.awt.Point;
import java.util.List;
import java.util.Random;
/**
* {@link Car} représente une voiture qui avance sur un circuit en boucles.
* Chaque appel à {@link #run()} avance la voiture d'une certaine position et fait perdre de l'essence.
* Chaque appel à {@link #run()} avance la voiture d'une certaine position et
* fait perdre de l'essence.
* Quand la position atteint la fin de la boucle, un nouveau tour est compté.
* <p>
* La voiture consomme du carburant à chaque déplacement, et son score
* est calculé en fonction du nombre de tours complétés et de sa progression sur le tour actuel.
* est calculé en fonction du nombre de tours complétés et de sa progression sur
* le tour actuel.
* </p>
*/
public class Car
{
public class Car {
/** Générateur de nombres aléatoires pour simuler la progression */
private final Random rand = new Random();
private static final Random RANDOM = new Random();
/** Couleur de la voiture pour l'affichage */
private Color color;
private final Color COLOR;
/** Nom de la voiture */
private final String name;
private final String NAME;
/** Position actuelle dans la boucle (entre 0 et loop) */
private int pos = 0;
/** Nombre de tours complétés */
private int round = 0;
/** Nombre de cases dans une boucle (doit être > 0) */
private final int loop;
/** Référence à l'état du jeu, pour récupérer les paramètres comme la consommation */
private final State state;
private final Map MAP;
/** Carburant restant */
private int fuel = 60;
/**
* Construit une nouvelle voiture.
*
* @param name nom de la voiture
* @param name nom de la voiture
* @param color couleur de la voiture
* @param loop nombre de positions par boucle (doit être > 0)
* @param state état global du jeu
* @param map
*/
public Car(String name, Color color, int loop, State state)
{
if (loop <= 0)
{
System.err.println("le tour de la piste doit etre positif");
System.exit(1);
public Car(String name, Color color, Map map) {
this.NAME = name;
this.COLOR = color;
this.MAP = map;
}
public static enum State {
/**
* L'état NORMAL du Vehicule avance selon un chiffre au alentour de 1 à 6 cases
* par tour. Il consomme 6 unités de carburant à chaque tour. Si l'on
* accelere, il passe à l'état BOOST. Si on Rallenti, il passe à l'état LOW.
*/
// @formatter:off
NORMAL(2, 1, 6) {
public State accelerate() { return BOOST; }
public State decelerate() { return LOW; }
},
/**
* L'état BOOST du Vehicule avance selon un chiffre au alentour de 5 à 10 cases
* par tour. Il consomme 5 unités de carburant à chaque tour. Si l'on
* accelere, il reste sur son état et indique un message sur le tableau de bord.
* Si on Rallenti, il passe à l'état LOW.
*/
BOOST(5, 5, 10) {
public State accelerate() { return this; }
public State decelerate() { return NORMAL; }
},
/**
* L'état LOW du Vehicule avance selon un chiffre au alentour de 1 à 3 cases
* par tour. Il consomme 1 unités de carburant à chaque tour. Si l'on
* accelere, il passe à l'état NORMAL. Si on Rallenti, il passe à l'état STOPPED.
*/
LOW(1, 1, 3) {
public State accelerate() { return NORMAL; }
public State decelerate() { return STOPPED; }
},
/**
* L'état STOPPED du Vehicule n'avance pas. Il consomme aucune unités de
* carburant à chaque tour. Si l'on
* accelere, il passe à l'état LOW. Si on Rallenti, il reste sur son état et
* indique un message sur le tableau de bord.
*/
STOPPED(0, 0, 0) {
public State accelerate() { return LOW; }
public State decelerate() { return this; }
@Override
public int move(int pos, int jump) { return pos; }
@Override
public int fuelConsumption(int fuel) { return fuel; }
},
/**
* L'état STOPPED du Vehicule n'avance pas. Il consomme aucune unités de
* carburant à chaque tour. Il reste immobile.
*/
DAMAGED(0, 0, 0) {
public State accelerate() { return this; }
public State decelerate() { return this; }
@Override
public int move(int pos, int jump) { return pos; }
@Override
public int fuelConsumption(int fuel) { return fuel; }
@Override
public boolean isDamaged() { return true; }
@Override
public State onDamageEnd() { return LOW; }
};
// @formatter:on
public final int FUELCOST;
public final int MAX;
public final int MIN;
private State(int fuelCost, int min, int max) {
this.FUELCOST = fuelCost;
this.MAX = max + 1;
this.MIN = min;
}
this.name = name;
this.color = color;
this.loop = loop;
this.state = state;
public List<Integer> getInterval() {
return List.of(MIN, MAX);
}
public int fuelConsumption(int fuel) {
return fuel - FUELCOST;
}
public int move(int pos, int jump) {
return pos + jump;
}
public boolean isDamaged() {
return false;
}
public State onDamageEnd() {
return this;
}
public abstract State accelerate();
public abstract State decelerate();
}
/**
* Fait avancer la voiture d'un certain nombre de positions.
* <p>
* Si la position atteint la fin de la boucle, le compteur de tours est incrémenté et
* la position revient à zéro.
* </p>
*
* @param move nombre de positions à avancer
* @return cette même instance (pour chaînage fluide)
* Référence à l'état du jeu, pour récupérer les paramètres comme la
* consommation
*/
public Car makeMove(int move)
{
pos += move;
if (pos >= loop)
{
round++;
pos %= loop;
private State state = State.NORMAL;
private int damageRound = 0;
public void setDamage() {
damageRound = 5;
state = State.DAMAGED;
}
private boolean decreaseDamage() {
if (state.isDamaged()) {
if (--damageRound <= 0) {
state = state.onDamageEnd();
}
return true;
}
return false;
}
public Car setState(State state) {
this.state = state;
return this;
}
/**
* @return la position actuelle dans la boucle
*/
public int getPosition()
{
public int getPosition() {
return pos;
}
@@ -90,62 +184,84 @@ public class Car
* @return le score de la voiture, calculé comme :
* (nombre de tours + progression du tour) × 100
*/
public int getScore()
{
return (int) ((round + (float) pos / loop) * 100);
public int getScore() {
return (int) ((round + (float) pos / MAP.getPathSize()) * 100);
}
/**
* @return le nombre de tours complétés
*/
public int getRound()
{
public int getRound() {
return round;
}
/**
* @return le nombre total de positions dans la boucle
*/
public int getLoop()
{
return loop;
}
/**
* @return le carburant restant
*/
public int getFuel()
{
public int getFuel() {
return fuel;
}
/**
* Fait avancer la voiture d'un certain nombre de positions.
* <p>
* Si la position atteint la fin de la boucle, le compteur de tours est
* incrémenté et
* la position revient à zéro.
* </p>
*
* @param move nombre de positions à avancer
* @return cette même instance (pour chaînage fluide)
*/
public void move() {
if (decreaseDamage()) {
System.out.println(NAME + " est en\taccident " + damageRound);
return;
}
int jump = RANDOM.nextInt(state.MIN, state.MAX);
for (int i = 0; i < jump; i++) {
pos = state.move(pos, 1);
Point point = MAP.getPath(pos);
Map.Circuit element = MAP.getElement(point.x, point.y);
if (element.isYRoad() && element.getValue() < jump) {
System.out.println(NAME + " a un\taccident");
setDamage();
return;
}
if (pos >= MAP.getPathSize()) {
pos = 0;
round++;
}
}
}
/**
* Consomme du carburant en fonction de l'état du jeu.
*
* @return cette même instance pour chaînage
*/
public Car consumeFuel()
{
fuel -= state.getConsumption();
if (fuel < 0) fuel = 0; // sécurité
return this;
public void consumeFuel() {
fuel = state.fuelConsumption(fuel);
if (fuel < 0)
fuel = 0; // sécurité
}
/**
* Exécute une "étape" de la voiture : avance d'une position aléatoire et consomme du carburant.
* Exécute une "étape" de la voiture : avance d'une position aléatoire et
* consomme du carburant.
* <p>
* La progression est déterminée par un intervalle aléatoire fourni par l'état du jeu.
* La progression est déterminée par un intervalle aléatoire fourni par l'état
* du jeu.
* </p>
*/
public void run()
{
if (fuel > 0)
{
int[] interval = state.getInterval();
// avance aléatoire en fonction de l'interval
int random = rand.nextInt(interval[0], interval[1]);
makeMove(random);
public void run() {
if (fuel > 0) {
move();
consumeFuel();
}
}
@@ -153,34 +269,21 @@ public class Car
/**
* @return la position actuelle (synonyme de getPosition)
*/
public int getPos()
{
public int getPos() {
return pos;
}
/**
* @return la couleur de la voiture
*/
public Color getColor()
{
return color;
}
/**
* Définit la couleur de la voiture
*
* @param color nouvelle couleur
*/
public void setColor(Color color)
{
this.color = color;
public Color getColor() {
return COLOR;
}
/**
* @return nom de la voiture
*/
public String getName()
{
return this.name;
public String getName() {
return NAME;
}
}