Fix des scores

This commit is contained in:
Vincent 2024-10-27 23:07:11 +01:00
parent 68e99b9cfc
commit b68751ce2c
13 changed files with 177 additions and 345 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -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;
}
}

@ -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[]{

@ -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);
}

@ -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);
}
}
}
}

@ -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;
}
}

@ -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;