diff --git a/bin/controller/GameContext.class b/bin/controller/GameContext.class index ff319ea..f92151f 100644 Binary files a/bin/controller/GameContext.class and b/bin/controller/GameContext.class differ diff --git a/bin/controller/GameController.class b/bin/controller/GameController.class index d34f2d1..297bf98 100644 Binary files a/bin/controller/GameController.class and b/bin/controller/GameController.class differ diff --git a/bin/controller/ScoreGameContext.class b/bin/controller/ScoreGameContext.class index d6755a3..d120ac0 100644 Binary files a/bin/controller/ScoreGameContext.class and b/bin/controller/ScoreGameContext.class differ diff --git a/bin/model/Pocket.class b/bin/model/Pocket.class index 315513c..c8b39df 100644 Binary files a/bin/model/Pocket.class and b/bin/model/Pocket.class differ diff --git a/bin/model/Tile.class b/bin/model/Tile.class index 96b6852..0dc211d 100644 Binary files a/bin/model/Tile.class and b/bin/model/Tile.class differ diff --git a/bin/view/HexagonTile$1.class b/bin/view/HexagonTile$1.class index f9a859f..8b9e3b6 100644 Binary files a/bin/view/HexagonTile$1.class and b/bin/view/HexagonTile$1.class differ diff --git a/bin/view/HexagonTile.class b/bin/view/HexagonTile.class index b8009f4..bf0bc95 100644 Binary files a/bin/view/HexagonTile.class and b/bin/view/HexagonTile.class differ diff --git a/src/main/java/controller/GameContext.java b/src/main/java/controller/GameContext.java index 722771d..4c0dafe 100644 --- a/src/main/java/controller/GameContext.java +++ b/src/main/java/controller/GameContext.java @@ -4,8 +4,10 @@ import view.HexagonTile; import java.awt.Point; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.ArrayList; import javax.swing.JPanel; /** @@ -46,7 +48,6 @@ public class GameContext { return availablePositions; } - /** * Récupère l'offset actuel de la vue. * @@ -66,7 +67,6 @@ public class GameContext { offset.translate(deltaX, deltaY); } - /** * Recalcule et applique la position de chaque tuile hexagonale en fonction de l'offset de vue. * Actualise l'interface graphique en ajustant les positions des tuiles et en repeignant le panneau. @@ -78,23 +78,45 @@ public class GameContext { Point position = entry.getKey(); HexagonTile tile = entry.getValue(); - // Calcule la position avec l'offset - int xOffset = position.x * (int) (50 * 3 / 2); // Ajuste la distance horizontale - int yOffset = position.y * (int) (Math.sqrt(3) * 50); // Ajuste la distance verticale + int xOffset = position.x * (int) (50 * 3 / 2); + int yOffset = position.y * (int) (Math.sqrt(3) * 50); - // Si la colonne est impaire, décale la tuile d'une demi-hauteur d'hexagone if (position.x % 2 != 0) { yOffset += (int) (Math.sqrt(3) * 50 / 2); } - // Applique l'offset de vue xOffset += offset.x; yOffset += offset.y; - // Met à jour la position de l'hexagone tile.setBounds(xOffset, yOffset, 50, 50); } gridPanel.revalidate(); gridPanel.repaint(); } + + /** + * Retourne les positions adjacentes à une position donnée dans la grille hexagonale. + * + * @param position La position centrale pour laquelle obtenir les positions adjacentes. + * @return Une liste de positions adjacentes à la position spécifiée. + */ + public List<Point> getAdjacentPositions(Point position) { + List<Point> adjacentPositions = new ArrayList<>(); + if (position.x % 2 == 0) { + adjacentPositions.add(new Point(position.x + 1, position.y)); + adjacentPositions.add(new Point(position.x - 1, position.y)); + adjacentPositions.add(new Point(position.x, position.y + 1)); + adjacentPositions.add(new Point(position.x, position.y - 1)); + adjacentPositions.add(new Point(position.x + 1, position.y - 1)); + adjacentPositions.add(new Point(position.x - 1, position.y - 1)); + } else { + adjacentPositions.add(new Point(position.x + 1, position.y)); + adjacentPositions.add(new Point(position.x - 1, position.y)); + adjacentPositions.add(new Point(position.x, position.y + 1)); + adjacentPositions.add(new Point(position.x, position.y - 1)); + adjacentPositions.add(new Point(position.x + 1, position.y + 1)); + adjacentPositions.add(new Point(position.x - 1, position.y + 1)); + } + return adjacentPositions; + } } diff --git a/src/main/java/controller/GameController.java b/src/main/java/controller/GameController.java index 2a9b385..785a690 100644 --- a/src/main/java/controller/GameController.java +++ b/src/main/java/controller/GameController.java @@ -11,11 +11,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -/** - * La classe GameController gère le flux de jeu et la logique principale, y compris le placement de tuiles, - * la mise à jour de la grille et le calcul du score. Elle prend en charge l'initialisation du jeu, - * la génération de tuiles et la gestion de la fin de la partie. - */ public class GameController implements TilePlacer { private Map<Point, HexagonTile> hexagonMap; private Set<Point> availablePositions; @@ -32,7 +27,6 @@ public class GameController implements TilePlacer { private int seriesId; private GameEndListener gameEndListener; - /** * Constructeur de la classe GameController. * Initialise les composants de la partie, y compris le contexte de jeu, la série de tuiles, @@ -61,24 +55,12 @@ public class GameController implements TilePlacer { updatePreview(); } - - /** - * Charge une série de tuiles spécifiée par l'identifiant de série. - * - * @param idSeries l'identifiant de la série à charger - */ public void loadSeries(int idSeries) { currentTiles = dbManager.getTilesBySeries(idSeries); tileIndex = 0; System.out.println("Série " + idSeries + " chargée avec " + currentTiles.size() + " tuiles."); } - - /** - * Place une tuile à la position spécifiée dans la grille, si la position est disponible. - * - * @param position la position de la grille pour placer la tuile - */ @Override public void placeTile(Point position) { if (availablePositions.contains(position)) { @@ -88,7 +70,6 @@ public class GameController implements TilePlacer { return; } - // Placer la tuile actuelle hexTile.setTile(nextTile); gridPanel.revalidate(); gridPanel.repaint(); @@ -103,40 +84,29 @@ public class GameController implements TilePlacer { } gameContext.repaintGrid(gridPanel); + + // Calculer les scores et mettre à jour la visualisation des poches scoreGameContext.calculateScore(); - // Incrémenter le nombre de tuiles placées et vérifier si la limite est atteinte placedTileCount++; if (placedTileCount > 48) { - endGame(); // Terminer la partie si on a atteint la 50ᵉ tuile pile - return; // Arrêter ici pour éviter de générer une tuile vide + endGame(); + return; } - // Générer la prochaine tuile si la partie n'est pas terminée generateNextTile(); } } - /** - * Termine la partie, enregistre le score final et notifie le listener de fin de partie. - */ private void endGame() { int finalScore = scoreGameContext.getScore(); - - // Enregistrer le score dans la base de données new SendScore().insertscore(seriesId, finalScore); - // Notifiez le listener de la fin de la partie if (gameEndListener != null) { gameEndListener.onGameEnd(finalScore); } } - /** - * Initialise le jeu en plaçant une tuile initiale au centre de la grille et en configurant la vue. - * - * @param cameraController le contrôleur de caméra pour gérer les déplacements de vue - */ public void initializeGame(CameraController cameraController) { generateNextTile(); Tile initialTile = getNextTile(); @@ -153,13 +123,6 @@ public class GameController implements TilePlacer { generateNextTile(); } - /** - * Place la tuile initiale dans la grille et initialise les positions adjacentes comme disponibles. - * - * @param position la position centrale pour la tuile initiale - * @param cameraController le contrôleur de caméra pour appliquer l'offset de vue - * @param tile la tuile initiale à placer - */ public void placeInitialTile(Point position, CameraController cameraController, Tile tile) { if (tile == null) { System.out.println("Erreur : tuile initiale non définie."); @@ -177,15 +140,6 @@ public class GameController implements TilePlacer { } } - /** - * Ajoute une nouvelle tuile hexagonale à la grille à la position spécifiée. - * - * @param position la position de la tuile dans la grille - * @param panel le panneau contenant la grille - * @param hexSize la taille de l'hexagone - * @param cameraController le contrôleur de caméra pour ajuster la position - * @param tile la tuile à placer ou null pour un espace réservé - */ public void addHexagonTile(Point position, JPanel panel, int hexSize, CameraController cameraController, Tile tile) { if (position == null || panel == null) { System.out.println("Erreur : position ou panel est null"); @@ -220,9 +174,6 @@ public class GameController implements TilePlacer { panel.repaint(); } - /** - * Génère la prochaine tuile de la série et met à jour l'aperçu. - */ public void generateNextTile() { if (tileIndex < currentTiles.size()) { nextTile = currentTiles.get(tileIndex++); @@ -233,9 +184,6 @@ public class GameController implements TilePlacer { } } - /** - * Met à jour l'aperçu de la tuile suivante. - */ private void updatePreview() { if (nextTilePreview != null) { if (nextTile != null) { @@ -247,21 +195,10 @@ public class GameController implements TilePlacer { } } - /** - * Retourne la prochaine tuile à placer. - * - * @return la prochaine tuile ou null si aucune tuile n'est disponible - */ public Tile getNextTile() { return nextTile; } - /** - * Retourne les positions adjacentes à une position donnée dans la grille. - * - * @param position la position centrale - * @return un tableau de positions adjacentes - */ private Point[] getAdjacentPositions(Point position) { if (position.x % 2 == 0) { return new Point[]{ diff --git a/src/main/java/controller/ScoreGameContext.java b/src/main/java/controller/ScoreGameContext.java index 816f66e..b0ae9b7 100644 --- a/src/main/java/controller/ScoreGameContext.java +++ b/src/main/java/controller/ScoreGameContext.java @@ -7,47 +7,43 @@ import view.HexagonTile; import javax.swing.*; import java.awt.Point; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * La classe ScoreGameContext gère le calcul et l'affichage du score dans le jeu. - * Elle crée des "Pockets" basées sur les tuiles placées et leurs types de terrain, + * Elle crée des "Pockets" basées sur les tuiles placées et leurs types de terrain, * et calcule le score total en fonction de la taille de chaque Pocket. */ public class ScoreGameContext { private GameContext gameContext; private int score; private JLabel scoreLabel; - private Map<Point, Pocket> pocketMap; // Map des Pockets pour chaque tuile - private Set<Pocket> pockets; // Ensemble de toutes les Pockets + private Map<Point, Pocket> pocketMap; // Map des Pockets pour chaque position de tuile + private Map<TerrainType, List<Pocket>> pocketsByTerrainType; // Ensemble de toutes les poches par type de terrain /** * Constructeur pour ScoreGameContext. * * @param gameContext le contexte du jeu qui contient l'état de la grille - * @param scoreLabel le JLabel pour afficher le score + * @param scoreLabel le JLabel pour afficher le score */ public ScoreGameContext(GameContext gameContext, JLabel scoreLabel) { this.gameContext = gameContext; this.scoreLabel = scoreLabel; this.pocketMap = new HashMap<>(); - this.pockets = new HashSet<>(); + this.pocketsByTerrainType = new HashMap<>(); this.score = 0; } /** - * Méthode principale pour recalculer le score en reconstruisant toutes les Pockets. - * Elle parcourt les tuiles dans la grille et crée des Pockets par type de terrain. + * Méthode principale pour recalculer le score en reconstruisant toutes les poches. + * Elle parcourt les tuiles dans la grille et crée des poches par type de terrain. */ public void calculateScore() { score = 0; - pockets.clear(); - pocketMap.clear(); + pocketsByTerrainType.clear(); - // Parcourt chaque tuile dans la grille pour créer des Pockets par type de terrain + // Parcourt chaque tuile dans la grille pour créer des poches par type de terrain for (Map.Entry<Point, HexagonTile> entry : gameContext.getHexagonMap().entrySet()) { Point position = entry.getKey(); HexagonTile hexTile = entry.getValue(); @@ -55,122 +51,69 @@ public class ScoreGameContext { if (hexTile.isFilled()) { Tile tile = hexTile.getTile(); - // Crée ou fusionne une Pocket pour chaque type de terrain de la tuile - for (int segment = 0; segment < 6; segment++) { - TerrainType terrainType = tile.getTerrainForSegment(segment); - if (terrainType != null) { - Pocket pocket = findOrCreatePocket(position, segment, terrainType); - pocketMap.put(position, pocket); - } + // Crée des poches pour chaque type de terrain de la tuile + addTileToPockets(tile.getTerrain(0), position); // Premier terrain + if (tile.hasTwoTerrains()) { // Deuxième terrain si disponible + addTileToPockets(tile.getTerrain(1), position); } } } - // Calcule le score total en additionnant le score de chaque Pocket - System.out.println("Pockets and their sizes:"); - for (Pocket pocket : pockets) { - System.out.println("Pocket with terrain " + pocket.getTerrainType() + " has size " + pocket.getSize()); - score += pocket.calculateScore(); + // Calcule le score total en additionnant le score de chaque poche + System.out.println("Poches et leurs tailles:"); + for (List<Pocket> pockets : pocketsByTerrainType.values()) { + for (Pocket pocket : pockets) { + int pocketSize = pocket.getSize(); + score += pocket.calculateScore(); + System.out.println("Poche de taille " + pocketSize + " ajoutant " + pocket.calculateScore() + " points au score."); + } } updateScoreDisplay(); } /** - * Recherche ou crée une Pocket pour un terrain spécifique dans une tuile. + * Ajoute une tuile à une poche de terrains en regroupant les tuiles adjacentes. + * Si des poches existent autour, fusionne ces poches. * - * @param position la position de la tuile - * @param segment le segment de la tuile - * @param terrainType le type de terrain de la tuile - * @return la Pocket correspondante, soit une Pocket existante fusionnée, soit une nouvelle Pocket + * @param terrainType Le type de terrain de la tuile. + * @param position La position de la tuile. */ - private Pocket findOrCreatePocket(Point position, int segment, TerrainType terrainType) { - Pocket newPocket = new Pocket(terrainType); - newPocket.addTile(position); + private void addTileToPockets(TerrainType terrainType, Point position) { + List<Pocket> pockets = pocketsByTerrainType.computeIfAbsent(terrainType, k -> new ArrayList<>()); + Pocket foundPocket = null; + List<Pocket> pocketsToMerge = new ArrayList<>(); - // Vérifie les voisins pour fusionner les Pockets si les segments se touchent - for (int adjSegment = 0; adjSegment < 6; adjSegment++) { - Point neighborPos = getAdjacentPositionForSegment(position, adjSegment); - Pocket neighborPocket = pocketMap.get(neighborPos); - - if (neighborPocket != null && neighborPocket.getTerrainType() == terrainType) { - // Vérifie si les segments de terrain se touchent avant de fusionner les Pockets - if (areSegmentsConnected(position, neighborPos, segment, adjSegment, terrainType)) { - System.out.println("Merging pocket at " + position + " with pocket at " + neighborPos + " for terrain " + terrainType); - neighborPocket.merge(newPocket); - pockets.remove(newPocket); // Supprime la Pocket fusionnée - return neighborPocket; // Retourne la Pocket fusionnée + for (Pocket pocket : pockets) { + for (Point adj : gameContext.getAdjacentPositions(position)) { + if (pocket.containsTile(adj)) { + if (foundPocket == null) { + foundPocket = pocket; + foundPocket.addTile(position); + } else { + foundPocket.merge(pocket); + pocketsToMerge.add(pocket); + } + break; } } } - System.out.println("New pocket created at " + position + " for terrain " + terrainType); - pockets.add(newPocket); // Ajoute la nouvelle Pocket si aucune fusion n'a eu lieu - return newPocket; - } - - /** - * Vérifie si les segments de deux tuiles se touchent et partagent le même type de terrain. - * - * @param position1 la première position de tuile - * @param position2 la seconde position de tuile - * @param segment1 le segment de la première tuile - * @param segment2 le segment de la seconde tuile - * @param terrainType le type de terrain à vérifier - * @return true si les segments sont connectés, false sinon - */ - private boolean areSegmentsConnected(Point position1, Point position2, int segment1, int segment2, TerrainType terrainType) { - Tile tile1 = gameContext.getHexagonMap().get(position1).getTile(); - Tile tile2 = gameContext.getHexagonMap().get(position2).getTile(); - - if (tile1 == null || tile2 == null) return false; - - TerrainType terrainSegment1 = tile1.getTerrainForSegment(segment1); - TerrainType terrainSegment2 = tile2.getTerrainForSegment(segment2); - - boolean connected = terrainSegment1 == terrainType && terrainSegment2 == terrainType; - if (connected) { - System.out.println("Segments connected between " + position1 + " and " + position2 + " for terrain " + terrainType); + if (foundPocket == null) { + Pocket newPocket = new Pocket(gameContext, terrainType); + newPocket.addTile(position); + pockets.add(newPocket); + pocketMap.put(position, newPocket); } - return connected; - } - /** - * Obtient la position adjacente pour un segment spécifique (0 à 5). - * - * @param position la position de la tuile - * @param segment le segment pour lequel on cherche la position adjacente - * @return la position adjacente - */ - private Point getAdjacentPositionForSegment(Point position, int segment) { - if (position.x % 2 == 0) { - switch (segment) { - case 0: return new Point(position.x + 1, position.y); - case 1: return new Point(position.x + 1, position.y - 1); - case 2: return new Point(position.x, position.y - 1); - case 3: return new Point(position.x - 1, position.y - 1); - case 4: return new Point(position.x - 1, position.y); - case 5: return new Point(position.x, position.y + 1); - default: return position; - } - } else { - switch (segment) { - case 0: return new Point(position.x + 1, position.y); - case 1: return new Point(position.x + 1, position.y + 1); - case 2: return new Point(position.x, position.y + 1); - case 3: return new Point(position.x - 1, position.y + 1); - case 4: return new Point(position.x - 1, position.y); - case 5: return new Point(position.x, position.y - 1); - default: return position; - } - } + pockets.removeAll(pocketsToMerge); } /** * Met à jour l'affichage du score dans GameView. */ private void updateScoreDisplay() { - System.out.println("Updated Score: " + score); // Débogage du score + System.out.println("Score mis à jour : " + score); scoreLabel.setText("Score: " + score); } diff --git a/src/main/java/model/Pocket.java b/src/main/java/model/Pocket.java index 1eff0e8..e6425c3 100644 --- a/src/main/java/model/Pocket.java +++ b/src/main/java/model/Pocket.java @@ -1,82 +1,95 @@ -// src/main/java/model/Pocket.java package model; +import controller.GameContext; +import view.HexagonTile; +import java.awt.Color; import java.awt.Point; import java.util.HashSet; import java.util.Set; -/** - * La classe <code>Pocket</code> représente un groupe de tuiles adjacentes - * d'un même type de terrain dans le jeu. - */ public class Pocket { - private TerrainType terrainType; // Type de terrain de cette Pocket - private Set<Point> tiles; // Ensemble des positions des tuiles de la Pocket + private GameContext gameContext; + private Set<Point> tilePositions; // Ensemble des positions des tuiles dans cette poche + private TerrainType terrainType; // Type de terrain de cette poche /** - * Constructeur de la classe <code>Pocket</code>. + * Constructeur de la classe Pocket. * - * @param terrainType Le type de terrain associé à cette Pocket. + * @param gameContext le contexte de jeu pour accéder aux tuiles + * @param terrainType le type de terrain de cette poche */ - public Pocket(TerrainType terrainType) { + public Pocket(GameContext gameContext, TerrainType terrainType) { + this.gameContext = gameContext; this.terrainType = terrainType; - this.tiles = new HashSet<>(); + this.tilePositions = new HashSet<>(); } /** - * Récupère le type de terrain de cette Pocket. + * Ajoute une tuile à la poche. * - * @return Le type de terrain de cette Pocket. + * @param position la position de la tuile dans la grille + */ + public void addTile(Point position) { + tilePositions.add(position); + } + + /** + * Vérifie si la poche contient une tuile à la position donnée. + * + * @param position la position de la tuile à vérifier + * @return true si la tuile est dans la poche, false sinon + */ + public boolean containsTile(Point position) { + return tilePositions.contains(position); + } + + /** + * Récupère le type de terrain de cette poche. + * + * @return le type de terrain de la poche */ public TerrainType getTerrainType() { return terrainType; } /** - * Obtient la taille de cette Pocket, c'est-à-dire le nombre de tuiles. + * Calcule la taille de la poche en fonction du nombre de tuiles qu'elle contient. * - * @return La taille de la Pocket. + * @return la taille de la poche */ public int getSize() { - return tiles.size(); + return tilePositions.size(); } /** - * Ajoute une tuile à cette Pocket à une position donnée. + * Calcule le score de la poche en fonction de sa taille. + * La règle est que le score est la taille de la poche au carré. * - * @param position La position de la tuile à ajouter. - */ - public void addTile(Point position) { - tiles.add(position); - } - - /** - * Vérifie si une tuile à une position donnée est présente dans cette Pocket. - * - * @param position La position de la tuile à vérifier. - * @return <code>true</code> si la tuile est présente, sinon <code>false</code>. - */ - public boolean containsTile(Point position) { - return tiles.contains(position); - } - - /** - * Fusionne cette Pocket avec une autre Pocket si elles partagent le même type de terrain. - * - * @param other La Pocket à fusionner. - */ - public void merge(Pocket other) { - if (this.terrainType == other.terrainType) { - this.tiles.addAll(other.tiles); - } - } - - /** - * Calcule le score de cette Pocket basé sur la taille au carré. - * - * @return Le score de la Pocket. + * @return le score de la poche */ public int calculateScore() { - return getSize() * getSize(); // La taille au carré donne le score + return (int) Math.pow(getSize(), 2); + } + + /** + * Fusionne cette poche avec une autre poche en ajoutant toutes ses tuiles. + * + * @param otherPocket la poche à fusionner avec celle-ci + */ + public void merge(Pocket otherPocket) { + tilePositions.addAll(otherPocket.tilePositions); + } + + /** + * Applique une couleur de contraste pour visualiser cette poche sur l'interface. + */ + public void applyContrastColor() { + Color contrastColor = new Color(255, 255, 255, 128); // Couleur semi-transparente pour visualiser + for (Point position : tilePositions) { + HexagonTile tile = gameContext.getHexagonMap().get(position); + if (tile != null) { + tile.setContrastColor(contrastColor); + } + } } } diff --git a/src/main/java/model/Tile.java b/src/main/java/model/Tile.java index 703e0d6..ae554f5 100644 --- a/src/main/java/model/Tile.java +++ b/src/main/java/model/Tile.java @@ -1,50 +1,25 @@ -// src/main/java/model/Tile.java package model; -/** - * La classe <code>Tile</code> représente une tuile dans le jeu, qui peut contenir un ou deux types de terrains. - * Chaque tuile a un identifiant unique, un tableau de types de terrains, et gère sa rotation. - */ public class Tile { - private int id; // ID de la tuile - private TerrainType[] terrains; // Tableau contenant deux types de terrains (ex. MER, FORET) - private int segmentsForTerrain1; // Nombre de segments pour le premier terrain - private int rotation; // Rotation de la tuile (en multiple de 60 degrés) + private int id; + private TerrainType[] terrains; + private int segmentsForTerrain1; + private int rotation; - /** - * Constructeur pour créer une nouvelle tuile avec deux types de terrains. - * - * @param id L'identifiant de la tuile. - * @param terrain1 Le premier type de terrain. - * @param terrain2 Le deuxième type de terrain. - * @param segmentsForTerrain1 Le nombre de segments pour le premier terrain. - */ public Tile(int id, TerrainType terrain1, TerrainType terrain2, int segmentsForTerrain1) { this.id = id; this.terrains = new TerrainType[]{terrain1, terrain2}; this.segmentsForTerrain1 = segmentsForTerrain1; - this.rotation = 0; // Initialisation de la rotation à 0 + this.rotation = 0; } - /** - * Renvoie le terrain pour l'index donné (0 ou 1). - * - * @param index L'index du terrain à récupérer. - * @return Le type de terrain à l'index spécifié, ou null si l'index est invalide. - */ public TerrainType getTerrain(int index) { if (index >= 0 && index < terrains.length) { return terrains[index]; } - return null; // Retourne null si l'index est invalide + return null; } - /** - * Méthode pour obtenir le terrain associé à un segment spécifique (prend en compte la rotation). - * - * @param segmentIndex L'index du segment. - * @return Le type de terrain associé au segment spécifié. - */ public TerrainType getTerrainForSegment(int segmentIndex) { int adjustedIndex = (segmentIndex - rotation + 6) % 6; if (adjustedIndex < segmentsForTerrain1) { @@ -54,35 +29,28 @@ public class Tile { } } - /** - * Fait tourner la tuile dans le sens horaire. - */ public void rotateClockwise() { rotation = (rotation + 1) % 6; } - /** - * Fait tourner la tuile dans le sens antihoraire. - */ public void rotateCounterClockwise() { - rotation = (rotation + 5) % 6; // Tourner dans le sens inverse + rotation = (rotation + 5) % 6; } - /** - * Renvoie la rotation actuelle de la tuile. - * - * @return La rotation de la tuile en multiples de 60 degrés. - */ public int getRotation() { return rotation; } - /** - * Renvoie l'identifiant de la tuile. - * - * @return L'identifiant de la tuile. - */ public int getId() { return id; } + + /** + * Vérifie si la tuile a deux terrains différents. + * + * @return true si la tuile a deux terrains, sinon false. + */ + public boolean hasTwoTerrains() { + return terrains[1] != null; + } } diff --git a/src/main/java/view/HexagonTile.java b/src/main/java/view/HexagonTile.java index fd16f47..8c19415 100644 --- a/src/main/java/view/HexagonTile.java +++ b/src/main/java/view/HexagonTile.java @@ -7,78 +7,44 @@ import javax.swing.*; import java.awt.*; import java.awt.geom.Path2D; -/** - * La classe <code>HexagonTile</code> représente une tuile hexagonale dans le jeu. - * Elle gère l'affichage d'une tuile avec ses segments de terrain et - * indique si la tuile est un placeholder. - */ public class HexagonTile extends JPanel { - /** La tuile associée à cet hexagone. */ private Tile tile; - - /** La position de l'hexagone sur la grille. */ private Point position; - - /** Indicateur si l'hexagone est un placeholder. */ private boolean isPlaceholder; + private Color contrastColor; // Nouvelle couleur pour le contraste visuel des poches - /** - * Constructeur de la classe <code>HexagonTile</code>. - * - * @param position La position de l'hexagone sur la grille. - * @param isPlaceholder Indique si cet hexagone est un placeholder. - */ public HexagonTile(Point position, boolean isPlaceholder) { this.position = position; this.isPlaceholder = isPlaceholder; this.tile = null; + this.contrastColor = null; // Par défaut, pas de contraste setPreferredSize(new Dimension(100, 100)); } - /** - * Récupère la position de l'hexagone. - * - * @return La position de l'hexagone. - */ public Point getPosition() { return position; } - /** - * Définit la tuile associée à cet hexagone. - * - * @param tile La tuile à associer. - */ public void setTile(Tile tile) { this.tile = tile; - this.isPlaceholder = false; // Une fois la tuile posée, ce n'est plus un placeholder + this.isPlaceholder = false; repaint(); } - /** - * Récupère la tuile associée à cet hexagone. - * - * @return La tuile associée. - */ public Tile getTile() { return tile; } - /** - * Vérifie si l'hexagone est rempli avec une tuile. - * - * @return <code>true</code> si l'hexagone contient une tuile, sinon <code>false</code>. - */ public boolean isFilled() { return this.tile != null; } - /** - * Méthode de peinture du composant. - * Dessine l'hexagone et ses segments de terrain, ou un placeholder si aucun terrain n'est présent. - * - * @param g Le contexte graphique dans lequel dessiner. - */ + // Nouvelle méthode pour définir la couleur de contraste + public void setContrastColor(Color color) { + this.contrastColor = color; + repaint(); + } + @Override protected void paintComponent(Graphics g) { super.paintComponent(g); @@ -86,7 +52,7 @@ public class HexagonTile extends JPanel { int centerX = getWidth() / 2; int centerY = getHeight() / 2; - int largeRadius = isPlaceholder ? 40 : 50; // Réduction de taille pour les placeholders + int largeRadius = isPlaceholder ? 40 : 50; Shape largeHexagon = createHexagon(centerX, centerY, largeRadius); g2d.setClip(largeHexagon); @@ -102,33 +68,22 @@ public class HexagonTile extends JPanel { g2d.setColor(Color.BLACK); g2d.setStroke(new BasicStroke(3)); g2d.draw(largeHexagon); + + // Appliquer la couleur contrastée si elle est définie + if (contrastColor != null) { + g2d.setColor(new Color(contrastColor.getRGB() & 0xFFFFFF | 0x66000000, true)); + g2d.fill(largeHexagon); + } } - /** - * Dessine les segments de terrain associés à la tuile. - * - * @param g2d Le contexte graphique dans lequel dessiner. - * @param centerX La coordonnée X du centre de l'hexagone. - * @param centerY La coordonnée Y du centre de l'hexagone. - * @param radius Le rayon de l'hexagone. - */ private void drawTerrainSegments(Graphics2D g2d, int centerX, int centerY, int radius) { - // Parcourt les segments de 0 à 5 pour dessiner chaque segment en fonction du terrain associé for (int i = 0; i < 6; i++) { - TerrainType terrain = tile.getTerrainForSegment(i); // Récupère le terrain du segment, en prenant en compte la rotation + TerrainType terrain = tile.getTerrainForSegment(i); g2d.setColor(getTerrainColor(terrain)); g2d.fillArc(centerX - radius, centerY - radius, 2 * radius, 2 * radius, 60 * i, 60); } } - /** - * Crée un hexagone à partir des coordonnées centrales et du rayon. - * - * @param centerX La coordonnée X du centre de l'hexagone. - * @param centerY La coordonnée Y du centre de l'hexagone. - * @param radius Le rayon de l'hexagone. - * @return La forme hexagonale créée. - */ private Shape createHexagon(int centerX, int centerY, int radius) { Path2D hexagon = new Path2D.Double(); for (int i = 0; i < 6; i++) { @@ -145,12 +100,6 @@ public class HexagonTile extends JPanel { return hexagon; } - /** - * Récupère la couleur associée à un type de terrain. - * - * @param terrain Le type de terrain à évaluer. - * @return La couleur correspondant au type de terrain. - */ private Color getTerrainColor(TerrainType terrain) { if (terrain == null) { return Color.WHITE;