166 lines
4.8 KiB
Java
166 lines
4.8 KiB
Java
package fr.iut_fbleau.Avalam.ui;
|
||
|
||
import fr.iut_fbleau.Avalam.AvalamBoard;
|
||
import fr.iut_fbleau.Avalam.AvalamPly;
|
||
import fr.iut_fbleau.Avalam.Tower;
|
||
|
||
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;
|
||
|
||
/**
|
||
* Le contrôleur gère toute l'interaction entre l'utilisateur et le moteur Avalam.
|
||
*
|
||
* Son rôle :
|
||
* - gérer la sélection d’une tour
|
||
* - générer les coups légaux via l’API (iterator)
|
||
* - valider un déplacement (isLegal)
|
||
* - appliquer un coup (doPly)
|
||
* - mettre à jour le plateau (via refresh demandé au BoardView)
|
||
*
|
||
* IMPORTANT : ce contrôleur n’affiche rien. Il envoie les infos à BoardView.
|
||
*/
|
||
public class InteractionController {
|
||
|
||
private AvalamBoard board;
|
||
|
||
/** Position sélectionnée (-1 si aucune) */
|
||
private int selectedRow = -1;
|
||
private int selectedCol = -1;
|
||
|
||
/** Liste des coups légaux (en Point) autour de la sélection */
|
||
private List<Point> legalMoves = new ArrayList<>();
|
||
|
||
/** Référence à la vue pour la rafraîchir après déplacements */
|
||
private BoardView view;
|
||
|
||
public InteractionController(AvalamBoard board, BoardView view) {
|
||
this.board = board;
|
||
this.view = view;
|
||
}
|
||
|
||
/** Retourne les cases jouables (pour HighlightLayer). */
|
||
public List<Point> getLegalMoves() {
|
||
return legalMoves;
|
||
}
|
||
|
||
/**
|
||
* Appelé lorsqu’un pion est cliqué dans BoardView.
|
||
* Gère :
|
||
* - sélection d’une tour
|
||
* - désélection
|
||
* - tentative de déplacement (si clique sur un highlight)
|
||
*/
|
||
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ÉLECTION D’UNE TOUR
|
||
* ---------------------------------------------------------------------- */
|
||
|
||
private void selectTower(int r, int c) {
|
||
selectedRow = r;
|
||
selectedCol = c;
|
||
computeLegalMoves();
|
||
}
|
||
|
||
private void clearSelection() {
|
||
selectedRow = -1;
|
||
selectedCol = -1;
|
||
legalMoves.clear();
|
||
}
|
||
|
||
/**
|
||
* Identifie les destinations possibles depuis la tour sélectionnée.
|
||
* Utilise l’API officielle : board.iterator()
|
||
*/
|
||
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()));
|
||
}
|
||
}
|
||
}
|
||
|
||
/* -------------------------------------------------------------------------
|
||
* TENTATIVE DE DÉPLACEMENT
|
||
* ---------------------------------------------------------------------- */
|
||
|
||
/**
|
||
* Tente d’exécuter un déplacement vers (r,c) si c’est un coup légal.
|
||
*/
|
||
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();
|
||
|
||
// Recalcul du score + joueur courant + fin de partie (handled in window)
|
||
view.onBoardUpdated();
|
||
|
||
} else {
|
||
// Coup impossible (rare, mais pour sécurité)
|
||
clearSelection();
|
||
}
|
||
|
||
view.refresh();
|
||
}
|
||
}
|