Compare commits
13 Commits
Plateau
...
b97b9cef69
| Author | SHA1 | Date | |
|---|---|---|---|
| b97b9cef69 | |||
| 25f8dcdc76 | |||
| 823b0fcae0 | |||
| 9f78dad6e5 | |||
| 830729ca21 | |||
| d95d52785e | |||
| ddf9b00c0a | |||
| c1e5de9ed2 | |||
| 1921b523c6 | |||
| d23aeb266f | |||
|
|
7db1583766 | ||
|
|
8ccd0229b0 | ||
| 32217b8e39 |
25
Makefile
25
Makefile
@@ -2,6 +2,10 @@
|
|||||||
SRC_DIR = fr
|
SRC_DIR = fr
|
||||||
BIN_DIR = bin
|
BIN_DIR = bin
|
||||||
|
|
||||||
|
# === Répertoires des ressources ===
|
||||||
|
RES_SRC = fr/iut_fbleau/Res
|
||||||
|
RES_BIN = bin/fr/iut_fbleau/Res
|
||||||
|
|
||||||
# === Recherche automatique des fichiers .java dans tous les sous-dossiers ===
|
# === Recherche automatique des fichiers .java dans tous les sous-dossiers ===
|
||||||
SOURCES := $(shell find $(SRC_DIR) -name "*.java")
|
SOURCES := $(shell find $(SRC_DIR) -name "*.java")
|
||||||
|
|
||||||
@@ -19,11 +23,20 @@ JAVAFLAGS = -cp $(BIN_DIR)
|
|||||||
all: build
|
all: build
|
||||||
|
|
||||||
# === Compilation ===
|
# === Compilation ===
|
||||||
build:
|
build: compile resources
|
||||||
|
@echo "✔ Compilation terminée."
|
||||||
|
|
||||||
|
compile:
|
||||||
@echo "===> Compilation du projet Avalam..."
|
@echo "===> Compilation du projet Avalam..."
|
||||||
@mkdir -p $(BIN_DIR)
|
@mkdir -p $(BIN_DIR)
|
||||||
@$(JC) $(JCFLAGS) $(SOURCES)
|
@$(JC) $(JCFLAGS) $(SOURCES)
|
||||||
@echo "✔ Compilation terminée."
|
|
||||||
|
# === Copie des ressources (.txt) dans bin ===
|
||||||
|
resources:
|
||||||
|
@echo "===> Copie des ressources..."
|
||||||
|
@mkdir -p $(RES_BIN)
|
||||||
|
@cp $(RES_SRC)/* $(RES_BIN)/
|
||||||
|
@echo "✔ Ressources copiées."
|
||||||
|
|
||||||
# === Exécution ===
|
# === Exécution ===
|
||||||
run:
|
run:
|
||||||
@@ -38,3 +51,11 @@ clean:
|
|||||||
|
|
||||||
# === Recompile + run ===
|
# === Recompile + run ===
|
||||||
re: clean build run
|
re: clean build run
|
||||||
|
|
||||||
|
# === Génération de la Javadoc ===
|
||||||
|
DOC_DIR = doc
|
||||||
|
javadoc:
|
||||||
|
@echo "===> Génération de la Javadoc..."
|
||||||
|
@mkdir -p $(DOC_DIR)
|
||||||
|
@javadoc -d $(DOC_DIR) -sourcepath $(SRC_DIR) -subpackages fr.iut_fbleau.Avalam
|
||||||
|
@echo "✔ Javadoc générée dans $(DOC_DIR)/"
|
||||||
|
|||||||
64
README.md
64
README.md
@@ -10,6 +10,70 @@ Dans un second temps, on fera des bots le plus efficace possible (probablement u
|
|||||||
|
|
||||||
Le jeu de notre groupe est **Avalam**.
|
Le jeu de notre groupe est **Avalam**.
|
||||||
|
|
||||||
|
## Compilation et exécution
|
||||||
|
|
||||||
|
### Compilation
|
||||||
|
```bash
|
||||||
|
make build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exécution
|
||||||
|
```bash
|
||||||
|
make run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nettoyage
|
||||||
|
```bash
|
||||||
|
make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
### Recompiler et exécuter
|
||||||
|
```bash
|
||||||
|
make re
|
||||||
|
```
|
||||||
|
|
||||||
|
### Générer la Javadoc
|
||||||
|
```bash
|
||||||
|
make javadoc
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture du projet
|
||||||
|
|
||||||
|
### Structure des classes principales
|
||||||
|
|
||||||
|
- **`AvalamBoard`** : Implémentation du plateau de jeu conforme à l'API `AbstractBoard`
|
||||||
|
- Gère l'état du plateau (grille 9x9)
|
||||||
|
- Valide les règles d'Avalam
|
||||||
|
- Applique et annule les coups
|
||||||
|
- Détecte la fin de partie et calcule le résultat
|
||||||
|
|
||||||
|
- **`AvalamPly`** : Représente un coup dans le jeu
|
||||||
|
- Stocke les coordonnées de départ et d'arrivée
|
||||||
|
- Stocke la hauteur de la tour source (pour l'annulation)
|
||||||
|
|
||||||
|
- **`Tower`** : Représente une tour de pions
|
||||||
|
- Stocke la couleur du sommet et la hauteur
|
||||||
|
|
||||||
|
- **`Color`** : Énumération des couleurs des joueurs
|
||||||
|
- COLOR1 (Jaune) et COLOR2 (Rouge)
|
||||||
|
|
||||||
|
### Logique du jeu
|
||||||
|
|
||||||
|
Le plateau est représenté par une grille 9x9 où chaque case contient :
|
||||||
|
- `null` : case vide (trou)
|
||||||
|
- `ArrayList<Integer>` : tour de pions (chaque Integer = 1 pour PLAYER1, 2 pour PLAYER2)
|
||||||
|
|
||||||
|
### Règles implémentées
|
||||||
|
|
||||||
|
- ✅ Validation des limites du plateau
|
||||||
|
- ✅ Vérification que la case source n'est pas vide
|
||||||
|
- ✅ Vérification que la case destination n'est pas vide (pas de trou)
|
||||||
|
- ✅ Vérification que la destination est voisine (horizontal, vertical ou diagonal)
|
||||||
|
- ✅ Vérification que la hauteur totale après déplacement ≤ 5
|
||||||
|
- ✅ Déplacement de toute la pile (pas partiel)
|
||||||
|
- ✅ Détection de fin de partie (plus aucun coup possible)
|
||||||
|
- ✅ Calcul du résultat (nombre de tours possédées par chaque joueur)
|
||||||
|
|
||||||
## Présentation [Avalam](https://escaleajeux.fr/?principal=/jeu/avaxl?)
|
## Présentation [Avalam](https://escaleajeux.fr/?principal=/jeu/avaxl?)
|
||||||
|
|
||||||
Sur un plateau de jeu, les joueurs disposent de 24 pions chacun. Le but est de créer de petites tours avec son pion de couleur au-dessus. Pour ce faire, chaque joueur déplace son pion sur une tour ou déplace une tour sur un autre pion. La personne ayant le plus de pions sur le dessus des tours gagne.
|
Sur un plateau de jeu, les joueurs disposent de 24 pions chacun. Le but est de créer de petites tours avec son pion de couleur au-dessus. Pour ce faire, chaque joueur déplace son pion sur une tour ou déplace une tour sur un autre pion. La personne ayant le plus de pions sur le dessus des tours gagne.
|
||||||
|
|||||||
291
fr/iut_fbleau/Avalam/AvalamBoard.java
Normal file
291
fr/iut_fbleau/Avalam/AvalamBoard.java
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.GameAPI.AbstractBoard;
|
||||||
|
import fr.iut_fbleau.GameAPI.AbstractPly;
|
||||||
|
import fr.iut_fbleau.GameAPI.IBoard;
|
||||||
|
import fr.iut_fbleau.GameAPI.Player;
|
||||||
|
import fr.iut_fbleau.GameAPI.Result;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>AvalamBoard</code>
|
||||||
|
*
|
||||||
|
* Représente le plateau et les règles du jeu Avalam.
|
||||||
|
* Cette classe étend <code>AbstractBoard</code> (GameAPI) et fournit :
|
||||||
|
* - la génération des coups (iterator)
|
||||||
|
* - le test de légalité (isLegal)
|
||||||
|
* - l’application d’un coup (doPly)
|
||||||
|
* - la détection de fin de partie (isGameOver)
|
||||||
|
* - le calcul du résultat (getResult)
|
||||||
|
*/
|
||||||
|
public class AvalamBoard extends AbstractBoard {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Taille du plateau Avalam (9x9). */
|
||||||
|
public static final int SIZE = 9;
|
||||||
|
|
||||||
|
/** Hauteur maximale autorisée pour une tour après fusion. */
|
||||||
|
private static final int MAX_HEIGHT = 5;
|
||||||
|
|
||||||
|
/** Grille du plateau : chaque case contient une tour (Tower) ou null si vide. */
|
||||||
|
private final Tower[][] grid;
|
||||||
|
|
||||||
|
/** Indique si la partie est terminée (mémoïsation). */
|
||||||
|
private boolean gameOver = false;
|
||||||
|
|
||||||
|
/** Résultat de la partie si elle est terminée (mémoïsation). */
|
||||||
|
private Result result = null;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit un plateau Avalam à partir d’une grille initiale et d’un joueur qui commence.
|
||||||
|
*
|
||||||
|
* @param initialGrid grille initiale (Tower ou null)
|
||||||
|
* @param startingPlayer joueur qui commence (PLAYER1 ou PLAYER2)
|
||||||
|
*/
|
||||||
|
public AvalamBoard(Tower[][] initialGrid, Player startingPlayer) {
|
||||||
|
super(startingPlayer, new ArrayDeque<>());
|
||||||
|
this.grid = new Tower[SIZE][SIZE];
|
||||||
|
|
||||||
|
for (int r = 0; r < SIZE; r++)
|
||||||
|
for (int c = 0; c < SIZE; c++)
|
||||||
|
this.grid[r][c] = initialGrid[r][c];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit un plateau Avalam à partir d’une grille initiale.
|
||||||
|
* Par défaut, PLAYER1 commence.
|
||||||
|
*
|
||||||
|
* @param initialGrid grille initiale (Tower ou null)
|
||||||
|
*/
|
||||||
|
public AvalamBoard(Tower[][] initialGrid) {
|
||||||
|
this(initialGrid, Player.PLAYER1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructeur interne utilisé par safeCopy().
|
||||||
|
*
|
||||||
|
* @param grid grille à réutiliser
|
||||||
|
* @param current joueur courant
|
||||||
|
* @param gameOver état “partie terminée”
|
||||||
|
* @param result résultat mémorisé
|
||||||
|
*/
|
||||||
|
private AvalamBoard(Tower[][] grid, Player current, boolean gameOver, Result result) {
|
||||||
|
super(current, new ArrayDeque<>());
|
||||||
|
this.grid = grid;
|
||||||
|
this.gameOver = gameOver;
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la tour située à la position (row, col), ou null si hors bornes ou vide.
|
||||||
|
*
|
||||||
|
* @param row ligne
|
||||||
|
* @param col colonne
|
||||||
|
* @return tour présente ou null
|
||||||
|
*/
|
||||||
|
public Tower getTowerAt(int row, int col) {
|
||||||
|
return inBounds(row, col) ? grid[row][col] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teste si une position est à l’intérieur du plateau.
|
||||||
|
*
|
||||||
|
* @param r ligne
|
||||||
|
* @param c colonne
|
||||||
|
* @return true si (r,c) est dans [0..SIZE-1]
|
||||||
|
*/
|
||||||
|
private boolean inBounds(int r, int c) {
|
||||||
|
return r >= 0 && r < SIZE && c >= 0 && c < SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teste si deux cases sont adjacentes (8-voisinage).
|
||||||
|
*
|
||||||
|
* @param r1 ligne source
|
||||||
|
* @param c1 colonne source
|
||||||
|
* @param r2 ligne destination
|
||||||
|
* @param c2 colonne destination
|
||||||
|
* @return true si les cases sont voisines et différentes
|
||||||
|
*/
|
||||||
|
private boolean areAdjacent(int r1, int c1, int r2, int c2) {
|
||||||
|
int dr = Math.abs(r1 - r2);
|
||||||
|
int dc = Math.abs(c1 - c2);
|
||||||
|
return (dr <= 1 && dc <= 1 && !(dr == 0 && dc == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associe un joueur GameAPI à une couleur Avalam.
|
||||||
|
*
|
||||||
|
* @param p joueur (PLAYER1/PLAYER2)
|
||||||
|
* @return couleur correspondante (YELLOW/RED)
|
||||||
|
*/
|
||||||
|
private Color colorForPlayer(Player p) {
|
||||||
|
return (p == Player.PLAYER1 ? Color.YELLOW : Color.RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indique si la partie est terminée.
|
||||||
|
* Ici : fin lorsque l’itérateur de coups légaux ne produit plus aucun coup.
|
||||||
|
*
|
||||||
|
* @return true si aucun coup n’est possible
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isGameOver() {
|
||||||
|
if (gameOver) return true;
|
||||||
|
|
||||||
|
Iterator<AbstractPly> it = iterator();
|
||||||
|
if (it.hasNext()) return false;
|
||||||
|
|
||||||
|
gameOver = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne le résultat si la partie est terminée.
|
||||||
|
* Règle utilisée ici : comparaison du nombre de tours contrôlées par chaque couleur.
|
||||||
|
*
|
||||||
|
* @return WIN / LOSS / DRAW ou null si partie non terminée
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Result getResult() {
|
||||||
|
if (!isGameOver()) return null;
|
||||||
|
if (result != null) return result;
|
||||||
|
|
||||||
|
int yellow = 0;
|
||||||
|
int red = 0;
|
||||||
|
|
||||||
|
for (int r = 0; r < SIZE; r++)
|
||||||
|
for (int c = 0; c < SIZE; c++) {
|
||||||
|
Tower t = grid[r][c];
|
||||||
|
if (t == null) continue;
|
||||||
|
|
||||||
|
if (t.getColor() == Color.YELLOW) yellow++;
|
||||||
|
else if (t.getColor() == Color.RED) red++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yellow > red) result = Result.WIN;
|
||||||
|
else if (yellow < red) result = Result.LOSS;
|
||||||
|
else result = Result.DRAW;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teste si un coup est légal selon les règles implémentées :
|
||||||
|
* - coup de type AvalamPly
|
||||||
|
* - source/destination dans le plateau et différentes
|
||||||
|
* - source et destination non null
|
||||||
|
* - la tour source appartient au joueur courant (couleur du sommet)
|
||||||
|
* - cases adjacentes
|
||||||
|
* - couleurs différentes entre source et destination (règle de ce projet)
|
||||||
|
* - hauteur finale <= MAX_HEIGHT
|
||||||
|
*
|
||||||
|
* @param c coup à tester
|
||||||
|
* @return true si le coup est légal
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isLegal(AbstractPly c) {
|
||||||
|
if (!(c instanceof AvalamPly)) return false;
|
||||||
|
AvalamPly p = (AvalamPly) c;
|
||||||
|
|
||||||
|
int xF = p.getXFrom(), yF = p.getYFrom();
|
||||||
|
int xT = p.getXTo(), yT = p.getYTo();
|
||||||
|
|
||||||
|
if (!inBounds(xF, yF) || !inBounds(xT, yT)) return false;
|
||||||
|
if (xF == xT && yF == yT) return false;
|
||||||
|
|
||||||
|
Tower src = grid[xF][yF];
|
||||||
|
Tower dst = grid[xT][yT];
|
||||||
|
if (src == null || dst == null) return false;
|
||||||
|
|
||||||
|
if (src.getColor() != colorForPlayer(getCurrentPlayer())) return false;
|
||||||
|
if (!areAdjacent(xF, yF, xT, yT)) return false;
|
||||||
|
if (src.getColor() == dst.getColor()) return false;
|
||||||
|
if (src.getHeight() + dst.getHeight() > MAX_HEIGHT) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applique un coup légal :
|
||||||
|
* - fusion de la tour source sur la destination
|
||||||
|
* - la case source devient vide
|
||||||
|
* - passage au joueur suivant via super.doPly
|
||||||
|
*
|
||||||
|
* @param c coup à jouer
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doPly(AbstractPly c) {
|
||||||
|
if (!isLegal(c)) throw new IllegalArgumentException("Coup illégal : " + c);
|
||||||
|
|
||||||
|
AvalamPly p = (AvalamPly) c;
|
||||||
|
|
||||||
|
int xF = p.getXFrom(), yF = p.getYFrom();
|
||||||
|
int xT = p.getXTo(), yT = p.getYTo();
|
||||||
|
|
||||||
|
Tower src = grid[xF][yF];
|
||||||
|
Tower dst = grid[xT][yT];
|
||||||
|
|
||||||
|
dst.mergeTower(src);
|
||||||
|
grid[xF][yF] = null;
|
||||||
|
|
||||||
|
super.doPly(c);
|
||||||
|
|
||||||
|
gameOver = false;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne un itérateur sur tous les coups légaux du joueur courant.
|
||||||
|
* Génération brute : pour chaque case et chaque voisin (8 directions), on teste isLegal().
|
||||||
|
*
|
||||||
|
* @return itérateur de coups possibles (AbstractPly)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterator<AbstractPly> iterator() {
|
||||||
|
java.util.List<AbstractPly> moves = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
Player cur = getCurrentPlayer();
|
||||||
|
|
||||||
|
for (int r = 0; r < SIZE; r++) {
|
||||||
|
for (int c = 0; c < SIZE; c++) {
|
||||||
|
for (int dr = -1; dr <= 1; dr++) {
|
||||||
|
for (int dc = -1; dc <= 1; dc++) {
|
||||||
|
if (dr == 0 && dc == 0) continue;
|
||||||
|
|
||||||
|
int nr = r + dr, nc = c + dc;
|
||||||
|
AvalamPly p = new AvalamPly(cur, r, c, nr, nc);
|
||||||
|
|
||||||
|
if (isLegal(p)) moves.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return moves.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne une copie “sûre” de l’état du plateau.
|
||||||
|
* Ici, la grille est recopiée case par case (copie des références Tower).
|
||||||
|
*
|
||||||
|
* @return copie du plateau (IBoard)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IBoard safeCopy() {
|
||||||
|
Tower[][] newGrid = new Tower[SIZE][SIZE];
|
||||||
|
|
||||||
|
for (int r = 0; r < SIZE; r++)
|
||||||
|
for (int c = 0; c < SIZE; c++)
|
||||||
|
newGrid[r][c] = grid[r][c];
|
||||||
|
|
||||||
|
return new AvalamBoard(newGrid, getCurrentPlayer(), gameOver, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
fr/iut_fbleau/Avalam/AvalamPly.java
Normal file
104
fr/iut_fbleau/Avalam/AvalamPly.java
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.GameAPI.AbstractPly;
|
||||||
|
import fr.iut_fbleau.GameAPI.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>AvalamPly</code>
|
||||||
|
*
|
||||||
|
* Représente un coup (ply) dans le jeu Avalam.
|
||||||
|
* Un coup est défini par :
|
||||||
|
* - un joueur (PLAYER1 ou PLAYER2)
|
||||||
|
* - une position source (xFrom, yFrom)
|
||||||
|
* - une position destination (xTo, yTo)
|
||||||
|
*
|
||||||
|
* Cette classe ne vérifie pas la légalité : tout est délégué à <code>AvalamBoard</code>.
|
||||||
|
*/
|
||||||
|
public class AvalamPly extends AbstractPly {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Coordonnée ligne de la case source. */
|
||||||
|
private final int xFrom;
|
||||||
|
|
||||||
|
/** Coordonnée colonne de la case source. */
|
||||||
|
private final int yFrom;
|
||||||
|
|
||||||
|
/** Coordonnée ligne de la case destination. */
|
||||||
|
private final int xTo;
|
||||||
|
|
||||||
|
/** Coordonnée colonne de la case destination. */
|
||||||
|
private final int yTo;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit un coup Avalam.
|
||||||
|
*
|
||||||
|
* @param player joueur qui joue le coup
|
||||||
|
* @param xFrom ligne d'origine
|
||||||
|
* @param yFrom colonne d'origine
|
||||||
|
* @param xTo ligne de destination
|
||||||
|
* @param yTo colonne de destination
|
||||||
|
*/
|
||||||
|
public AvalamPly(Player player, int xFrom, int yFrom, int xTo, int yTo) {
|
||||||
|
super(player);
|
||||||
|
this.xFrom = xFrom;
|
||||||
|
this.yFrom = yFrom;
|
||||||
|
this.xTo = xTo;
|
||||||
|
this.yTo = yTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la ligne d'origine.
|
||||||
|
*
|
||||||
|
* @return ligne source
|
||||||
|
*/
|
||||||
|
public int getXFrom() {
|
||||||
|
return xFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la colonne d'origine.
|
||||||
|
*
|
||||||
|
* @return colonne source
|
||||||
|
*/
|
||||||
|
public int getYFrom() {
|
||||||
|
return yFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la ligne de destination.
|
||||||
|
*
|
||||||
|
* @return ligne destination
|
||||||
|
*/
|
||||||
|
public int getXTo() {
|
||||||
|
return xTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la colonne de destination.
|
||||||
|
*
|
||||||
|
* @return colonne destination
|
||||||
|
*/
|
||||||
|
public int getYTo() {
|
||||||
|
return yTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Affichage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne une représentation textuelle du coup.
|
||||||
|
*
|
||||||
|
* @return chaîne décrivant le coup
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AvalamPly{" +
|
||||||
|
"player=" + getPlayer() +
|
||||||
|
", (" + xFrom + "," + yFrom + ") -> (" + xTo + "," + yTo + ")" +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,42 +1,161 @@
|
|||||||
package fr.iut_fbleau.Avalam;
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.logic.*;
|
import fr.iut_fbleau.GameAPI.Player;
|
||||||
import fr.iut_fbleau.Avalam.ui.*;
|
import fr.iut_fbleau.GameAPI.Result;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fenêtre principale du jeu Avalam.
|
* La classe <code>AvalamWindow</code>
|
||||||
*/
|
*
|
||||||
|
* Fenêtre principale (interface graphique) du jeu Avalam.
|
||||||
|
* Elle contient :
|
||||||
|
* - le plateau (BoardView)
|
||||||
|
* - l'affichage du score (ScoreView)
|
||||||
|
* - l'affichage du joueur courant (TurnView)
|
||||||
|
*
|
||||||
|
* Elle pilote un objet <code>AvalamBoard</code> (moteur du jeu).
|
||||||
|
*/
|
||||||
public class AvalamWindow extends JFrame {
|
public class AvalamWindow extends JFrame {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Moteur du jeu (état + règles). */
|
||||||
|
private AvalamBoard board;
|
||||||
|
|
||||||
|
/** Vue affichant le score des deux couleurs. */
|
||||||
|
private ScoreView scoreView;
|
||||||
|
|
||||||
|
/** Vue affichant le joueur dont c'est le tour. */
|
||||||
|
private TurnView turnView;
|
||||||
|
|
||||||
|
/** Vue affichant le plateau et gérant les interactions de jeu. */
|
||||||
|
private BoardView boardView;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit la fenêtre et initialise l’interface :
|
||||||
|
* - charge le plateau initial depuis Plateau.txt
|
||||||
|
* - construit les vues (score, tour, plateau)
|
||||||
|
* - affiche la fenêtre
|
||||||
|
*/
|
||||||
public AvalamWindow() {
|
public AvalamWindow() {
|
||||||
super("Avalam - Plateau Graphique");
|
super("Avalam");
|
||||||
|
|
||||||
setSize(750, 800);
|
|
||||||
setLocationRelativeTo(null);
|
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
Tower[][] grid = BoardLoader.loadFromFile("fr/iut_fbleau/Res/Plateau.txt");
|
// Chargement du plateau initial depuis Plateau.txt
|
||||||
GameState gs = new GameState(grid);
|
Tower[][] initialGrid = BoardLoader.loadFromFile("fr/iut_fbleau/Res/Plateau.txt");
|
||||||
ScoreManager sm = new ScoreManager();
|
|
||||||
|
|
||||||
int y = sm.count(Color.COLOR1, grid);
|
// Initialisation du moteur (PLAYER1 commence)
|
||||||
int r = sm.count(Color.COLOR2, grid);
|
board = new AvalamBoard(initialGrid);
|
||||||
|
|
||||||
ScoreView scoreView = new ScoreView(y, r);
|
// Création du panneau supérieur (score + tour)
|
||||||
TurnView turnView = new TurnView("Tour du joueur : Jaune");
|
JPanel topPanel = new JPanel(new GridLayout(2, 1));
|
||||||
|
topPanel.setBackground(new java.awt.Color(200, 200, 200));
|
||||||
|
|
||||||
BoardView boardView = new BoardView(gs);
|
scoreView = new ScoreView(
|
||||||
|
computeScore(Color.YELLOW),
|
||||||
|
computeScore(Color.RED)
|
||||||
|
);
|
||||||
|
|
||||||
JPanel top = new JPanel(new GridLayout(2,1));
|
turnView = new TurnView(turnMessage());
|
||||||
top.add(scoreView);
|
|
||||||
top.add(turnView);
|
|
||||||
|
|
||||||
add(top, BorderLayout.NORTH);
|
topPanel.add(scoreView);
|
||||||
|
topPanel.add(turnView);
|
||||||
|
|
||||||
|
add(topPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// Création de la vue plateau (avec callback de mise à jour)
|
||||||
|
boardView = new BoardView(board, this::onBoardUpdated);
|
||||||
add(boardView, BorderLayout.CENTER);
|
add(boardView, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
pack();
|
||||||
|
setResizable(false);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Méthode appelée automatiquement après chaque coup (via BoardView).
|
||||||
|
* Elle rafraîchit :
|
||||||
|
* - les scores
|
||||||
|
* - le joueur courant
|
||||||
|
* et affiche un message si la partie est terminée.
|
||||||
|
*/
|
||||||
|
public void onBoardUpdated() {
|
||||||
|
|
||||||
|
// Mise à jour du score
|
||||||
|
scoreView.updateScores(
|
||||||
|
computeScore(Color.YELLOW),
|
||||||
|
computeScore(Color.RED)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mise à jour du joueur courant
|
||||||
|
turnView.setTurn(turnMessage());
|
||||||
|
|
||||||
|
// Détection de fin de partie
|
||||||
|
if (board.isGameOver()) {
|
||||||
|
Result res = board.getResult();
|
||||||
|
|
||||||
|
String msg;
|
||||||
|
|
||||||
|
// Correction : ajout des "break" pour éviter le fall-through.
|
||||||
|
switch (res) {
|
||||||
|
case WIN:
|
||||||
|
msg = "Le joueur jaune a gagné !";
|
||||||
|
break;
|
||||||
|
case LOSS:
|
||||||
|
msg = "Le joueur rouge a gagné !";
|
||||||
|
break;
|
||||||
|
case DRAW:
|
||||||
|
msg = "Égalité !";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg = "Fin de partie.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
this,
|
||||||
|
msg,
|
||||||
|
"Partie terminée",
|
||||||
|
JOptionPane.INFORMATION_MESSAGE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule le score d'une couleur : nombre de tours contrôlées (sommet de la tour).
|
||||||
|
*
|
||||||
|
* @param c couleur à compter
|
||||||
|
* @return nombre de tours appartenant à la couleur c
|
||||||
|
*/
|
||||||
|
private int computeScore(Color c) {
|
||||||
|
int score = 0;
|
||||||
|
for (int r = 0; r < AvalamBoard.SIZE; r++) {
|
||||||
|
for (int col = 0; col < AvalamBoard.SIZE; col++) {
|
||||||
|
Tower t = board.getTowerAt(r, col);
|
||||||
|
if (t != null && t.getColor() == c) {
|
||||||
|
score++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne le message correspondant au joueur dont c'est le tour.
|
||||||
|
*
|
||||||
|
* @return message d’affichage du tour
|
||||||
|
*/
|
||||||
|
private String turnMessage() {
|
||||||
|
return "Tour du joueur : " +
|
||||||
|
(board.getCurrentPlayer() == Player.PLAYER1 ? "Jaune" : "Rouge");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
84
fr/iut_fbleau/Avalam/BoardLoader.java
Normal file
84
fr/iut_fbleau/Avalam/BoardLoader.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.Avalam.Color;
|
||||||
|
import fr.iut_fbleau.Avalam.Tower;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>BoardLoader</code>
|
||||||
|
*
|
||||||
|
* Permet de charger un plateau Avalam à partir d’un fichier texte.
|
||||||
|
* Le fichier contient une grille 9x9 de valeurs numériques :
|
||||||
|
* - 0 : case vide
|
||||||
|
* - 1 : tour jaune
|
||||||
|
* - 2 : tour rouge
|
||||||
|
*
|
||||||
|
* Cette classe fournit une méthode statique pour construire
|
||||||
|
* une grille de tours (<code>Tower[][]</code>) à partir d’une ressource.
|
||||||
|
*/
|
||||||
|
public class BoardLoader {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Charge un plateau Avalam depuis un fichier de ressources.
|
||||||
|
*
|
||||||
|
* @param resourcePath chemin du fichier de plateau (dans les ressources)
|
||||||
|
* @return une grille 9x9 de tours (Tower) ou null pour les cases vides
|
||||||
|
*/
|
||||||
|
public static Tower[][] loadFromFile(String resourcePath) {
|
||||||
|
|
||||||
|
Tower[][] grid = new Tower[9][9];
|
||||||
|
|
||||||
|
InputStream in = BoardLoader.class.getResourceAsStream("/" + resourcePath);
|
||||||
|
|
||||||
|
if (in == null) {
|
||||||
|
System.err.println("Ressource introuvable : /" + resourcePath);
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
|
||||||
|
|
||||||
|
String line;
|
||||||
|
int row = 0;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null && row < 9) {
|
||||||
|
|
||||||
|
// Accepte SOIT les espaces, SOIT les virgules
|
||||||
|
line = line.replace(",", " ");
|
||||||
|
String[] parts = line.trim().split("\\s+");
|
||||||
|
|
||||||
|
for (int col = 0; col < 9; col++) {
|
||||||
|
int value = Integer.parseInt(parts[col]);
|
||||||
|
|
||||||
|
switch (value) {
|
||||||
|
case 1:
|
||||||
|
grid[row][col] = new Tower(Color.YELLOW);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
grid[row][col] = new Tower(Color.RED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
grid[row][col] = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
}
|
||||||
166
fr/iut_fbleau/Avalam/BoardView.java
Normal file
166
fr/iut_fbleau/Avalam/BoardView.java
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.Avalam.AvalamBoard;
|
||||||
|
import fr.iut_fbleau.Avalam.Tower;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>BoardView</code>
|
||||||
|
*
|
||||||
|
* Représente la vue principale du plateau Avalam.
|
||||||
|
* Elle gère :
|
||||||
|
* - l’affichage des tours (PieceLayer)
|
||||||
|
* - l’affichage des coups possibles (HighlightLayer)
|
||||||
|
* - l’affichage du fond graphique
|
||||||
|
* - la gestion des interactions via InteractionController
|
||||||
|
*
|
||||||
|
* Cette classe ne contient aucune logique de jeu.
|
||||||
|
*/
|
||||||
|
public class BoardView extends JLayeredPane {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Référence au moteur du jeu Avalam. */
|
||||||
|
private AvalamBoard board;
|
||||||
|
|
||||||
|
/** Couche graphique du fond du plateau. */
|
||||||
|
private BackgroundLayer backgroundLayer;
|
||||||
|
|
||||||
|
/** Couche graphique des déplacements possibles. */
|
||||||
|
private HighlightLayer highlightLayer;
|
||||||
|
|
||||||
|
/** Couche graphique des pièces (tours). */
|
||||||
|
private PieceLayer pieceLayer;
|
||||||
|
|
||||||
|
/** Contrôleur des interactions utilisateur. */
|
||||||
|
private InteractionController controller;
|
||||||
|
|
||||||
|
/** Taille d’un pion en pixels. */
|
||||||
|
private final int size = 50;
|
||||||
|
|
||||||
|
/** Espacement entre deux cases du plateau. */
|
||||||
|
private final int spacing = 70;
|
||||||
|
|
||||||
|
/** Décalage horizontal du plateau. */
|
||||||
|
private final int xBase = 60;
|
||||||
|
|
||||||
|
/** Décalage vertical du plateau. */
|
||||||
|
private final int yBase = 60;
|
||||||
|
|
||||||
|
/** Callback vers AvalamWindow pour mettre à jour l’interface (score, tour, fin). */
|
||||||
|
private Runnable boardUpdateCallback;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit la vue du plateau Avalam.
|
||||||
|
*
|
||||||
|
* @param board moteur du jeu Avalam
|
||||||
|
* @param boardUpdateCallback fonction de rappel après un coup
|
||||||
|
*/
|
||||||
|
public BoardView(AvalamBoard board, Runnable boardUpdateCallback) {
|
||||||
|
this.board = board;
|
||||||
|
this.boardUpdateCallback = boardUpdateCallback;
|
||||||
|
|
||||||
|
setLayout(null);
|
||||||
|
|
||||||
|
// --- Contrôleur ---
|
||||||
|
this.controller = new InteractionController(board, this);
|
||||||
|
|
||||||
|
// --- Couche fond ---
|
||||||
|
backgroundLayer = new BackgroundLayer("fr/iut_fbleau/Res/BackgroundAvalam.png");
|
||||||
|
backgroundLayer.setBounds(0, 0, 725, 725);
|
||||||
|
add(backgroundLayer, JLayeredPane.FRAME_CONTENT_LAYER);
|
||||||
|
|
||||||
|
// --- Couche highlight ---
|
||||||
|
highlightLayer = new HighlightLayer(xBase, yBase, spacing, size);
|
||||||
|
add(highlightLayer, JLayeredPane.DEFAULT_LAYER);
|
||||||
|
|
||||||
|
// --- Couche des pièces ---
|
||||||
|
pieceLayer = new PieceLayer();
|
||||||
|
add(pieceLayer, JLayeredPane.PALETTE_LAYER);
|
||||||
|
|
||||||
|
setPreferredSize(new Dimension(725, 725));
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appelé par le contrôleur après un coup.
|
||||||
|
*/
|
||||||
|
public void onBoardUpdated() {
|
||||||
|
if (boardUpdateCallback != null) {
|
||||||
|
boardUpdateCallback.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rafraîchit l’affichage du plateau.
|
||||||
|
*/
|
||||||
|
public void refresh() {
|
||||||
|
|
||||||
|
pieceLayer.displayGrid(
|
||||||
|
boardGrid(),
|
||||||
|
xBase, yBase, spacing, size,
|
||||||
|
(r, c) -> controller.onPieceClicked(r, c)
|
||||||
|
);
|
||||||
|
|
||||||
|
highlightLayer.setLegalMoves(controller.getLegalMoves());
|
||||||
|
|
||||||
|
backgroundLayer.repaint();
|
||||||
|
highlightLayer.repaint();
|
||||||
|
pieceLayer.repaint();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère la grille actuelle du moteur de jeu.
|
||||||
|
*
|
||||||
|
* @return grille 9x9 de tours
|
||||||
|
*/
|
||||||
|
private Tower[][] boardGrid() {
|
||||||
|
Tower[][] grid = new Tower[AvalamBoard.SIZE][AvalamBoard.SIZE];
|
||||||
|
|
||||||
|
for (int r = 0; r < AvalamBoard.SIZE; r++) {
|
||||||
|
for (int c = 0; c < AvalamBoard.SIZE; c++) {
|
||||||
|
grid[r][c] = board.getTowerAt(r, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Affichage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe interne représentant la couche graphique du fond.
|
||||||
|
*/
|
||||||
|
private static class BackgroundLayer extends JComponent {
|
||||||
|
private Image img;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit une couche de fond à partir d’une image.
|
||||||
|
*
|
||||||
|
* @param resourcePath chemin de l’image
|
||||||
|
*/
|
||||||
|
public BackgroundLayer(String resourcePath) {
|
||||||
|
img = Toolkit.getDefaultToolkit().getImage(
|
||||||
|
getClass().getClassLoader().getResource(resourcePath)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dessine l’image de fond.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
if (img != null) {
|
||||||
|
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,60 @@
|
|||||||
package fr.iut_fbleau.Avalam;
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* L'énumération <code>Color</code> représente la couleur du sommet d'une tour Avalam.
|
* L'énumération <code>Color</code>
|
||||||
*
|
*
|
||||||
* COLOR1 : couleur du Joueur Jaune
|
* Représente les deux couleurs utilisées dans Avalam :
|
||||||
* COLOR2 : couleur du Joueur Rouge
|
* - YELLOW (jaune)
|
||||||
*
|
* - RED (rouge)
|
||||||
* Les couleurs Swing associées peuvent être modifiées ici pour changer tout le jeu.
|
*
|
||||||
*
|
* Chaque valeur est associée à une couleur Swing (<code>java.awt.Color</code>)
|
||||||
* @version 3.0
|
* pour l’affichage graphique et peut être convertie en <code>Player</code> (GameAPI).
|
||||||
*/
|
*/
|
||||||
public enum Color {
|
public enum Color {
|
||||||
|
|
||||||
COLOR1(java.awt.Color.YELLOW), // Joueur Jaune
|
//Attributs
|
||||||
COLOR2(java.awt.Color.RED); // Joueur Rouge
|
|
||||||
|
|
||||||
/** Couleur Swing associée */
|
/** Couleur jaune (associée à PLAYER1). */
|
||||||
|
YELLOW(255, 220, 0),
|
||||||
|
|
||||||
|
/** Couleur rouge (associée à PLAYER2). */
|
||||||
|
RED(200, 40, 40);
|
||||||
|
|
||||||
|
/** Couleur Swing utilisée pour l'affichage dans l'interface graphique. */
|
||||||
private final java.awt.Color swingColor;
|
private final java.awt.Color swingColor;
|
||||||
|
|
||||||
Color(java.awt.Color col) {
|
//Constructeur
|
||||||
this.swingColor = col;
|
|
||||||
|
/**
|
||||||
|
* Construit une couleur Avalam en initialisant sa couleur Swing associée.
|
||||||
|
*
|
||||||
|
* @param r composante rouge [0..255]
|
||||||
|
* @param g composante verte [0..255]
|
||||||
|
* @param b composante bleue [0..255]
|
||||||
|
*/
|
||||||
|
Color(int r, int g, int b) {
|
||||||
|
this.swingColor = new java.awt.Color(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la couleur Swing associée (pour l'affichage).
|
||||||
|
*
|
||||||
|
* @return java.awt.Color
|
||||||
|
*/
|
||||||
public java.awt.Color getSwingColor() {
|
public java.awt.Color getSwingColor() {
|
||||||
return this.swingColor;
|
return swingColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convertit la couleur Avalam en joueur GameAPI.
|
||||||
|
*
|
||||||
|
* @return PLAYER1 si YELLOW, sinon PLAYER2
|
||||||
|
*/
|
||||||
|
public fr.iut_fbleau.GameAPI.Player toPlayer() {
|
||||||
|
return (this == YELLOW ?
|
||||||
|
fr.iut_fbleau.GameAPI.Player.PLAYER1 :
|
||||||
|
fr.iut_fbleau.GameAPI.Player.PLAYER2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
94
fr/iut_fbleau/Avalam/HighlightLayer.java
Normal file
94
fr/iut_fbleau/Avalam/HighlightLayer.java
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>HighlightLayer</code>
|
||||||
|
*
|
||||||
|
* Gère l'affichage graphique des cases jouables sur le plateau Avalam.
|
||||||
|
* Les cases autorisées sont représentées par des cercles verts semi-transparents.
|
||||||
|
*
|
||||||
|
* Cette classe ne contient aucune logique de jeu.
|
||||||
|
*/
|
||||||
|
public class HighlightLayer extends JPanel {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Position X de base du plateau. */
|
||||||
|
private int xBase;
|
||||||
|
|
||||||
|
/** Position Y de base du plateau. */
|
||||||
|
private int yBase;
|
||||||
|
|
||||||
|
/** Espacement entre les cases du plateau. */
|
||||||
|
private int spacing;
|
||||||
|
|
||||||
|
/** Taille d’un pion en pixels. */
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
/** Liste des positions jouables (cases en vert). */
|
||||||
|
private List<Point> legalMoves;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit la couche d'affichage des coups légaux.
|
||||||
|
*
|
||||||
|
* @param xBase position X de base du plateau
|
||||||
|
* @param yBase position Y de base du plateau
|
||||||
|
* @param spacing espacement entre cases
|
||||||
|
* @param size taille des pions
|
||||||
|
*/
|
||||||
|
public HighlightLayer(int xBase, int yBase, int spacing, int size) {
|
||||||
|
this.xBase = xBase;
|
||||||
|
this.yBase = yBase;
|
||||||
|
this.spacing = spacing;
|
||||||
|
this.size = size;
|
||||||
|
|
||||||
|
setOpaque(false);
|
||||||
|
setBounds(0, 0, 800, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Définit la liste des cases légales à afficher.
|
||||||
|
*
|
||||||
|
* @param moves liste des positions jouables
|
||||||
|
*/
|
||||||
|
public void setLegalMoves(List<Point> moves) {
|
||||||
|
this.legalMoves = moves;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Affichage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dessine les cercles verts autour des cases autorisées.
|
||||||
|
*
|
||||||
|
* @param g contexte graphique
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
|
if (legalMoves == null) return;
|
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
|
g2.setColor(new java.awt.Color(0, 255, 0, 120));
|
||||||
|
|
||||||
|
for (Point p : legalMoves) {
|
||||||
|
|
||||||
|
int r = p.x;
|
||||||
|
int c = p.y;
|
||||||
|
|
||||||
|
int x = xBase + c * spacing;
|
||||||
|
int y = yBase + r * spacing;
|
||||||
|
|
||||||
|
int highlight = size + 20; // Cercle plus grand que le pion
|
||||||
|
g2.fillOval(x - 10, y - 10, highlight, highlight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
188
fr/iut_fbleau/Avalam/InteractionController.java
Normal file
188
fr/iut_fbleau/Avalam/InteractionController.java
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.GameAPI.AbstractPly;
|
||||||
|
import fr.iut_fbleau.GameAPI.Player;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>InteractionController</code>
|
||||||
|
*
|
||||||
|
* Gère l'interaction entre l'utilisateur et le moteur du jeu Avalam.
|
||||||
|
* Elle permet :
|
||||||
|
* - la sélection d'une tour
|
||||||
|
* - le calcul des coups légaux
|
||||||
|
* - la validation d'un déplacement
|
||||||
|
* - l'application d'un coup
|
||||||
|
* - la mise à jour de l'affichage via BoardView
|
||||||
|
*
|
||||||
|
* Cette classe ne réalise aucun affichage direct.
|
||||||
|
*/
|
||||||
|
public class InteractionController {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Référence au moteur du jeu Avalam. */
|
||||||
|
private AvalamBoard board;
|
||||||
|
|
||||||
|
/** Ligne de la tour sélectionnée (-1 si aucune). */
|
||||||
|
private int selectedRow = -1;
|
||||||
|
|
||||||
|
/** Colonne de la tour sélectionnée (-1 si aucune). */
|
||||||
|
private int selectedCol = -1;
|
||||||
|
|
||||||
|
/** Liste des coups légaux (sous forme de points). */
|
||||||
|
private List<Point> legalMoves = new ArrayList<>();
|
||||||
|
|
||||||
|
/** Référence à la vue du plateau pour rafraîchir l'affichage. */
|
||||||
|
private BoardView view;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit le contrôleur d'interactions.
|
||||||
|
*
|
||||||
|
* @param board moteur du jeu Avalam
|
||||||
|
* @param view vue du plateau
|
||||||
|
*/
|
||||||
|
public InteractionController(AvalamBoard board, BoardView view) {
|
||||||
|
this.board = board;
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la liste des cases jouables.
|
||||||
|
*
|
||||||
|
* @return liste des coups légaux
|
||||||
|
*/
|
||||||
|
public List<Point> getLegalMoves() {
|
||||||
|
return legalMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appelé lorsqu’un pion est cliqué dans BoardView.
|
||||||
|
* Gère :
|
||||||
|
* - la sélection d’une tour
|
||||||
|
* - la désélection
|
||||||
|
* - la tentative de déplacement
|
||||||
|
*
|
||||||
|
* @param r ligne cliquée
|
||||||
|
* @param c colonne cliquée
|
||||||
|
*/
|
||||||
|
public void onPieceClicked(int r, int c) {
|
||||||
|
|
||||||
|
// Si on clique la même case ⇒ désélection
|
||||||
|
if (r == selectedRow && c == selectedCol) {
|
||||||
|
clearSelection();
|
||||||
|
view.refresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si aucune sélection : on sélectionne un pion appartenant au joueur courant
|
||||||
|
Tower t = board.getTowerAt(r, c);
|
||||||
|
|
||||||
|
if (t != null && t.getColor().toPlayer() == board.getCurrentPlayer()) {
|
||||||
|
selectTower(r, c);
|
||||||
|
view.refresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sinon : tentons de jouer un coup (déplacement)
|
||||||
|
if (selectedRow != -1 && selectedCol != -1) {
|
||||||
|
tryMove(r, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sélectionne une tour à la position (r,c).
|
||||||
|
*
|
||||||
|
* @param r ligne
|
||||||
|
* @param c colonne
|
||||||
|
*/
|
||||||
|
private void selectTower(int r, int c) {
|
||||||
|
selectedRow = r;
|
||||||
|
selectedCol = c;
|
||||||
|
computeLegalMoves();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annule la sélection actuelle.
|
||||||
|
*/
|
||||||
|
private void clearSelection() {
|
||||||
|
selectedRow = -1;
|
||||||
|
selectedCol = -1;
|
||||||
|
legalMoves.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule les coups légaux à partir de la tour sélectionnée.
|
||||||
|
* Utilise l'itérateur fourni par AvalamBoard.
|
||||||
|
*/
|
||||||
|
private void computeLegalMoves() {
|
||||||
|
legalMoves.clear();
|
||||||
|
|
||||||
|
Iterator<AbstractPly> it = board.iterator();
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
AbstractPly p = it.next();
|
||||||
|
|
||||||
|
if (!(p instanceof AvalamPly)) continue;
|
||||||
|
AvalamPly ap = (AvalamPly) p;
|
||||||
|
|
||||||
|
// On ne garde que les coups dont la source correspond à la sélection
|
||||||
|
if (ap.getXFrom() == selectedRow && ap.getYFrom() == selectedCol) {
|
||||||
|
legalMoves.add(new Point(ap.getXTo(), ap.getYTo()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tente d’exécuter un déplacement vers la case (r,c).
|
||||||
|
*
|
||||||
|
* @param r ligne de destination
|
||||||
|
* @param c colonne de destination
|
||||||
|
*/
|
||||||
|
private void tryMove(int r, int c) {
|
||||||
|
// Vérifier si (r,c) est une destination légale
|
||||||
|
boolean isLegalDest = false;
|
||||||
|
for (Point p : legalMoves) {
|
||||||
|
if (p.x == r && p.y == c) {
|
||||||
|
isLegalDest = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isLegalDest) {
|
||||||
|
clearSelection(); // clic ailleurs = désélection
|
||||||
|
view.refresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construire le coup
|
||||||
|
Player cur = board.getCurrentPlayer();
|
||||||
|
AvalamPly ply = new AvalamPly(cur, selectedRow, selectedCol, r, c);
|
||||||
|
|
||||||
|
// Vérifier via l’API
|
||||||
|
if (board.isLegal(ply)) {
|
||||||
|
|
||||||
|
// Appliquer via l’API
|
||||||
|
board.doPly(ply);
|
||||||
|
|
||||||
|
// Réinitialiser la sélection
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
|
// Mise à jour de l'interface
|
||||||
|
view.onBoardUpdated();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Coup impossible
|
||||||
|
clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
view.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,27 @@
|
|||||||
package fr.iut_fbleau.Avalam;
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>Main</code>
|
||||||
|
*
|
||||||
|
* Point d’entrée du programme.
|
||||||
|
* Lance l’interface graphique principale (<code>AvalamWindow</code>).
|
||||||
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
public Main() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Méthode principale : démarre l’application.
|
||||||
|
*
|
||||||
|
* @param args arguments de la ligne de commande (non utilisés)
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new AvalamWindow();
|
new AvalamWindow();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,47 @@
|
|||||||
package fr.iut_fbleau.Avalam.ui;
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe <code>PieceButton</code> représente graphiquement une tour Avalam.
|
* La classe <code>PieceButton</code>
|
||||||
* Il s'agit d'un bouton rond :
|
*
|
||||||
*
|
* Représente graphiquement une tour Avalam sous forme d’un bouton rond.
|
||||||
* <ul>
|
* Chaque bouton :
|
||||||
* <li>coloré selon le joueur</li>
|
* - possède une couleur correspondant au joueur,
|
||||||
* <li>affichant sa hauteur</li>
|
* - affiche la hauteur de la tour,
|
||||||
* <li>avec un effet de survol visuel</li>
|
* - réagit au survol de la souris.
|
||||||
* </ul>
|
*
|
||||||
*
|
* Ce composant permet l’interaction avec les pièces du plateau.
|
||||||
* Ce composant sert d'interaction principale pour cliquer les pions.
|
*/
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class PieceButton extends JButton {
|
public class PieceButton extends JButton {
|
||||||
|
|
||||||
private Color color;
|
//Attributs
|
||||||
|
|
||||||
|
/** Couleur graphique du pion. */
|
||||||
|
private java.awt.Color color;
|
||||||
|
|
||||||
|
/** Hauteur de la tour affichée. */
|
||||||
private int height;
|
private int height;
|
||||||
|
|
||||||
|
/** Indique si la souris survole le bouton. */
|
||||||
private boolean hover = false;
|
private boolean hover = false;
|
||||||
|
|
||||||
/** Position de la tour sur la grille. */
|
/** Position de la tour sur la grille (ligne). */
|
||||||
public final int row, col;
|
public final int row;
|
||||||
|
|
||||||
|
/** Position de la tour sur la grille (colonne). */
|
||||||
|
public final int col;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur.
|
* Construit un bouton représentant une tour Avalam.
|
||||||
*
|
*
|
||||||
* @param c couleur graphique du pion
|
* @param c couleur graphique du pion
|
||||||
* @param height hauteur de la tour
|
* @param height hauteur de la tour
|
||||||
* @param row ligne du pion
|
* @param row ligne du pion
|
||||||
* @param col colonne du pion
|
* @param col colonne du pion
|
||||||
*/
|
*/
|
||||||
public PieceButton(java.awt.Color c, int height, int row, int col) {
|
public PieceButton(java.awt.Color c, int height, int row, int col) {
|
||||||
this.color = c;
|
this.color = c;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
@@ -52,9 +59,13 @@ public class PieceButton extends JButton {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dessine le pion rond ainsi que son chiffre au centre.
|
* Dessine le pion rond ainsi que sa hauteur au centre.
|
||||||
*/
|
*
|
||||||
|
* @param g contexte graphique
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics g) {
|
protected void paintComponent(Graphics g) {
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
@@ -78,9 +89,15 @@ public class PieceButton extends JButton {
|
|||||||
g2.dispose();
|
g2.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Affichage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rend le bouton réellement rond (zone cliquable circulaire).
|
* Rend le bouton réellement rond (zone cliquable circulaire).
|
||||||
*/
|
*
|
||||||
|
* @param x coordonnée X
|
||||||
|
* @param y coordonnée Y
|
||||||
|
* @return true si le point est dans le cercle
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(int x, int y) {
|
public boolean contains(int x, int y) {
|
||||||
double dx = x - getWidth()/2.0;
|
double dx = x - getWidth()/2.0;
|
||||||
@@ -1,48 +1,44 @@
|
|||||||
package fr.iut_fbleau.Avalam.ui;
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.Tower;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe <code>PieceLayer</code> gère l'affichage des pions
|
* La classe <code>PieceLayer</code>
|
||||||
* (sous forme de <code>PieceButton</code>) sur la grille.
|
*
|
||||||
*
|
* Gère l'affichage des tours du plateau Avalam sous forme de boutons.
|
||||||
* Elle s'occupe uniquement :
|
* Elle :
|
||||||
* <ul>
|
* - affiche les pièces,
|
||||||
* <li>d'afficher les pièces</li>
|
* - positionne les boutons sur la grille,
|
||||||
* <li>de positionner correctement les boutons</li>
|
* - associe une action de clic à chaque pièce.
|
||||||
* <li>d'attacher un callback à chaque clic</li>
|
*
|
||||||
* </ul>
|
* Aucune logique de jeu n'est implémentée ici.
|
||||||
*
|
*/
|
||||||
* Aucune logique de jeu n'est réalisée ici.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class PieceLayer extends JPanel {
|
public class PieceLayer extends JPanel {
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur.
|
* Construit la couche graphique des pièces.
|
||||||
* Initialise un panneau transparent prêt à recevoir des pions.
|
*/
|
||||||
*/
|
|
||||||
public PieceLayer() {
|
public PieceLayer() {
|
||||||
setLayout(null);
|
setLayout(null);
|
||||||
setOpaque(false);
|
setOpaque(false);
|
||||||
setBounds(0, 0, 800, 800);
|
setBounds(0, 0, 800, 800);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affiche la grille de tours sous forme de boutons.
|
* Affiche la grille de tours sous forme de boutons interactifs.
|
||||||
*
|
*
|
||||||
* @param grid grille 9×9 des tours
|
* @param grid grille 9×9 des tours
|
||||||
* @param xBase offset X du plateau
|
* @param xBase décalage horizontal du plateau
|
||||||
* @param yBase offset Y du plateau
|
* @param yBase décalage vertical du plateau
|
||||||
* @param spacing espacement entre cases
|
* @param spacing espacement entre cases
|
||||||
* @param size taille d'un pion
|
* @param size taille d'un pion
|
||||||
* @param clickCallback fonction appelée lors d’un clic sur un pion
|
* @param clickCallback fonction appelée lors d’un clic sur un pion
|
||||||
*/
|
*/
|
||||||
public void displayGrid(Tower[][] grid, int xBase, int yBase,
|
public void displayGrid(Tower[][] grid, int xBase, int yBase,
|
||||||
int spacing, int size,
|
int spacing, int size,
|
||||||
java.util.function.BiConsumer<Integer, Integer> clickCallback) {
|
java.util.function.BiConsumer<Integer, Integer> clickCallback) {
|
||||||
57
fr/iut_fbleau/Avalam/ScoreView.java
Normal file
57
fr/iut_fbleau/Avalam/ScoreView.java
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>ScoreView</code>
|
||||||
|
*
|
||||||
|
* Affiche les scores des deux joueurs du jeu Avalam.
|
||||||
|
* Cette classe est purement graphique : elle ne calcule pas les scores.
|
||||||
|
*/
|
||||||
|
public class ScoreView extends JPanel {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Label affichant le score du joueur jaune. */
|
||||||
|
private JLabel scoreY;
|
||||||
|
|
||||||
|
/** Label affichant le score du joueur rouge. */
|
||||||
|
private JLabel scoreR;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit la vue des scores.
|
||||||
|
*
|
||||||
|
* @param y score initial du joueur jaune
|
||||||
|
* @param r score initial du joueur rouge
|
||||||
|
*/
|
||||||
|
public ScoreView(int y, int r) {
|
||||||
|
setBackground(new java.awt.Color(200,200,200));
|
||||||
|
setLayout(new FlowLayout());
|
||||||
|
|
||||||
|
scoreY = new JLabel("Score Jaune : " + y);
|
||||||
|
scoreR = new JLabel("Score Rouge : " + r);
|
||||||
|
|
||||||
|
scoreY.setFont(new Font("Arial", Font.BOLD, 18));
|
||||||
|
scoreR.setFont(new Font("Arial", Font.BOLD, 18));
|
||||||
|
|
||||||
|
add(scoreY);
|
||||||
|
add(new JLabel(" | "));
|
||||||
|
add(scoreR);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour l'affichage des scores.
|
||||||
|
*
|
||||||
|
* @param y nouveau score du joueur jaune
|
||||||
|
* @param r nouveau score du joueur rouge
|
||||||
|
*/
|
||||||
|
public void updateScores(int y, int r) {
|
||||||
|
scoreY.setText("Score Jaune : " + y);
|
||||||
|
scoreR.setText("Score Rouge : " + r);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,41 +1,101 @@
|
|||||||
package fr.iut_fbleau.Avalam ;
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe <code>Tower</code> stocke la couleur de son pion haut et la hauteur de la tour.
|
* La classe <code>Tower</code>
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* Représente une tour dans le jeu Avalam.
|
||||||
* @author Aurélien
|
* Une tour est caractérisée par :
|
||||||
|
* - une couleur (couleur du sommet)
|
||||||
|
* - une hauteur (nombre de pions empilés)
|
||||||
|
*
|
||||||
|
* Cette version est volontairement compatible avec le reste du projet :
|
||||||
|
* - constructeur Tower(Color) utilisé par BoardLoader
|
||||||
|
* - constructeur Tower(int, Color) utilisé dans d'autres parties possibles
|
||||||
|
* - méthode mergeTower(Tower) utilisée par AvalamBoard
|
||||||
|
* - méthode merge(Tower) conservée (si elle est utilisée ailleurs)
|
||||||
*/
|
*/
|
||||||
public class Tower {
|
public class Tower {
|
||||||
//Attributs
|
|
||||||
private Color color ;
|
|
||||||
private byte height = 1 ;
|
|
||||||
|
|
||||||
//Constructeur
|
//Attributs
|
||||||
public Tower(Color color) {
|
|
||||||
this.color = color ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Méthodes
|
/** Hauteur de la tour (nombre de pions empilés). */
|
||||||
public Color getColor() {
|
private int height;
|
||||||
return this.color ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getHeight() {
|
/** Couleur du sommet de la tour (propriétaire actuel). */
|
||||||
return this.height ;
|
private Color color;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
//Constructeur
|
||||||
* Méthode qui empile une autre tour sur l'objet sur lequel le méthode est appelée.
|
|
||||||
* Aucune vérification de hauteur n'est effectuée.
|
/**
|
||||||
|
* Construit une tour de hauteur 1 avec la couleur donnée.
|
||||||
|
* (Constructeur attendu par BoardLoader dans ton projet.)
|
||||||
|
*
|
||||||
|
* @param color couleur du sommet
|
||||||
*/
|
*/
|
||||||
public void mergeTower(Tower tower) {
|
public Tower(Color color) {
|
||||||
this.color = tower.getColor();
|
this(1, color);
|
||||||
this.height += tower.getHeight();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String toString() {
|
* Construit une tour avec une hauteur et une couleur données.
|
||||||
return "" ;
|
*
|
||||||
}
|
* @param height hauteur initiale
|
||||||
|
* @param color couleur du sommet
|
||||||
|
*/
|
||||||
|
public Tower(int height, Color color) {
|
||||||
|
this.height = height;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la hauteur de la tour.
|
||||||
|
*
|
||||||
|
* @return hauteur
|
||||||
|
*/
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la couleur du sommet.
|
||||||
|
*
|
||||||
|
* @return couleur
|
||||||
|
*/
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fusionne la tour <code>src</code> sur la tour courante (destination).
|
||||||
|
* La couleur du sommet devient celle de <code>src</code>.
|
||||||
|
*
|
||||||
|
* @param src tour source empilée sur la destination
|
||||||
|
*/
|
||||||
|
public void merge(Tower src) {
|
||||||
|
this.height += src.height;
|
||||||
|
this.color = src.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias de merge() pour compatibilité avec d'autres classes.
|
||||||
|
*
|
||||||
|
* @param src tour source empilée sur la destination
|
||||||
|
*/
|
||||||
|
public void mergeTower(Tower src) {
|
||||||
|
merge(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Affichage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Représentation textuelle de la tour.
|
||||||
|
*
|
||||||
|
* @return chaîne représentant la tour
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return color + "(" + height + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
45
fr/iut_fbleau/Avalam/TurnView.java
Normal file
45
fr/iut_fbleau/Avalam/TurnView.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>TurnView</code>
|
||||||
|
*
|
||||||
|
* Affiche le joueur dont c'est le tour dans le jeu Avalam.
|
||||||
|
* Cette classe est uniquement graphique.
|
||||||
|
*/
|
||||||
|
public class TurnView extends JPanel {
|
||||||
|
|
||||||
|
//Attributs
|
||||||
|
|
||||||
|
/** Label affichant le joueur courant. */
|
||||||
|
private JLabel text;
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit la vue du tour de jeu.
|
||||||
|
*
|
||||||
|
* @param initial message initial à afficher
|
||||||
|
*/
|
||||||
|
public TurnView(String initial) {
|
||||||
|
setBackground(new java.awt.Color(220,220,220));
|
||||||
|
|
||||||
|
text = new JLabel(initial);
|
||||||
|
text.setFont(new Font("Arial", Font.BOLD, 20));
|
||||||
|
|
||||||
|
add(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour le texte affichant le joueur courant.
|
||||||
|
*
|
||||||
|
* @param s message à afficher
|
||||||
|
*/
|
||||||
|
public void setTurn(String s) {
|
||||||
|
text.setText(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.logic;
|
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.Color;
|
|
||||||
import fr.iut_fbleau.Avalam.Tower;
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>BoardLoader</code> est responsable du chargement d'un plateau Avalam
|
|
||||||
* depuis un fichier texte externe (généralement Plateau.txt).
|
|
||||||
*
|
|
||||||
* Le fichier doit contenir une matrice 9×9 de valeurs numériques séparées par des virgules :
|
|
||||||
* - 0 : case vide (trou)
|
|
||||||
* - 1 : pion appartenant au joueur COLOR1 (Jaune)
|
|
||||||
* - 2 : pion appartenant au joueur COLOR2 (Rouge)
|
|
||||||
*
|
|
||||||
* Aucun contrôle de cohérence avancé n'est effectué, le chargeur se contente
|
|
||||||
* d’interpréter les valeurs comme demandé.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class BoardLoader {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Charge un plateau Avalam depuis un fichier.
|
|
||||||
*
|
|
||||||
* @param path chemin du fichier plateau.
|
|
||||||
* @return un tableau 9×9 contenant des objets <code>Tower</code> ou <code>null</code>.
|
|
||||||
*/
|
|
||||||
public static Tower[][] loadFromFile(String path) {
|
|
||||||
|
|
||||||
Tower[][] grid = new Tower[9][9];
|
|
||||||
|
|
||||||
try (BufferedReader br = new BufferedReader(new FileReader(new File(path)))) {
|
|
||||||
|
|
||||||
String line;
|
|
||||||
int row = 0;
|
|
||||||
|
|
||||||
while ((line = br.readLine()) != null && row < 9) {
|
|
||||||
|
|
||||||
String[] parts = line.split(",");
|
|
||||||
|
|
||||||
for (int col = 0; col < 9; col++) {
|
|
||||||
int v = Integer.parseInt(parts[col]);
|
|
||||||
|
|
||||||
// Interprétation des valeurs
|
|
||||||
if (v == 1) grid[row][col] = new Tower(Color.COLOR1);
|
|
||||||
else if (v == 2) grid[row][col] = new Tower(Color.COLOR2);
|
|
||||||
else grid[row][col] = null; // Case vide
|
|
||||||
}
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.logic;
|
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.Color;
|
|
||||||
import fr.iut_fbleau.Avalam.Tower;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>GameState</code> représente l'état courant du jeu Avalam :
|
|
||||||
* - la grille 9×9
|
|
||||||
* - le joueur dont c'est le tour
|
|
||||||
*
|
|
||||||
* Elle ne contient aucune logique de déplacement ni de vérification des règles ;
|
|
||||||
* son rôle est uniquement de stocker et de fournir l'état du jeu.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class GameState {
|
|
||||||
|
|
||||||
/** Grille du plateau : 9×9 tours ou cases vides. */
|
|
||||||
private Tower[][] grid;
|
|
||||||
|
|
||||||
/** Joueur dont c’est le tour (COLOR1 ou COLOR2). */
|
|
||||||
private Color currentPlayer = Color.COLOR1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur.
|
|
||||||
*
|
|
||||||
* @param grid la grille initiale du plateau.
|
|
||||||
*/
|
|
||||||
public GameState(Tower[][] grid) {
|
|
||||||
this.grid = grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retourne la tour présente à la position (r,c), ou null.
|
|
||||||
*/
|
|
||||||
public Tower get(int r, int c) {
|
|
||||||
return grid[r][c];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retourne la grille complète.
|
|
||||||
*/
|
|
||||||
public Tower[][] getGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retourne le joueur dont c'est le tour.
|
|
||||||
*/
|
|
||||||
public Color getCurrentPlayer() {
|
|
||||||
return currentPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change le joueur courant : COLOR1 → COLOR2 → COLOR1.
|
|
||||||
*/
|
|
||||||
public void switchPlayer() {
|
|
||||||
currentPlayer = (currentPlayer == Color.COLOR1) ? Color.COLOR2 : Color.COLOR1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vérifie si une position (r,c) est dans les limites du plateau.
|
|
||||||
*
|
|
||||||
* @return vrai si la position est comprise dans un plateau 9×9.
|
|
||||||
*/
|
|
||||||
public boolean isInside(int r, int c) {
|
|
||||||
return r >= 0 && r < 9 && c >= 0 && c < 9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.logic;
|
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.Color;
|
|
||||||
import fr.iut_fbleau.Avalam.Tower;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>ScoreManager</code> gère le calcul des scores
|
|
||||||
* selon les règles officielles d’Avalam :
|
|
||||||
*
|
|
||||||
* Un joueur gagne 1 point par tour dont le sommet (couleur) lui appartient,
|
|
||||||
* indépendamment de la hauteur de la tour.
|
|
||||||
*
|
|
||||||
* Cette classe n’a aucune responsabilité autre que compter.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class ScoreManager {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compte le nombre de tours dont le sommet appartient à la couleur donnée.
|
|
||||||
*
|
|
||||||
* @param c couleur du joueur (COLOR1 ou COLOR2)
|
|
||||||
* @param grid grille 9×9 contenant des tours ou null
|
|
||||||
* @return score du joueur
|
|
||||||
*/
|
|
||||||
public static int count(Color c, Tower[][] grid) {
|
|
||||||
int score = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < 9; i++)
|
|
||||||
for (int j = 0; j < 9; j++)
|
|
||||||
if (grid[i][j] != null && grid[i][j].getColor() == c)
|
|
||||||
score++;
|
|
||||||
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.logic;
|
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>TurnManager</code> gère le déroulement des tours d’Avalam.
|
|
||||||
*
|
|
||||||
* Son rôle est simple :
|
|
||||||
* - identifier le joueur dont c’est le tour
|
|
||||||
* - passer au joueur suivant
|
|
||||||
*
|
|
||||||
* Elle ne contient pas de logique de mouvement, ni de validation.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class TurnManager {
|
|
||||||
|
|
||||||
/** Joueur dont c'est le tour (COLOR1 commence la partie). */
|
|
||||||
private Color current = Color.COLOR1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retourne le joueur actuel.
|
|
||||||
*/
|
|
||||||
public Color getPlayer() {
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passe au joueur suivant.
|
|
||||||
*/
|
|
||||||
public void next() {
|
|
||||||
current = (current == Color.COLOR1) ? Color.COLOR2 : Color.COLOR1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.ui;
|
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.logic.GameState;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>BoardView</code> représente l'affichage complet du plateau Avalam.
|
|
||||||
* Elle s’appuie sur une architecture en couches (layered pane) pour séparer proprement :
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li><b>HighlightLayer</b> : les cases jouables mises en surbrillance</li>
|
|
||||||
* <li><b>PieceLayer</b> : les pions affichés sous forme de boutons ronds</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* La vue ne contient pas la logique de jeu : elle la délègue entièrement
|
|
||||||
* à un <code>InteractionController</code>.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class BoardView extends JLayeredPane {
|
|
||||||
|
|
||||||
/** Taille des pions affichés. */
|
|
||||||
private final int size = 50;
|
|
||||||
|
|
||||||
/** Distance entre deux cases de la grille. */
|
|
||||||
private final int spacing = 70;
|
|
||||||
|
|
||||||
/** Décalages pour centrer l'affichage. */
|
|
||||||
private final int xBase = 60, yBase = 60;
|
|
||||||
|
|
||||||
/** Accès à l'état du jeu. */
|
|
||||||
private GameState state;
|
|
||||||
|
|
||||||
/** Couche d'affichage des ronds verts. */
|
|
||||||
private HighlightLayer highlightLayer;
|
|
||||||
|
|
||||||
/** Couche d'affichage des pions. */
|
|
||||||
private PieceLayer pieceLayer;
|
|
||||||
|
|
||||||
/** Gestionnaire d'interactions utilisateur. */
|
|
||||||
private InteractionController controller;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur de la vue du plateau.
|
|
||||||
*
|
|
||||||
* @param state l'état du jeu Avalam
|
|
||||||
*/
|
|
||||||
public BoardView(GameState state) {
|
|
||||||
this.state = state;
|
|
||||||
setLayout(null);
|
|
||||||
|
|
||||||
controller = new InteractionController(state);
|
|
||||||
|
|
||||||
highlightLayer = new HighlightLayer(xBase, yBase, spacing, size);
|
|
||||||
pieceLayer = new PieceLayer();
|
|
||||||
|
|
||||||
add(highlightLayer, JLayeredPane.DEFAULT_LAYER);
|
|
||||||
add(pieceLayer, JLayeredPane.PALETTE_LAYER);
|
|
||||||
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Met à jour l'affichage des couches en fonction de l'état actuel du jeu.
|
|
||||||
*/
|
|
||||||
public void refresh() {
|
|
||||||
|
|
||||||
pieceLayer.displayGrid(
|
|
||||||
state.getGrid(),
|
|
||||||
xBase, yBase, spacing, size,
|
|
||||||
|
|
||||||
// Callback appelé lorsqu’un pion est cliqué
|
|
||||||
(r, c) -> {
|
|
||||||
controller.onPieceClicked(r, c);
|
|
||||||
highlightLayer.setLegalMoves(controller.getLegalMoves());
|
|
||||||
highlightLayer.repaint();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
highlightLayer.repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.ui;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>HighlightLayer</code> est responsable de l'affichage des
|
|
||||||
* cases de déplacement autorisées sous forme de cercles verts.
|
|
||||||
*
|
|
||||||
* Elle n'interagit pas directement avec les pièces, mais se contente
|
|
||||||
* de dessiner en arrière-plan selon une liste de positions légales.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class HighlightLayer extends JPanel {
|
|
||||||
|
|
||||||
private int xBase, yBase, spacing, size;
|
|
||||||
|
|
||||||
/** Liste des positions jouables (cases en vert). */
|
|
||||||
private List<Point> legalMoves;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur.
|
|
||||||
*
|
|
||||||
* @param xBase position X de base du plateau
|
|
||||||
* @param yBase position Y de base du plateau
|
|
||||||
* @param spacing espacement entre cases
|
|
||||||
* @param size taille des pions
|
|
||||||
*/
|
|
||||||
public HighlightLayer(int xBase, int yBase, int spacing, int size) {
|
|
||||||
this.xBase = xBase;
|
|
||||||
this.yBase = yBase;
|
|
||||||
this.spacing = spacing;
|
|
||||||
this.size = size;
|
|
||||||
|
|
||||||
setOpaque(false);
|
|
||||||
setBounds(0, 0, 800, 800);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Définit la liste des cases légales à afficher.
|
|
||||||
*/
|
|
||||||
public void setLegalMoves(List<Point> moves) {
|
|
||||||
this.legalMoves = moves;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dessine les cercles verts autour des cases autorisées.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void paintComponent(Graphics g) {
|
|
||||||
super.paintComponent(g);
|
|
||||||
|
|
||||||
if (legalMoves == null) return;
|
|
||||||
|
|
||||||
Graphics2D g2 = (Graphics2D) g;
|
|
||||||
g2.setColor(new Color(0, 255, 0, 120));
|
|
||||||
|
|
||||||
for (Point p : legalMoves) {
|
|
||||||
|
|
||||||
int r = p.x;
|
|
||||||
int c = p.y;
|
|
||||||
|
|
||||||
int x = xBase + c * spacing;
|
|
||||||
int y = yBase + r * spacing;
|
|
||||||
|
|
||||||
int highlight = size + 20; // Cercle plus grand que le pion
|
|
||||||
g2.fillOval(x - 10, y - 10, highlight, highlight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.ui;
|
|
||||||
|
|
||||||
import fr.iut_fbleau.Avalam.Tower;
|
|
||||||
import fr.iut_fbleau.Avalam.logic.GameState;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>InteractionController</code> gère entièrement
|
|
||||||
* la logique d'interaction de l'utilisateur :
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>Sélection d'un pion</li>
|
|
||||||
* <li>Annulation de la sélection</li>
|
|
||||||
* <li>Calcul des cases de déplacement légales</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* Aucun affichage n'est réalisé ici ; la vue (BoardView) récupère
|
|
||||||
* simplement les données calculées pour les afficher.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class InteractionController {
|
|
||||||
|
|
||||||
private GameState state;
|
|
||||||
|
|
||||||
/** Position du pion sélectionné (ou -1 s'il n'y en a pas). */
|
|
||||||
private int selectedRow = -1, selectedCol = -1;
|
|
||||||
|
|
||||||
/** Liste des déplacements possibles depuis la sélection. */
|
|
||||||
private List<Point> legalMoves = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur.
|
|
||||||
*
|
|
||||||
* @param state état du jeu à manipuler
|
|
||||||
*/
|
|
||||||
public InteractionController(GameState state) {
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retourne les cases jouables calculées.
|
|
||||||
*/
|
|
||||||
public List<Point> getLegalMoves() {
|
|
||||||
return legalMoves;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gère le clic sur un pion donné.
|
|
||||||
*
|
|
||||||
* @param r ligne de la case cliquée
|
|
||||||
* @param c colonne de la case cliquée
|
|
||||||
*/
|
|
||||||
public void onPieceClicked(int r, int c) {
|
|
||||||
|
|
||||||
Tower t = state.get(r, c);
|
|
||||||
if (t == null) return;
|
|
||||||
|
|
||||||
// Annulation si on reclique la sélection
|
|
||||||
if (r == selectedRow && c == selectedCol) {
|
|
||||||
selectedRow = -1;
|
|
||||||
selectedCol = -1;
|
|
||||||
legalMoves.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interdiction de jouer le pion adverse
|
|
||||||
if (t.getColor() != state.getCurrentPlayer()) {
|
|
||||||
selectedRow = -1;
|
|
||||||
selectedCol = -1;
|
|
||||||
legalMoves.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedRow = r;
|
|
||||||
selectedCol = c;
|
|
||||||
|
|
||||||
computeLegalMoves();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calcule toutes les cases accessibles à partir du pion sélectionné.
|
|
||||||
*/
|
|
||||||
private void computeLegalMoves() {
|
|
||||||
|
|
||||||
legalMoves.clear();
|
|
||||||
|
|
||||||
Tower[][] grid = state.getGrid();
|
|
||||||
Tower src = grid[selectedRow][selectedCol];
|
|
||||||
int h = src.getHeight();
|
|
||||||
|
|
||||||
int[] d = {-1, 0, 1};
|
|
||||||
|
|
||||||
for (int dr : d) {
|
|
||||||
for (int dc : d) {
|
|
||||||
|
|
||||||
if (dr == 0 && dc == 0) continue;
|
|
||||||
|
|
||||||
int nr = selectedRow + dr;
|
|
||||||
int nc = selectedCol + dc;
|
|
||||||
|
|
||||||
if (!state.isInside(nr, nc)) continue;
|
|
||||||
|
|
||||||
Tower dest = grid[nr][nc];
|
|
||||||
if (dest == null) continue;
|
|
||||||
if (h + dest.getHeight() > 5) continue;
|
|
||||||
|
|
||||||
legalMoves.add(new Point(nr, nc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.ui;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>ScoreView</code> affiche les scores actuels des deux joueurs.
|
|
||||||
*
|
|
||||||
* Elle est purement graphique : aucune logique de calcul n'est présente.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class ScoreView extends JPanel {
|
|
||||||
|
|
||||||
private JLabel scoreY, scoreR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur.
|
|
||||||
*
|
|
||||||
* @param y score initial du joueur jaune
|
|
||||||
* @param r score initial du joueur rouge
|
|
||||||
*/
|
|
||||||
public ScoreView(int y, int r) {
|
|
||||||
setBackground(new Color(200,200,200));
|
|
||||||
setLayout(new FlowLayout());
|
|
||||||
|
|
||||||
scoreY = new JLabel("Score Jaune : " + y);
|
|
||||||
scoreR = new JLabel("Score Rouge : " + r);
|
|
||||||
|
|
||||||
scoreY.setFont(new Font("Arial", Font.BOLD, 18));
|
|
||||||
scoreR.setFont(new Font("Arial", Font.BOLD, 18));
|
|
||||||
|
|
||||||
add(scoreY);
|
|
||||||
add(new JLabel(" | "));
|
|
||||||
add(scoreR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Met à jour l'affichage des scores.
|
|
||||||
*/
|
|
||||||
public void updateScores(int y, int r) {
|
|
||||||
scoreY.setText("Score Jaune : " + y);
|
|
||||||
scoreR.setText("Score Rouge : " + r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package fr.iut_fbleau.Avalam.ui;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe <code>TurnView</code> affiche le joueur à qui c'est le tour.
|
|
||||||
*
|
|
||||||
* Elle agit comme une simple bannière d’information,
|
|
||||||
* mise à jour par la logique du jeu.
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class TurnView extends JPanel {
|
|
||||||
|
|
||||||
private JLabel text;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur.
|
|
||||||
*
|
|
||||||
* @param initial message initial à afficher
|
|
||||||
*/
|
|
||||||
public TurnView(String initial) {
|
|
||||||
setBackground(new Color(220,220,220));
|
|
||||||
|
|
||||||
text = new JLabel(initial);
|
|
||||||
text.setFont(new Font("Arial", Font.BOLD, 20));
|
|
||||||
|
|
||||||
add(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Met à jour le texte affichant le joueur courant.
|
|
||||||
*
|
|
||||||
* @param s message à afficher
|
|
||||||
*/
|
|
||||||
public void setTurn(String s) {
|
|
||||||
text.setText(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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.
BIN
fr/iut_fbleau/Res/BackgroundAvalam.png
Normal file
BIN
fr/iut_fbleau/Res/BackgroundAvalam.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Reference in New Issue
Block a user