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 InteractionController * * 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 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 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 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(); } }