feat: ajout impl Car et rework State et Game

This commit is contained in:
2025-11-05 20:23:57 +01:00
parent 5121e25e46
commit d2847745ba
6 changed files with 149 additions and 137 deletions

View File

@@ -1,9 +1,14 @@
import java.util.Random;
/**
* <code>Car</code> représente une voiture qui avance sur un circuit en boucles.
* Chaque appel à {@link #makeMove()} avance la voiture d'une position.
* Quand la position atteint la fin de la boucle, un nouveau tour est compté.
*/
public class Car {
public class Car implements GObserver
{
/** Ajout de la classe Random (Evite de le recreer a chaque fois) */
private Random rand = new Random();
/** Position actuelle dans la boucle (entre 0 et loop inclus) */
private int pos = 0;
@@ -13,6 +18,7 @@ public class Car {
/** Nombre total de cases dans une boucle (doit être > 0) */
private final int loop;
private final State state;
/** Nombre de fuel restant */
private int fuel = 60;
@@ -22,8 +28,10 @@ public class Car {
* @param loop nombre de positions par boucle (doit être > 0)
* @throws IllegalArgumentException si {@code loop <= 0}
*/
public Car(int loop)
public Car(int loop, State state)
{
this.state = state;
if (loop <= 0)
throw new IllegalArgumentException("loop must be > 0!");
this.loop = loop;
@@ -85,7 +93,20 @@ public class Car {
public Car consumeFuel()
{
fuel -= State.get().getConsumption();
fuel -= state.getConsumption();
return this;
}
@Override
public boolean apply()
{
if (this.fuel > 0)
{
int[] interval = state.getInterval();
int random = rand.nextInt(interval[0], interval[1]);
makeMove(random).consumeFuel();
}
return true;
}
}

View File

@@ -1,20 +0,0 @@
public class GFactory
{
public static Game defaultInit()
{
Integer[][] map = new Integer[][] {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 5, 0 },
{ 0, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, -1, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 2, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
{ 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -3, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
return Game.getInstance().init(3, Map.fromInts(map));
}
}

13
src/GObserver.java Normal file
View File

@@ -0,0 +1,13 @@
@FunctionalInterface
/**
* L'interface utilisée pour Game.
*/
public interface GObserver
{
/**
*
* @return true si la fonction s'est bien passé sinon false (le programme va se
* stopper)
*/
public boolean apply();
}

View File

@@ -1,73 +1,79 @@
import java.util.ArrayList;
import java.util.Random;
public class Game
{
@FunctionalInterface
private static interface GameObserver
{
/**
*
* @return true si la fonction s'est bien passé sinon false (le programme va se stopper)
*/
public boolean apply();
}
private static Game game;
private boolean paused;
private Car[] cars;
private Map map;
private ArrayList<GameObserver> obs = new ArrayList<>();
private Random random = new Random();
private boolean paused = false;
public static Game getInstance()
public static class Builder
{
if (game == null) game = new Game();
return game;
}
private int pnumber = 3;
private Map map = null;
private State state = new State();
private Game() {}
public Game init(int playerNumber, Map map)
public Builder setPlayers(int pnumber)
{
this.cars = new Car[playerNumber];
this.map = map;
// combien de route avant loop
int loop = this.map.getPathSize();
for (int i = 0; i < cars.length; i++)
{
final Car CAR = new Car(loop);
final int I = i;
cars[i] = CAR;
// Observer pour avancer
obs.add(() -> {
if (CAR.getFuel() > 0)
{
int[] interval = State.get().getInterval();
int rand = random.nextInt(interval[0], interval[1]);
CAR.makeMove(rand).consumeFuel();
System.out.println("car " + I + " score: " + CAR.getScore() + " random: " + rand);
}
return true;
});
}
this.pnumber = pnumber;
return this;
}
public void addObserver(GameObserver game)
public Builder setMap(Map map)
{
obs.add(game);
this.map = map;
return this;
}
public void removeObserver(GameObserver game)
public Builder setState(State s)
{
obs.remove(game);
this.state = s;
return this;
}
public Builder defaultMap()
{
Integer[][] map = new Integer[][]
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 5, 0 },
{ 0, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, -1, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 2, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
{ 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -3, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
this.map = Map.fromInts(map);
return this;
}
public Game build()
{
if (map == null) defaultMap();
return new Game(pnumber, map, state);
}
}
private ArrayList<GObserver> obs;
public Game(int pnumber, Map map, State state)
{
int loop = map.getPathSize();
this.map = map;
cars = new Car[pnumber];
obs = new ArrayList<>();
for (int i = 0; i < pnumber; i++)
{
Car car = new Car(loop, state);
cars[i] = car;
// Observer pour avancer
obs.add(car);
}
}
private boolean isFinish()
@@ -80,9 +86,16 @@ public class Game
return false;
}
public synchronized boolean togglePause()
{
if (paused) notifyAll();
paused = !paused;
return paused;
}
private void step() throws InterruptedException
{
for (GameObserver o : obs)
for (GObserver o : obs)
{
synchronized (this)
{
@@ -91,7 +104,7 @@ public class Game
{
wait();
}
}
boolean isSuccess = o.apply();
if (!isSuccess)
{
@@ -101,27 +114,8 @@ public class Game
}
}
}
public synchronized boolean togglePause()
{
if (paused)
{
notifyAll();
paused = false;
}
else paused = true;
return paused;
}
public void run()
{
if (this.cars == null || this.map == null)
{
System.out.println("Lancement du init par défaut.");
GFactory.defaultInit();
}
while (!isFinish())
{
try

View File

@@ -6,6 +6,11 @@ public class Main {
{'9', '#', 'F'},
});
Game game = new Game.Builder()
.setMap(m)
.setPlayers(3)
.build();
Thread t = new Thread(() -> {
int i = 0;
while (i++ < 10)
@@ -18,12 +23,11 @@ public class Main {
{
e.printStackTrace();
}
System.out.println(Game.getInstance().togglePause() ? "stop" : "fini" );
System.out.println(game.togglePause() ? "stop" : "fini" );
}
});
t.start();
Game.getInstance()
.run();
game.run();
}
}

View File

@@ -5,34 +5,34 @@ public class State
// <CARBURANT PERDU> <PREMIER INTERVAL> <SECOND INTERVAL>
NORMAL(2, 1, 6);
private int carbUsed;
private int[] interval;
public int carbUsed;
public int[] interval;
private DriveMode(int carbUsed, int fInterval, int sInterval)
{
this.carbUsed = carbUsed;
interval = new int[] {fInterval, sInterval};
}
public int getConsumption()
{
return carbUsed;
}
public int[] getInterval()
{
return interval;
}
}
private DriveMode current = DriveMode.NORMAL;
private static DriveMode current = DriveMode.NORMAL;
public static DriveMode get()
public DriveMode get()
{
return current;
}
public static void set(DriveMode DriveMode)
public int[] getInterval()
{
return current.interval;
}
public int getConsumption()
{
return current.carbUsed;
}
public void set(DriveMode DriveMode)
{
current = DriveMode;
}