2026-01-26 06:39:49 -05:00
|
|
|
|
package fr.iut_fbleau.Avalam;
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
import fr.iut_fbleau.GameAPI.AbstractPly;
|
|
|
|
|
|
import fr.iut_fbleau.GameAPI.Player;
|
|
|
|
|
|
|
|
|
|
|
|
import java.awt.Point;
|
2025-11-22 11:56:51 -05:00
|
|
|
|
import java.util.ArrayList;
|
2025-11-25 16:02:23 -05:00
|
|
|
|
import java.util.Iterator;
|
2025-11-22 11:56:51 -05:00
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-26 06:39:49 -05:00
|
|
|
|
* 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.
|
|
|
|
|
|
*/
|
2025-11-22 11:56:51 -05:00
|
|
|
|
public class InteractionController {
|
|
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
//Attributs
|
|
|
|
|
|
|
|
|
|
|
|
/** Référence au moteur du jeu Avalam. */
|
2025-11-25 16:02:23 -05:00
|
|
|
|
private AvalamBoard board;
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
/** Ligne de la tour sélectionnée (-1 si aucune). */
|
2025-11-25 16:02:23 -05:00
|
|
|
|
private int selectedRow = -1;
|
2026-01-26 06:39:49 -05:00
|
|
|
|
|
|
|
|
|
|
/** Colonne de la tour sélectionnée (-1 si aucune). */
|
2025-11-25 16:02:23 -05:00
|
|
|
|
private int selectedCol = -1;
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
/** Liste des coups légaux (sous forme de points). */
|
2025-11-22 11:56:51 -05:00
|
|
|
|
private List<Point> legalMoves = new ArrayList<>();
|
|
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
/** Référence à la vue du plateau pour rafraîchir l'affichage. */
|
2025-11-25 16:02:23 -05:00
|
|
|
|
private BoardView view;
|
|
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
//Constructeur
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Construit le contrôleur d'interactions.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param board moteur du jeu Avalam
|
|
|
|
|
|
* @param view vue du plateau
|
|
|
|
|
|
*/
|
2025-11-25 16:02:23 -05:00
|
|
|
|
public InteractionController(AvalamBoard board, BoardView view) {
|
|
|
|
|
|
this.board = board;
|
|
|
|
|
|
this.view = view;
|
2025-11-22 11:56:51 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
//Méthodes
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Retourne la liste des cases jouables.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return liste des coups légaux
|
|
|
|
|
|
*/
|
2025-11-22 11:56:51 -05:00
|
|
|
|
public List<Point> getLegalMoves() {
|
|
|
|
|
|
return legalMoves;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-26 06:39:49 -05:00
|
|
|
|
* 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
|
|
|
|
|
|
*/
|
2025-11-22 11:56:51 -05:00
|
|
|
|
public void onPieceClicked(int r, int c) {
|
|
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
// Si on clique la même case ⇒ désélection
|
2025-11-22 11:56:51 -05:00
|
|
|
|
if (r == selectedRow && c == selectedCol) {
|
2025-11-25 16:02:23 -05:00
|
|
|
|
clearSelection();
|
|
|
|
|
|
view.refresh();
|
2025-11-22 11:56:51 -05:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
// 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();
|
2025-11-22 11:56:51 -05:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
// Sinon : tentons de jouer un coup (déplacement)
|
|
|
|
|
|
if (selectedRow != -1 && selectedCol != -1) {
|
|
|
|
|
|
tryMove(r, c);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
/**
|
|
|
|
|
|
* Sélectionne une tour à la position (r,c).
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param r ligne
|
|
|
|
|
|
* @param c colonne
|
|
|
|
|
|
*/
|
2025-11-25 16:02:23 -05:00
|
|
|
|
private void selectTower(int r, int c) {
|
2025-11-22 11:56:51 -05:00
|
|
|
|
selectedRow = r;
|
|
|
|
|
|
selectedCol = c;
|
|
|
|
|
|
computeLegalMoves();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
/**
|
|
|
|
|
|
* Annule la sélection actuelle.
|
|
|
|
|
|
*/
|
2025-11-25 16:02:23 -05:00
|
|
|
|
private void clearSelection() {
|
|
|
|
|
|
selectedRow = -1;
|
|
|
|
|
|
selectedCol = -1;
|
|
|
|
|
|
legalMoves.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-22 11:56:51 -05:00
|
|
|
|
/**
|
2026-01-26 06:39:49 -05:00
|
|
|
|
* Calcule les coups légaux à partir de la tour sélectionnée.
|
|
|
|
|
|
* Utilise l'itérateur fourni par AvalamBoard.
|
|
|
|
|
|
*/
|
2025-11-22 11:56:51 -05:00
|
|
|
|
private void computeLegalMoves() {
|
|
|
|
|
|
legalMoves.clear();
|
|
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
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()));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-26 06:39:49 -05:00
|
|
|
|
* Tente d’exécuter un déplacement vers la case (r,c).
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param r ligne de destination
|
|
|
|
|
|
* @param c colonne de destination
|
|
|
|
|
|
*/
|
2025-11-25 16:02:23 -05:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
// Construire le coup
|
|
|
|
|
|
Player cur = board.getCurrentPlayer();
|
|
|
|
|
|
AvalamPly ply = new AvalamPly(cur, selectedRow, selectedCol, r, c);
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
// Vérifier via l’API
|
|
|
|
|
|
if (board.isLegal(ply)) {
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
// Appliquer via l’API
|
|
|
|
|
|
board.doPly(ply);
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
// Réinitialiser la sélection
|
|
|
|
|
|
clearSelection();
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2026-01-26 06:39:49 -05:00
|
|
|
|
// Mise à jour de l'interface
|
2025-11-25 16:02:23 -05:00
|
|
|
|
view.onBoardUpdated();
|
2025-11-22 11:56:51 -05:00
|
|
|
|
|
2025-11-25 16:02:23 -05:00
|
|
|
|
} else {
|
2026-01-26 06:39:49 -05:00
|
|
|
|
// Coup impossible
|
2025-11-25 16:02:23 -05:00
|
|
|
|
clearSelection();
|
2025-11-22 11:56:51 -05:00
|
|
|
|
}
|
2025-11-25 16:02:23 -05:00
|
|
|
|
|
|
|
|
|
|
view.refresh();
|
2025-11-22 11:56:51 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|