From 760e338b486373cbdf221125c6cfa88016177ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Mon, 27 Oct 2025 17:37:11 +0100 Subject: [PATCH 01/29] feat(Circuit.java): ajout interface pour la map --- src/Circuit.java | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/Circuit.java diff --git a/src/Circuit.java b/src/Circuit.java new file mode 100644 index 0000000..71818c3 --- /dev/null +++ b/src/Circuit.java @@ -0,0 +1,3 @@ +public interface Circuit { + CircuitCell getType(); +} \ No newline at end of file From 685313dc254f7e7644a2a8847d941384901ce6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Mon, 27 Oct 2025 17:50:57 +0100 Subject: [PATCH 02/29] feat(Map.java): init la class Map --- src/Map.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Map.java diff --git a/src/Map.java b/src/Map.java new file mode 100644 index 0000000..0822ff2 --- /dev/null +++ b/src/Map.java @@ -0,0 +1,19 @@ +import java.awt.Point; + +public class Map { + private Circuit[][] map; + private Point[] pathMap; + + public Map(Circuit[][] map) { + this.map = map; + this.buildPath(); + } + + private boolean buildPath() { + return false; + } + + public Circuit getElement(int x, int y) { + return map[y][x]; + } +} From 04b95601abd84b786104158ffe38f63b697c3598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 13:06:24 +0100 Subject: [PATCH 03/29] feat(Map.java): ajout fonction bindPath --- src/Map.java | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/Map.java b/src/Map.java index 0822ff2..7e8a6f9 100644 --- a/src/Map.java +++ b/src/Map.java @@ -1,19 +1,47 @@ import java.awt.Point; +import java.util.ArrayList; -public class Map { +public class Map +{ private Circuit[][] map; - private Point[] pathMap; + private ArrayList pathMap; - public Map(Circuit[][] map) { + public Map(Circuit[][] map) + { this.map = map; - this.buildPath(); } - private boolean buildPath() { - return false; + private Point[] bindPath() + { + Point start = null; + Point end = null; + + for (int i = 0; i < map.length; i++) + { + for (int j = 0; j < map.length; j++) + { + switch (map[i][j].getType()) + { + case CircuitCell.START: + if (start == null) start = new Point(i, j); + else return null; + break; + case CircuitCell.FINISH: + if (end == null) end = new Point(i, j); + else return null; + break; + default: + break; + } + } + } + + return new Point[] {start, end}; } - public Circuit getElement(int x, int y) { + + public Circuit getElement(int x, int y) + { return map[y][x]; } } From 5dd84cef9081ad2a51caf3f35214caae38fae046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 15:12:25 +0100 Subject: [PATCH 04/29] feat(Map.java): ajout followPath fonction --- src/Map.java | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/Map.java b/src/Map.java index 7e8a6f9..3a96ab4 100644 --- a/src/Map.java +++ b/src/Map.java @@ -39,6 +39,63 @@ public class Map return new Point[] {start, end}; } + private boolean followPath(Point start, Point end) + { + // remettre à 0 la liste + pathMap.clear(); + + // positions + Point current = start; + Point previous = null; + + int[][] coord = { + {1, 0}, // haut + {-1, 0}, // bas + {0, -1}, // gauche + {0, 1} // droite + }; + + // sécurité pour éviter les boucles infinie + int step = 0; + int max = map.length * map[0].length; + for (; step < max; step++) + { + pathMap.add(current); + + if (current.equals(end)) + return true; + + boolean moved = false; + + for (int[] pos : coord) + { + int x = current.x + pos[0]; + int y = current.y + pos[1]; + + if ((x >= 0 || map[0].length > x) || (y >= 0 || map.length > y)) + { + Point next = new Point(x, y); + + if (next.equals(previous)) + continue; + + CircuitCell type = map[y][x].getType(); + if (type == CircuitCell.FINISH || type == CircuitCell.ROAD + || type == CircuitCell.YROAD) + { + previous = current; + current = next; + moved = true; + break; + } + } + } + // Si il est bloqué + if (!moved) break; + } + + return false; + } public Circuit getElement(int x, int y) { From df30cd07169a3eedfa6dabcce4ac4d7c4857b91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 15:14:09 +0100 Subject: [PATCH 05/29] feat(Map.java): ajout buildPath function --- src/Map.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Map.java b/src/Map.java index 3a96ab4..c047d10 100644 --- a/src/Map.java +++ b/src/Map.java @@ -9,6 +9,20 @@ public class Map public Map(Circuit[][] map) { this.map = map; + this.buildPath(); + } + + private boolean buildPath() + { + Point[] p = bindPath(); + + if (p == null) + return false; + + Point start = p[0]; + Point end = p[0]; + + return followPath(start, end); } private Point[] bindPath() From 072b37ece74a62fa7b859a7111e1072e776eae5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 16:00:21 +0100 Subject: [PATCH 06/29] fix(Map.java): modif des fonc bind, follow et build path - `bindPath`: `Point(i, j)` -> `Point(j, i)` - `buildPath`: init ArrayList - `followPath`: ajout current == ROAD ET next == FINISH --- src/Map.java | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Map.java b/src/Map.java index c047d10..7277f44 100644 --- a/src/Map.java +++ b/src/Map.java @@ -9,7 +9,13 @@ public class Map public Map(Circuit[][] map) { this.map = map; - this.buildPath(); + boolean isPossible = this.buildPath(); + + if (!isPossible) + { + System.err.println("La map contient des doublons ou est impossible à finir!"); + System.exit(1); + } } private boolean buildPath() @@ -20,8 +26,9 @@ public class Map return false; Point start = p[0]; - Point end = p[0]; + Point end = p[1]; + this.pathMap = new ArrayList<>(); return followPath(start, end); } @@ -37,11 +44,11 @@ public class Map switch (map[i][j].getType()) { case CircuitCell.START: - if (start == null) start = new Point(i, j); + if (start == null) start = new Point(j, i); else return null; break; case CircuitCell.FINISH: - if (end == null) end = new Point(i, j); + if (end == null) end = new Point(j, i); else return null; break; default: @@ -49,7 +56,7 @@ public class Map } } } - + if (start == null || end == null) return null; return new Point[] {start, end}; } @@ -68,14 +75,14 @@ public class Map {0, -1}, // gauche {0, 1} // droite }; - + // sécurité pour éviter les boucles infinie int step = 0; int max = map.length * map[0].length; for (; step < max; step++) { pathMap.add(current); - + if (current.equals(end)) return true; @@ -86,7 +93,7 @@ public class Map int x = current.x + pos[0]; int y = current.y + pos[1]; - if ((x >= 0 || map[0].length > x) || (y >= 0 || map.length > y)) + if ((x >= 0 && map[0].length > x) && (y >= 0 && map.length > y)) { Point next = new Point(x, y); @@ -94,8 +101,8 @@ public class Map continue; CircuitCell type = map[y][x].getType(); - if (type == CircuitCell.FINISH || type == CircuitCell.ROAD - || type == CircuitCell.YROAD) + if ((type == CircuitCell.ROAD || type == CircuitCell.YROAD) || + (type == CircuitCell.FINISH && map[current.y][current.x] == CircuitCell.ROAD)) { previous = current; current = next; @@ -104,6 +111,7 @@ public class Map } } } + // Si il est bloqué if (!moved) break; } From f7677fec3b7ab1c58bd2c031da759fd5731707dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 16:27:47 +0100 Subject: [PATCH 07/29] feat(CircuitCell): implemente Circuit --- src/CircuitCell.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/CircuitCell.java b/src/CircuitCell.java index cf4918f..fa4e384 100644 --- a/src/CircuitCell.java +++ b/src/CircuitCell.java @@ -4,7 +4,7 @@ * cases qui composent le circuit de * course. */ -public enum CircuitCell { +public enum CircuitCell implements Circuit { /** * Case hors piste, non * praticable par les @@ -36,4 +36,9 @@ public enum CircuitCell { * livrable 2 */ YROAD; + + @Override + public CircuitCell getType() { + return this; + } } \ No newline at end of file From 9ab1d6b96076e695c85e79d371cbef1934f96c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 16:41:03 +0100 Subject: [PATCH 08/29] feat: enlever Circuit.java et toute ses impl --- src/Circuit.java | 3 --- src/CircuitCell.java | 7 +------ src/Map.java | 10 +++++----- 3 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 src/Circuit.java diff --git a/src/Circuit.java b/src/Circuit.java deleted file mode 100644 index 71818c3..0000000 --- a/src/Circuit.java +++ /dev/null @@ -1,3 +0,0 @@ -public interface Circuit { - CircuitCell getType(); -} \ No newline at end of file diff --git a/src/CircuitCell.java b/src/CircuitCell.java index fa4e384..cf4918f 100644 --- a/src/CircuitCell.java +++ b/src/CircuitCell.java @@ -4,7 +4,7 @@ * cases qui composent le circuit de * course. */ -public enum CircuitCell implements Circuit { +public enum CircuitCell { /** * Case hors piste, non * praticable par les @@ -36,9 +36,4 @@ public enum CircuitCell implements Circuit { * livrable 2 */ YROAD; - - @Override - public CircuitCell getType() { - return this; - } } \ No newline at end of file diff --git a/src/Map.java b/src/Map.java index 7277f44..d12254e 100644 --- a/src/Map.java +++ b/src/Map.java @@ -3,10 +3,10 @@ import java.util.ArrayList; public class Map { - private Circuit[][] map; + private CircuitCell[][] map; private ArrayList pathMap; - public Map(Circuit[][] map) + private Map(CircuitCell[][] map) { this.map = map; boolean isPossible = this.buildPath(); @@ -41,7 +41,7 @@ public class Map { for (int j = 0; j < map.length; j++) { - switch (map[i][j].getType()) + switch (map[i][j]) { case CircuitCell.START: if (start == null) start = new Point(j, i); @@ -100,7 +100,7 @@ public class Map if (next.equals(previous)) continue; - CircuitCell type = map[y][x].getType(); + CircuitCell type = map[y][x]; if ((type == CircuitCell.ROAD || type == CircuitCell.YROAD) || (type == CircuitCell.FINISH && map[current.y][current.x] == CircuitCell.ROAD)) { @@ -119,7 +119,7 @@ public class Map return false; } - public Circuit getElement(int x, int y) + public CircuitCell getElement(int x, int y) { return map[y][x]; } From c9affba9f54be97c0e93692543b8ba6bd6151f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 17:34:11 +0100 Subject: [PATCH 09/29] feat(Circuit): rework complet de Circuit --- src/Circuit.java | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/Circuit.java diff --git a/src/Circuit.java b/src/Circuit.java new file mode 100644 index 0000000..1006dcb --- /dev/null +++ b/src/Circuit.java @@ -0,0 +1,25 @@ +public class Circuit { + private final CircuitCell type; + private int value; + + public Circuit(CircuitCell type) + { + this.type = type; + this.value = type.ordinal(); + } + + public Circuit(CircuitCell type, int value) + { + this.type = type; + this.value = value; + } + + public Circuit setValue(int value) + { + this.value = value; + return this; + } + + public CircuitCell getType() { return type; } + public int getValue() { return value; } +} From 5a62b58e9ed16a6cab1d3474bb706dc0125c9956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 17:35:46 +0100 Subject: [PATCH 10/29] feat(Map.java): ajout static factory ajout fonctionnel dans constructeur --- src/Map.java | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/Map.java b/src/Map.java index d12254e..09382b2 100644 --- a/src/Map.java +++ b/src/Map.java @@ -1,12 +1,42 @@ import java.awt.Point; import java.util.ArrayList; +import java.util.function.Function; public class Map { - private CircuitCell[][] map; + private Circuit[][] map; private ArrayList pathMap; - private Map(CircuitCell[][] map) + public static Map create(Function fn, T[][] map) + { + int lenX = map[0].length; + int lenY = map.length; + + Circuit[][] newmap = new Circuit[lenY][lenX]; + + for (int y = 0; y < lenY; y++) + { + for (int x = 0; x < lenX; x++) + { + newmap[y][x] = fn.apply(map[y][x]); + } + } + + return new Map(newmap); + } + + public static Map fromInts(Integer[][] map) + { + return create((i) -> switch (i) { + case 0 -> new Circuit(CircuitCell.EMPTY); + case 1 -> new Circuit(CircuitCell.ROAD); + case 2 -> new Circuit(CircuitCell.START); + case 3 -> new Circuit(CircuitCell.FINISH); + default -> new Circuit(CircuitCell.YROAD, i); + }, map); + } + + private Map(Circuit[][] map) { this.map = map; boolean isPossible = this.buildPath(); @@ -41,7 +71,7 @@ public class Map { for (int j = 0; j < map.length; j++) { - switch (map[i][j]) + switch (map[i][j].getType()) { case CircuitCell.START: if (start == null) start = new Point(j, i); @@ -100,9 +130,9 @@ public class Map if (next.equals(previous)) continue; - CircuitCell type = map[y][x]; + CircuitCell type = map[y][x].getType(); if ((type == CircuitCell.ROAD || type == CircuitCell.YROAD) || - (type == CircuitCell.FINISH && map[current.y][current.x] == CircuitCell.ROAD)) + (type == CircuitCell.FINISH && map[current.y][current.x].getType() == CircuitCell.ROAD)) { previous = current; current = next; @@ -121,6 +151,6 @@ public class Map public CircuitCell getElement(int x, int y) { - return map[y][x]; + return map[y][x].getType(); } } From 183e45dbd4d8c09e965a27ca27cade23def6d4e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 17:47:39 +0100 Subject: [PATCH 11/29] feat(Map.java): ajout fromChars fonction --- src/Main.java | 6 +++++- src/Map.java | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Main.java b/src/Main.java index 3148cdf..3ae8b53 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,9 @@ public class Main { public static void main(String[] args) { - System.out.println("Projet Livrable 1"); + Map m = Map.fromChars(new Character[][] { + {'3', '#', '2'}, + {'#', ' ', 'S'}, + {'9', '#', 'F'}, + }); } } \ No newline at end of file diff --git a/src/Map.java b/src/Map.java index 09382b2..3504b79 100644 --- a/src/Map.java +++ b/src/Map.java @@ -36,6 +36,18 @@ public class Map }, map); } + public static Map fromChars(Character[][] map) + { + return create((i) -> switch (i) { + case '#' -> new Circuit(CircuitCell.ROAD); + case 'S' -> new Circuit(CircuitCell.START); + case 'F' -> new Circuit(CircuitCell.FINISH); + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + -> new Circuit(CircuitCell.YROAD, '0' - i); + default -> new Circuit(CircuitCell.EMPTY); + }, map); + } + private Map(Circuit[][] map) { this.map = map; From f169269c4aec4d58ba0ee69eca81d710480878ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 17:48:13 +0100 Subject: [PATCH 12/29] feat(Map.java): ajout getPathSize fonction --- src/Map.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Map.java b/src/Map.java index 3504b79..74004ba 100644 --- a/src/Map.java +++ b/src/Map.java @@ -165,4 +165,9 @@ public class Map { return map[y][x].getType(); } + + public int getPathSize() + { + return this.pathMap.size(); + } } From f950972aa682bd69729cfdb914f4e3ac7836fa6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 19:22:26 +0100 Subject: [PATCH 13/29] =?UTF-8?q?chore(Map.java):=20init=20javadoc=20(va?= =?UTF-8?q?=20tr=C3=A8s=20vite=20changer)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Map.java | 116 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 3 deletions(-) diff --git a/src/Map.java b/src/Map.java index 74004ba..08e1bdc 100644 --- a/src/Map.java +++ b/src/Map.java @@ -2,11 +2,35 @@ import java.awt.Point; import java.util.ArrayList; import java.util.function.Function; +/** + *

Map représente le circuit de course.

+ *

Cette classe contient:

+ *
    + *
  • Un tableau 2D de CircuitCell
  • + *
  • Une liste de Points qui représente le chemin pour la voiture entre START et FINISH
  • + *
+ */ public class Map { + /** + * Tableau 2D représentant le circuit. + * Chaque élément est une instance de Circuit. + */ private Circuit[][] map; + /** + * Liste des coordonnées représentant le chemin du START au FINISH. + */ private ArrayList pathMap; + /** + * Crée une nouvelle instance de Map à partir d'un tableau générique + * et d'une fonction de transformation. + * + * @param Type des éléments du tableau source + * @param fn Fonction qui transforme un élément T en Circuit + * @param array Tableau 2D d'éléments T + * @return Une nouvelle instance de Map + */ public static Map create(Function fn, T[][] map) { int lenX = map[0].length; @@ -25,6 +49,19 @@ public class Map return new Map(newmap); } + /** + * Crée une map à partir d'un tableau d'entiers. + *
    + *
  • 0 -> EMPTY
  • + *
  • 1 -> ROAD
  • + *
  • 2 -> START
  • + *
  • 3 -> FINISH
  • + *
  • autres -> YROAD avec la valeur associée
  • + *
+ * + * @param array Tableau 2D d'entiers + * @return Une nouvelle instance de Map + */ public static Map fromInts(Integer[][] map) { return create((i) -> switch (i) { @@ -36,6 +73,19 @@ public class Map }, map); } + /** + * Crée une map à partir d'un tableau de caractères. + *
    + *
  • '#' -> ROAD
  • + *
  • 'S' -> START
  • + *
  • 'F' -> FINISH
  • + *
  • '0'-'9' -> YROAD avec valeur correspondante
  • + *
  • autres -> EMPTY
  • + *
+ * + * @param array Tableau 2D de caractères + * @return Une nouvelle instance de Map + */ public static Map fromChars(Character[][] map) { return create((i) -> switch (i) { @@ -48,6 +98,13 @@ public class Map }, map); } + /** + * Constructeur privé utilisé par les méthodes statiques de création. + * Initialise la map et construit le chemin. + * Si la map est invalide ou impossible à résoudre, termine le programme. + * + * @param map Tableau 2D de Circuit + */ private Map(Circuit[][] map) { this.map = map; @@ -59,7 +116,12 @@ public class Map System.exit(1); } } - + + /** + * Construit le chemin entre START et FINISH. + * + * @return true si un chemin valide existe, false sinon + */ private boolean buildPath() { Point[] p = bindPath(); @@ -74,6 +136,11 @@ public class Map return followPath(start, end); } + /** + * Cherche les points START et FINISH sur la map. + * + * @return Un tableau de 2 éléments : {START, FINISH} ou null si la map est invalide + */ private Point[] bindPath() { Point start = null; @@ -102,6 +169,14 @@ public class Map return new Point[] {start, end}; } + /** + * Suivi du chemin depuis START jusqu'à FINISH. + * Parcours les cases ROAD et YROAD jusqu'à atteindre FINISH. + * + * @param start Point de départ + * @param end Point d'arrivée + * @return true si un chemin complet a été trouvé, false sinon + */ private boolean followPath(Point start, Point end) { // remettre à 0 la liste @@ -161,11 +236,46 @@ public class Map return false; } - public CircuitCell getElement(int x, int y) + /** + * Retourne l'objet Circuit à la position (x, y). + * + * @param x Coordonnée X + * @param y Coordonnée Y + * @return L'objet Circuit + */ + public Circuit getElement(int x, int y) { - return map[y][x].getType(); + return map[y][x]; } + /** + * Retourne le type de cellule (CircuitCell) à la position (x, y). + * + * @param x Coordonnée X + * @param y Coordonnée Y + * @return Le type de cellule CircuitCell + */ + public CircuitCell getCell(int x, int y) + { + return getElement(x, y).getType(); + } + + /** + * Retourne le point du chemin à l'indice donné. + * + * @param index Indice dans le chemin + * @return Point correspondant + */ + public Point getPath(int i) + { + return this.pathMap.get(i); + } + + /** + * Retourne la taille du chemin trouvé. + * + * @return Nombre de points dans le chemin + */ public int getPathSize() { return this.pathMap.size(); From cd9894e92bdcd7d061af155d61adaca3da3223e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 21:32:46 +0100 Subject: [PATCH 14/29] fix(Map.java): '0' - i -> i - '0' --- src/Map.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Map.java b/src/Map.java index 08e1bdc..a632b85 100644 --- a/src/Map.java +++ b/src/Map.java @@ -93,7 +93,7 @@ public class Map case 'S' -> new Circuit(CircuitCell.START); case 'F' -> new Circuit(CircuitCell.FINISH); case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - -> new Circuit(CircuitCell.YROAD, '0' - i); + -> new Circuit(CircuitCell.YROAD, i - '0'); default -> new Circuit(CircuitCell.EMPTY); }, map); } @@ -270,7 +270,7 @@ public class Map { return this.pathMap.get(i); } - + /** * Retourne la taille du chemin trouvé. * From 6e0ddb5aa652805da5f9fde202c8b471a3482669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 23:19:56 +0100 Subject: [PATCH 15/29] feat(Car.java): ajout commentaire et basic fn --- src/Car.java | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Main.java | 3 ++ 2 files changed, 79 insertions(+) create mode 100644 src/Car.java diff --git a/src/Car.java b/src/Car.java new file mode 100644 index 0000000..7093a91 --- /dev/null +++ b/src/Car.java @@ -0,0 +1,76 @@ +/** + * Car 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 { + + /** Position actuelle dans la boucle (entre 0 et loop inclus) */ + private int pos = 0; + + /** Nombre de tours complétés */ + private int round = 0; + + /** Nombre total de cases dans une boucle (doit être > 0) */ + private final int loop; + + /** + * Construit une nouvelle voiture. + * + * @param loop nombre de positions par boucle (doit être > 0) + * @throws IllegalArgumentException si {@code loop <= 0} + */ + public Car(int loop) + { + if (loop <= 0) + throw new IllegalArgumentException("loop must be > 0!"); + this.loop = loop; + } + + /** + * Fait avancer la voiture d'une position. + *

Si la position atteint la fin de la boucle, un nouveau tour est compté.

+ * + * @return cette même instance (pour chaînage fluide) + */ + public Car makeMove() + { + pos++; + if (pos == loop) + round++; + pos %= (loop + 1); // Repart de 0 après avoir dépassé loop + return this; + } + + /** + * @return la position actuelle dans la boucle + */ + public int getPosition() + { + return pos; + } + + /** + * @return le score, calculé comme (nombre de tours + progression du tour) × 100 + */ + public int getScore() + { + return (int) ((round + (float) pos / loop) * 100); + } + + /** + * @return le nombre de tours complétés + */ + public int getRound() + { + return round; + } + + /** + * @return la taille de la boucle (nombre de positions) + */ + public int getLoop() + { + return loop; + } +} \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index 3ae8b53..f7a71af 100644 --- a/src/Main.java +++ b/src/Main.java @@ -5,5 +5,8 @@ public class Main { {'#', ' ', 'S'}, {'9', '#', 'F'}, }); + + System.out.println(m.getPathSize()); + Car car = new Car(m.getPathSize()); } } \ No newline at end of file From 6a0d411e8ec646a5b80bdafcbacff2f3a45adee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 23:26:34 +0100 Subject: [PATCH 16/29] feat(Circuit.java): ajout new fn et commentaires --- src/Circuit.java | 106 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 17 deletions(-) diff --git a/src/Circuit.java b/src/Circuit.java index 1006dcb..de3cfd8 100644 --- a/src/Circuit.java +++ b/src/Circuit.java @@ -1,25 +1,97 @@ -public class Circuit { - private final CircuitCell type; +/** + * Représente une cellule du circuit. + *

+ * Chaque cellule possède un type ({@link CircuitCell}) et éventuellement une valeur + * numérique (par exemple pour indiquer une intensité, une vitesse, ou un identifiant de route). + *

+ */ +public class Circuit +{ + /** Type de la cellule (vide, route, départ, arrivée, etc.) */ + private final CircuitCell type; + + /** Valeur associée à la cellule (optionnelle, dépend du type) */ private int value; - public Circuit(CircuitCell type) - { + /** + * Construit une cellule avec un type défini et une valeur par défaut + * égale à l’indice ordinal du type. + * + * @param type le type de la cellule + */ + public Circuit(CircuitCell type) + { this.type = type; - this.value = type.ordinal(); + this.value = type.ordinal(); } - public Circuit(CircuitCell type, int value) - { + /** + * Construit une cellule avec un type et une valeur spécifique. + * + * @param type le type de la cellule + * @param value la valeur associée à la cellule + */ + public Circuit(CircuitCell type, int value) + { this.type = type; - this.value = value; + this.value = value; } - - public Circuit setValue(int value) - { - this.value = value; - return this; - } - public CircuitCell getType() { return type; } - public int getValue() { return value; } -} + /** + * Modifie la valeur associée à la cellule. + * + * @param value la nouvelle valeur + * @return cette même instance (pour chaînage fluide) + */ + public Circuit setValue(int value) + { + this.value = value; + return this; + } + + /** + * @return le type de la cellule + */ + public CircuitCell getType() + { + return type; + } + + /** + * @return la valeur associée à la cellule + */ + public int getValue() + { + return value; + } + + /** + * Vérifie si la cellule est une route (ROAD ou YROAD). + * + * @return vrai si la cellule représente une route + */ + public boolean isRoad() + { + return type == CircuitCell.ROAD || type == CircuitCell.YROAD; + } + + /** + * Vérifie si la cellule est un point de départ. + * + * @return vrai si la cellule représente le départ + */ + public boolean isStart() + { + return type == CircuitCell.START; + } + + /** + * Vérifie si la cellule est un point d’arrivée. + * + * @return vrai si la cellule représente la fin du circuit + */ + public boolean isFinish() + { + return type == CircuitCell.FINISH; + } +} \ No newline at end of file From bfc34df62aab87c4dbaf9d9a2a94d45eb65b5bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 23:31:12 +0100 Subject: [PATCH 17/29] feat(Map.java): ajout element.isFinish / isRoad --- src/Map.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Map.java b/src/Map.java index a632b85..468e902 100644 --- a/src/Map.java +++ b/src/Map.java @@ -14,7 +14,7 @@ public class Map { /** * Tableau 2D représentant le circuit. - * Chaque élément est une instance de Circuit. + * Chaque élément est une instance de {@link Circuit}. */ private Circuit[][] map; /** @@ -217,9 +217,8 @@ public class Map if (next.equals(previous)) continue; - CircuitCell type = map[y][x].getType(); - if ((type == CircuitCell.ROAD || type == CircuitCell.YROAD) || - (type == CircuitCell.FINISH && map[current.y][current.x].getType() == CircuitCell.ROAD)) + Circuit element = getElement(x, y); + if (element.isRoad() || (element.isFinish() && element.isRoad())) { previous = current; current = next; From c2516705f232ea6cd42844110dd6985c7636a4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 29 Oct 2025 23:38:30 +0100 Subject: [PATCH 18/29] fix(Map.java): changer en current.isRoad --- src/Map.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Map.java b/src/Map.java index 468e902..a407a37 100644 --- a/src/Map.java +++ b/src/Map.java @@ -217,8 +217,9 @@ public class Map if (next.equals(previous)) continue; - Circuit element = getElement(x, y); - if (element.isRoad() || (element.isFinish() && element.isRoad())) + Circuit element = getElement(x, y); + Circuit cElement = getElement(current.x, current.y); + if (element.isRoad() || (element.isFinish() && cElement.isRoad())) { previous = current; current = next; From c1bc62b879c8de2efcc9d68d844309ef556a3780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Thu, 30 Oct 2025 16:45:13 +0100 Subject: [PATCH 19/29] feat(State.java): ajout classe State (Livrable 2) --- src/State.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/State.java diff --git a/src/State.java b/src/State.java new file mode 100644 index 0000000..890b920 --- /dev/null +++ b/src/State.java @@ -0,0 +1,19 @@ +public class State +{ + public static enum Status + { + NORMAL; + } + + private static Status current = Status.NORMAL; + + public static Status get() + { + return current; + } + + public static void set(Status status) + { + current = status; + } +} From ef30313a2522481aa1b34504666e426129f3f086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Thu, 30 Oct 2025 17:13:51 +0100 Subject: [PATCH 20/29] fix: nom etat et ajout fuel --- src/Car.java | 13 +++++++++++++ src/State.java | 32 ++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/Car.java b/src/Car.java index 7093a91..c3ff178 100644 --- a/src/Car.java +++ b/src/Car.java @@ -13,6 +13,8 @@ public class Car { /** Nombre total de cases dans une boucle (doit être > 0) */ private final int loop; + /** Nombre de fuel restant */ + private int fuel = 60; /** * Construit une nouvelle voiture. @@ -73,4 +75,15 @@ public class Car { { return loop; } + + public int getFuel() + { + return fuel; + } + + public Car consumeFuel() + { + fuel -= State.get().getConsumption(); + return this; + } } \ No newline at end of file diff --git a/src/State.java b/src/State.java index 890b920..315f069 100644 --- a/src/State.java +++ b/src/State.java @@ -1,19 +1,39 @@ public class State { - public static enum Status + public static enum DriveMode { - NORMAL; +// + NORMAL(2, 1, 6); + + private int carbUsed; + private 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 static Status current = Status.NORMAL; + private static DriveMode current = DriveMode.NORMAL; - public static Status get() + public static DriveMode get() { return current; } - public static void set(Status status) + public static void set(DriveMode DriveMode) { - current = status; + current = DriveMode; } } From 23f56113b718aa8b3e21be4216e8b36be6ce26cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Thu, 30 Oct 2025 17:23:30 +0100 Subject: [PATCH 21/29] feat(Game.java): ajout constructor et init fn --- src/Game.java | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/Game.java diff --git a/src/Game.java b/src/Game.java new file mode 100644 index 0000000..b8dc83b --- /dev/null +++ b/src/Game.java @@ -0,0 +1,42 @@ +public class Game +{ + private Car[] car; + private Map map; + + public Game(int playerNumber, Map map) + { + this.car = new Car[playerNumber]; + this.map = map; + + init().run(); + } + + private Game init() + { + // combien de route avant loop + int loop = this.map.getPathSize(); + for (int i = 0; i < car.length; i++) + { + car[i] = new Car(loop); + } + return this; + } + + private boolean isFinish() + { + for (int i = 0; i < car.length; i++) + { + if (car[i].getFuel() == 0) + return true; + } + return false; + } + + public void run() + { + while (isFinish()) + { + + } + } +} From 974fa21c3d6b63bbd7c28d520b35a2bb05a13a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Thu, 30 Oct 2025 19:08:56 +0100 Subject: [PATCH 22/29] fix: ajout multiple fonction Map / Game / Car --- src/Car.java | 8 ++-- src/Game.java | 109 +++++++++++++++++++++++++++++++++++++++++++------- src/Main.java | 5 ++- src/Map.java | 12 +++--- 4 files changed, 108 insertions(+), 26 deletions(-) diff --git a/src/Car.java b/src/Car.java index c3ff178..f05019f 100644 --- a/src/Car.java +++ b/src/Car.java @@ -35,12 +35,14 @@ public class Car { * * @return cette même instance (pour chaînage fluide) */ - public Car makeMove() + public Car makeMove(int move) { - pos++; + pos += move; if (pos == loop) + { round++; - pos %= (loop + 1); // Repart de 0 après avoir dépassé loop + pos = 0; + } return this; } diff --git a/src/Game.java b/src/Game.java index b8dc83b..4074796 100644 --- a/src/Game.java +++ b/src/Game.java @@ -1,42 +1,121 @@ +import java.util.ArrayList; +import java.util.Random; + public class Game { - private Car[] car; - private Map map; - - public Game(int playerNumber, Map map) + @FunctionalInterface + private static interface GameObserver { - this.car = new Car[playerNumber]; - this.map = map; - - init().run(); + /** + * + * @return true si la fonction s'est bien passé sinon false (le programme va se stopper) + */ + public boolean apply(); } - private Game init() + private static Game game; + + private Car[] cars; + private Map map; + private ArrayList obs = new ArrayList<>(); + + private Random random = new Random(); + private boolean pause = false; + + public static Game create() { + if (game == null) game = new Game(); + return game; + } + + private Game() {} + + public Game init(int playerNumber, Map map) + { + this.cars = new Car[playerNumber]; + this.map = map; // combien de route avant loop int loop = this.map.getPathSize(); - for (int i = 0; i < car.length; i++) + for (int i = 0; i < cars.length; i++) { - car[i] = new Car(loop); + 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()); + } + + return true; + }); } + return this; } + public 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 init(3, Map.fromInts(map)); + } + private boolean isFinish() { - for (int i = 0; i < car.length; i++) + for (Car car : cars) { - if (car[i].getFuel() == 0) + if (car.getFuel() == 0) return true; } return false; } + private synchronized void step() throws InterruptedException + { + // if (pause) wait(); + + for (GameObserver o : obs) + { + if (!o.apply()) + { + System.err.println("Une erreur s'est produite pendant le jeu."); + System.exit(1); + } + } + + } + public void run() { - while (isFinish()) - { + if (this.cars == null || this.map == null) + defaultInit(); + while (!isFinish()) + { + // notifyAll(); + try + { + step(); + Thread.sleep(1000); + } + catch (InterruptedException e) + { e.printStackTrace(); } } } } diff --git a/src/Main.java b/src/Main.java index f7a71af..390fe52 100644 --- a/src/Main.java +++ b/src/Main.java @@ -6,7 +6,8 @@ public class Main { {'9', '#', 'F'}, }); - System.out.println(m.getPathSize()); - Car car = new Car(m.getPathSize()); + Game.create() + .init(3, m) + .run(); } } \ No newline at end of file diff --git a/src/Map.java b/src/Map.java index a407a37..5bfd1b6 100644 --- a/src/Map.java +++ b/src/Map.java @@ -53,9 +53,9 @@ public class Map * Crée une map à partir d'un tableau d'entiers. *
    *
  • 0 -> EMPTY
  • - *
  • 1 -> ROAD
  • - *
  • 2 -> START
  • - *
  • 3 -> FINISH
  • + *
  • -1 -> ROAD
  • + *
  • -2 -> START
  • + *
  • -3 -> FINISH
  • *
  • autres -> YROAD avec la valeur associée
  • *
* @@ -66,9 +66,9 @@ public class Map { return create((i) -> switch (i) { case 0 -> new Circuit(CircuitCell.EMPTY); - case 1 -> new Circuit(CircuitCell.ROAD); - case 2 -> new Circuit(CircuitCell.START); - case 3 -> new Circuit(CircuitCell.FINISH); + case -1 -> new Circuit(CircuitCell.ROAD); + case -2 -> new Circuit(CircuitCell.START); + case -3 -> new Circuit(CircuitCell.FINISH); default -> new Circuit(CircuitCell.YROAD, i); }, map); } From 0504c5affb46ba0664d57fc9be064386ae54da36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Thu, 30 Oct 2025 19:51:02 +0100 Subject: [PATCH 23/29] fix: correction map.length -> map[0].length --- src/Map.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Map.java b/src/Map.java index a407a37..527b2c2 100644 --- a/src/Map.java +++ b/src/Map.java @@ -53,9 +53,9 @@ public class Map * Crée une map à partir d'un tableau d'entiers. *
    *
  • 0 -> EMPTY
  • - *
  • 1 -> ROAD
  • - *
  • 2 -> START
  • - *
  • 3 -> FINISH
  • + *
  • -1 -> ROAD
  • + *
  • -2 -> START
  • + *
  • -3 -> FINISH
  • *
  • autres -> YROAD avec la valeur associée
  • *
* @@ -66,9 +66,9 @@ public class Map { return create((i) -> switch (i) { case 0 -> new Circuit(CircuitCell.EMPTY); - case 1 -> new Circuit(CircuitCell.ROAD); - case 2 -> new Circuit(CircuitCell.START); - case 3 -> new Circuit(CircuitCell.FINISH); + case -1 -> new Circuit(CircuitCell.ROAD); + case -2 -> new Circuit(CircuitCell.START); + case -3 -> new Circuit(CircuitCell.FINISH); default -> new Circuit(CircuitCell.YROAD, i); }, map); } @@ -148,7 +148,7 @@ public class Map for (int i = 0; i < map.length; i++) { - for (int j = 0; j < map.length; j++) + for (int j = 0; j < map[0].length; j++) { switch (map[i][j].getType()) { From 2488aec5a222a46e65fbc58ea40544423266b3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Sat, 1 Nov 2025 10:23:51 +0100 Subject: [PATCH 24/29] feat(Game.java): ajout fonction togglePause --- src/Game.java | 31 +++++++++++++++++++++++-------- src/Main.java | 18 +++++++++++++++++- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/Game.java b/src/Game.java index 4074796..07de966 100644 --- a/src/Game.java +++ b/src/Game.java @@ -20,7 +20,7 @@ public class Game private ArrayList obs = new ArrayList<>(); private Random random = new Random(); - private boolean pause = false; + private boolean paused = false; public static Game create() { @@ -86,21 +86,37 @@ public class Game return false; } - private synchronized void step() throws InterruptedException + private void step() throws InterruptedException { - // if (pause) wait(); - for (GameObserver o : obs) { - if (!o.apply()) + synchronized (this) { - System.err.println("Une erreur s'est produite pendant le jeu."); - System.exit(1); + // pause du jeu + if (paused) wait(); + + boolean isSuccess = o.apply(); + if (!isSuccess) + { + System.err.println("Une erreur s'est produite pendant le jeu."); + System.exit(1); + } } } } + public synchronized boolean togglePause() + { + if (paused) + { + notifyAll(); + paused = false; + } + else paused = true; + return paused; + } + public void run() { if (this.cars == null || this.map == null) @@ -108,7 +124,6 @@ public class Game while (!isFinish()) { - // notifyAll(); try { step(); diff --git a/src/Main.java b/src/Main.java index 390fe52..c251c8a 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,11 +1,27 @@ public class Main { - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { Map m = Map.fromChars(new Character[][] { {'3', '#', '2'}, {'#', ' ', 'S'}, {'9', '#', 'F'}, }); + Thread t = new Thread(() -> { + while (true) + { + try + { + Thread.sleep(5000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + System.out.println(Game.create().togglePause() ? "stop" : "fini"); + } + }); + + t.start(); Game.create() .init(3, m) .run(); From 47bbe1e7496c995fa42273ed531ce1f2e85ee9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Sat, 1 Nov 2025 10:28:50 +0100 Subject: [PATCH 25/29] fix(Map.java): changement position [0] <-> [1] --- src/Map.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Map.java b/src/Map.java index 527b2c2..c0a1411 100644 --- a/src/Map.java +++ b/src/Map.java @@ -207,8 +207,8 @@ public class Map for (int[] pos : coord) { - int x = current.x + pos[0]; - int y = current.y + pos[1]; + int x = current.x + pos[1]; + int y = current.y + pos[0]; if ((x >= 0 && map[0].length > x) && (y >= 0 && map.length > y)) { From 78ad5d3491bd9a86a4b011de0db372cde48f04f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Sat, 1 Nov 2025 20:08:39 +0100 Subject: [PATCH 26/29] feat: ajout fonction observer et while dans paused --- src/Game.java | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Game.java b/src/Game.java index 07de966..ee2aa99 100644 --- a/src/Game.java +++ b/src/Game.java @@ -22,7 +22,7 @@ public class Game private Random random = new Random(); private boolean paused = false; - public static Game create() + public static Game getInstance() { if (game == null) game = new Game(); return game; @@ -41,6 +41,7 @@ public class Game final Car CAR = new Car(loop); final int I = i; cars[i] = CAR; + // Observer pour avancer obs.add(() -> { if (CAR.getFuel() > 0) @@ -49,7 +50,7 @@ public class Game int rand = random.nextInt(interval[0], interval[1]); CAR.makeMove(rand).consumeFuel(); - System.out.println("car " + I + " score: " + CAR.getScore()); + System.out.println("car " + I + " score: " + CAR.getScore() + " random: " + rand); } return true; @@ -59,21 +60,14 @@ public class Game return this; } - public Game defaultInit() + public void addObserver(GameObserver game) { - 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 init(3, Map.fromInts(map)); + obs.add(game); + } + + public void removeObserver(GameObserver game) + { + obs.remove(game); } private boolean isFinish() @@ -92,8 +86,11 @@ public class Game { synchronized (this) { - // pause du jeu - if (paused) wait(); + // pause du jeu, while si on notifyall sans faire exprès un autre bout de code + while (paused) + { + wait(); + } boolean isSuccess = o.apply(); if (!isSuccess) @@ -120,7 +117,10 @@ public class Game public void run() { if (this.cars == null || this.map == null) - defaultInit(); + { + System.out.println("Lancement du init par défaut."); + GFactory.defaultInit(); + } while (!isFinish()) { From 5121e25e46384c3cf9148caa3d03dea071c198cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Sat, 1 Nov 2025 20:09:18 +0100 Subject: [PATCH 27/29] feat: ajout une classe pour les inits de base --- src/GFactory.java | 20 ++++++++++++++++++++ src/Main.java | 8 ++++---- 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 src/GFactory.java diff --git a/src/GFactory.java b/src/GFactory.java new file mode 100644 index 0000000..8621a7c --- /dev/null +++ b/src/GFactory.java @@ -0,0 +1,20 @@ +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)); + } + +} diff --git a/src/Main.java b/src/Main.java index c251c8a..049c432 100644 --- a/src/Main.java +++ b/src/Main.java @@ -7,7 +7,8 @@ public class Main { }); Thread t = new Thread(() -> { - while (true) + int i = 0; + while (i++ < 10) { try { @@ -17,13 +18,12 @@ public class Main { { e.printStackTrace(); } - System.out.println(Game.create().togglePause() ? "stop" : "fini"); + System.out.println(Game.getInstance().togglePause() ? "stop" : "fini" ); } }); t.start(); - Game.create() - .init(3, m) + Game.getInstance() .run(); } } \ No newline at end of file From d2847745baa9ff348abd0fc8884037a6cc2ddf8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 5 Nov 2025 20:23:57 +0100 Subject: [PATCH 28/29] feat: ajout impl Car et rework State et Game --- src/Car.java | 33 +++++++-- src/GFactory.java | 20 ------ src/GObserver.java | 13 ++++ src/Game.java | 164 ++++++++++++++++++++++----------------------- src/Main.java | 10 ++- src/State.java | 46 ++++++------- 6 files changed, 149 insertions(+), 137 deletions(-) delete mode 100644 src/GFactory.java create mode 100644 src/GObserver.java diff --git a/src/Car.java b/src/Car.java index f05019f..1ac630f 100644 --- a/src/Car.java +++ b/src/Car.java @@ -1,18 +1,24 @@ +import java.util.Random; + /** * Car 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; - + /** Nombre de tours complétés */ private int round = 0; - + /** 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; + } } \ No newline at end of file diff --git a/src/GFactory.java b/src/GFactory.java deleted file mode 100644 index 8621a7c..0000000 --- a/src/GFactory.java +++ /dev/null @@ -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)); - } - -} diff --git a/src/GObserver.java b/src/GObserver.java new file mode 100644 index 0000000..cb2e4f6 --- /dev/null +++ b/src/GObserver.java @@ -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(); +} \ No newline at end of file diff --git a/src/Game.java b/src/Game.java index ee2aa99..64519e8 100644 --- a/src/Game.java +++ b/src/Game.java @@ -1,73 +1,79 @@ import java.util.ArrayList; -import java.util.Random; public class Game { - @FunctionalInterface - private static interface GameObserver + private boolean paused; + private Car[] cars; + private Map map; + + public static class Builder { - /** - * - * @return true si la fonction s'est bien passé sinon false (le programme va se stopper) - */ - public boolean apply(); - } + private int pnumber = 3; + private Map map = null; + private State state = new State(); - private static Game game; - - private Car[] cars; - private Map map; - private ArrayList obs = new ArrayList<>(); - - private Random random = new Random(); - private boolean paused = false; - - public static Game getInstance() - { - if (game == null) game = new Game(); - return game; - } - - private Game() {} - - public Game init(int playerNumber, Map map) - { - 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++) + public Builder setPlayers(int pnumber) { - 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 Builder setMap(Map map) + { + this.map = map; + return this; + } + + public Builder setState(State s) + { + 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); } - - return this; } - - public void addObserver(GameObserver game) + + private ArrayList obs; + + public Game(int pnumber, Map map, State state) { - obs.add(game); - } + int loop = map.getPathSize(); + this.map = map; - public void removeObserver(GameObserver game) - { - obs.remove(game); + 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,37 +104,18 @@ public class Game { wait(); } - - boolean isSuccess = o.apply(); - if (!isSuccess) - { - System.err.println("Une erreur s'est produite pendant le jeu."); - System.exit(1); - } + } + boolean isSuccess = o.apply(); + if (!isSuccess) + { + System.err.println("Une erreur s'est produite pendant le jeu."); + System.exit(1); } } - - } - - 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 diff --git a/src/Main.java b/src/Main.java index 049c432..c95ad42 100644 --- a/src/Main.java +++ b/src/Main.java @@ -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(); } } \ No newline at end of file diff --git a/src/State.java b/src/State.java index 315f069..148d39a 100644 --- a/src/State.java +++ b/src/State.java @@ -5,35 +5,35 @@ public class State // 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; + this.carbUsed = carbUsed; + interval = new int[] {fInterval, sInterval}; } } - private static DriveMode current = DriveMode.NORMAL; + private DriveMode current = DriveMode.NORMAL; - public static DriveMode get() - { - return current; - } + public DriveMode get() + { + return current; + } - public static void set(DriveMode DriveMode) - { - current = DriveMode; - } + public int[] getInterval() + { + return current.interval; + } + + public int getConsumption() + { + return current.carbUsed; + } + + public void set(DriveMode DriveMode) + { + current = DriveMode; + } } From 8d280b1024eb01a14cd78770c6a7f72b29738105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 5 Nov 2025 22:26:20 +0100 Subject: [PATCH 29/29] feat: fusion Circuit et CircuitCell --- src/Circuit.java | 57 +++++++++++++++++++++++++++++++++++++------- src/CircuitCell.java | 39 ------------------------------ src/Game.java | 5 ++-- src/Main.java | 12 +++++----- src/Map.java | 32 ++++++++++++------------- 5 files changed, 74 insertions(+), 71 deletions(-) delete mode 100644 src/CircuitCell.java diff --git a/src/Circuit.java b/src/Circuit.java index de3cfd8..8f52aee 100644 --- a/src/Circuit.java +++ b/src/Circuit.java @@ -1,14 +1,55 @@ /** * Représente une cellule du circuit. *

- * Chaque cellule possède un type ({@link CircuitCell}) et éventuellement une valeur + * Chaque cellule possède un type ({@link Cell}) et éventuellement une valeur * numérique (par exemple pour indiquer une intensité, une vitesse, ou un identifiant de route). *

*/ public class Circuit { + /** + * Cell est un enum + * représentant les différents types de + * cases qui composent le circuit de + * course. + */ + public static enum Cell + { + /** + * Case hors piste, non + * praticable par les + * voitures. */ + EMPTY, + + /** + * Case de route normale + * sur laquelle les voitures + * peuvent circuler. + */ + ROAD, + + /** + * Case correspondant à la + * ligne de départ du circuit. + */ + START, + + /** + * Case correspondant à la + * ligne d'arrivée du circuit. + */ + FINISH, + + /** + * Case de route jaune, plus + * d'information sur le + * livrable 2 + */ + YROAD; + } + /** Type de la cellule (vide, route, départ, arrivée, etc.) */ - private final CircuitCell type; + private final Cell type; /** Valeur associée à la cellule (optionnelle, dépend du type) */ private int value; @@ -19,7 +60,7 @@ public class Circuit * * @param type le type de la cellule */ - public Circuit(CircuitCell type) + public Circuit(Cell type) { this.type = type; this.value = type.ordinal(); @@ -31,7 +72,7 @@ public class Circuit * @param type le type de la cellule * @param value la valeur associée à la cellule */ - public Circuit(CircuitCell type, int value) + public Circuit(Cell type, int value) { this.type = type; this.value = value; @@ -52,7 +93,7 @@ public class Circuit /** * @return le type de la cellule */ - public CircuitCell getType() + public Cell getType() { return type; } @@ -72,7 +113,7 @@ public class Circuit */ public boolean isRoad() { - return type == CircuitCell.ROAD || type == CircuitCell.YROAD; + return type == Cell.ROAD || type == Cell.YROAD; } /** @@ -82,7 +123,7 @@ public class Circuit */ public boolean isStart() { - return type == CircuitCell.START; + return type == Cell.START; } /** @@ -92,6 +133,6 @@ public class Circuit */ public boolean isFinish() { - return type == CircuitCell.FINISH; + return type == Cell.FINISH; } } \ No newline at end of file diff --git a/src/CircuitCell.java b/src/CircuitCell.java deleted file mode 100644 index cf4918f..0000000 --- a/src/CircuitCell.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * CircuitCell est un enum - * représentant les différents types de - * cases qui composent le circuit de - * course. - */ -public enum CircuitCell { - /** - * Case hors piste, non - * praticable par les - * voitures. */ - EMPTY, - - /** - * Case de route normale - * sur laquelle les voitures - * peuvent circuler. - */ - ROAD, - - /** - * Case correspondant à la - * ligne de départ du circuit. - */ - START, - - /** - * Case correspondant à la - * ligne d'arrivée du circuit. - */ - FINISH, - - /** - * Case de route jaune, plus - * d'information sur le - * livrable 2 - */ - YROAD; -} \ No newline at end of file diff --git a/src/Game.java b/src/Game.java index 64519e8..c5ef574 100644 --- a/src/Game.java +++ b/src/Game.java @@ -6,6 +6,8 @@ public class Game private Car[] cars; private Map map; + private ArrayList obs; + public static class Builder { private int pnumber = 3; @@ -57,8 +59,6 @@ public class Game } } - private ArrayList obs; - public Game(int pnumber, Map map, State state) { int loop = map.getPathSize(); @@ -71,6 +71,7 @@ public class Game { Car car = new Car(loop, state); cars[i] = car; + // Observer pour avancer obs.add(car); } diff --git a/src/Main.java b/src/Main.java index c95ad42..1b034ad 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,13 +1,13 @@ public class Main { public static void main(String[] args) throws InterruptedException { - Map m = Map.fromChars(new Character[][] { - {'3', '#', '2'}, - {'#', ' ', 'S'}, - {'9', '#', 'F'}, - }); + // Map m = Map.fromChars(new Character[][] { + // {'3', '#', '2'}, + // {'#', ' ', 'S'}, + // {'9', '#', 'F'}, + // }); Game game = new Game.Builder() - .setMap(m) + .defaultMap() .setPlayers(3) .build(); diff --git a/src/Map.java b/src/Map.java index c0a1411..fb0812f 100644 --- a/src/Map.java +++ b/src/Map.java @@ -6,7 +6,7 @@ import java.util.function.Function; *

Map représente le circuit de course.

*

Cette classe contient:

*
    - *
  • Un tableau 2D de CircuitCell
  • + *
  • Un tableau 2D de Circuit.Cell
  • *
  • Une liste de Points qui représente le chemin pour la voiture entre START et FINISH
  • *
*/ @@ -65,11 +65,11 @@ public class Map public static Map fromInts(Integer[][] map) { return create((i) -> switch (i) { - case 0 -> new Circuit(CircuitCell.EMPTY); - case -1 -> new Circuit(CircuitCell.ROAD); - case -2 -> new Circuit(CircuitCell.START); - case -3 -> new Circuit(CircuitCell.FINISH); - default -> new Circuit(CircuitCell.YROAD, i); + case 0 -> new Circuit(Circuit.Cell.EMPTY); + case -1 -> new Circuit(Circuit.Cell.ROAD); + case -2 -> new Circuit(Circuit.Cell.START); + case -3 -> new Circuit(Circuit.Cell.FINISH); + default -> new Circuit(Circuit.Cell.YROAD, i); }, map); } @@ -89,12 +89,12 @@ public class Map public static Map fromChars(Character[][] map) { return create((i) -> switch (i) { - case '#' -> new Circuit(CircuitCell.ROAD); - case 'S' -> new Circuit(CircuitCell.START); - case 'F' -> new Circuit(CircuitCell.FINISH); + case '#' -> new Circuit(Circuit.Cell.ROAD); + case 'S' -> new Circuit(Circuit.Cell.START); + case 'F' -> new Circuit(Circuit.Cell.FINISH); case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - -> new Circuit(CircuitCell.YROAD, i - '0'); - default -> new Circuit(CircuitCell.EMPTY); + -> new Circuit(Circuit.Cell.YROAD, i - '0'); + default -> new Circuit(Circuit.Cell.EMPTY); }, map); } @@ -152,11 +152,11 @@ public class Map { switch (map[i][j].getType()) { - case CircuitCell.START: + case Circuit.Cell.START: if (start == null) start = new Point(j, i); else return null; break; - case CircuitCell.FINISH: + case Circuit.Cell.FINISH: if (end == null) end = new Point(j, i); else return null; break; @@ -249,13 +249,13 @@ public class Map } /** - * Retourne le type de cellule (CircuitCell) à la position (x, y). + * Retourne le type de cellule (Circuit.Cell) à la position (x, y). * * @param x Coordonnée X * @param y Coordonnée Y - * @return Le type de cellule CircuitCell + * @return Le type de cellule Circuit.Cell */ - public CircuitCell getCell(int x, int y) + public Circuit.Cell getCell(int x, int y) { return getElement(x, y).getType(); }