Files
BUT3-JEU/TP3/fr/iut_fbleau/Nim/NimBoard.java
James Boutaric 403764edc6 changement API
2025-10-09 11:46:45 +02:00

199 lines
5.8 KiB
Java

package fr.iut_fbleau.Nim;
import fr.iut_fbleau.GameAPI.AbstractBoard;
import fr.iut_fbleau.GameAPI.AbstractPly;
import fr.iut_fbleau.GameAPI.Player;
import fr.iut_fbleau.GameAPI.Result;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Deque;
import java.util.ArrayDeque;
/**
* Représente le plateau du jeu de Nim.
* Le jeu de Nim se joue avec un certain nombre d'allumettes.
* Les joueurs retirent à tour de rôle entre 1 et maxParCoup allumettes.
* Le joueur qui retire la dernière allumette perd (variante misère).
*/
public class NimBoard extends AbstractBoard {
private int allumettesRestantes;
private int maxParCoup;
private int allumettesInitiales;
private Player currentPlayer;
private Deque<AbstractPly> history;
private boolean gameOver;
private Result result;
/**
* Constructeur du plateau de Nim
*
* @param allumettesInitiales le nombre d'allumettes au début du jeu
* @param maxParCoup le nombre maximum d'allumettes qu'on peut retirer par coup
*/
public NimBoard(int allumettesInitiales, int maxParCoup) {
if (allumettesInitiales <= 0) {
throw new IllegalArgumentException("Le nombre d'allumettes doit être positif");
}
if (maxParCoup <= 0) {
throw new IllegalArgumentException("Le nombre maximum par coup doit être positif");
}
this.allumettesInitiales = allumettesInitiales;
this.allumettesRestantes = allumettesInitiales;
this.maxParCoup = maxParCoup;
this.currentPlayer = Player.PLAYER1;
this.history = new ArrayDeque<>();
this.gameOver = false;
this.result = null;
}
/**
* @return le nombre d'allumettes restantes
*/
public int getAllumettesRestantes() {
return this.allumettesRestantes;
}
/**
* @return le nombre maximum d'allumettes par coup
*/
public int getMaxParCoup() {
return this.maxParCoup;
}
@Override
public Player getCurrentPlayer() {
return this.currentPlayer;
}
@Override
public boolean isGameOver() {
return this.gameOver;
}
@Override
public Result getResult() {
return this.result;
}
@Override
public boolean isLegal(AbstractPly c) {
if (this.gameOver) {
throw new NullPointerException("Le jeu est terminé");
}
if (!(c instanceof NimPly)) {
return false;
}
NimPly coup = (NimPly) c;
if (coup.getJoueur() != this.currentPlayer) {
return false;
}
// Vérifier que le nombre d'allumettes est valide
int nbAllumettes = coup.getNombreAllumettesPrises();
return nbAllumettes >= 1 &&
nbAllumettes <= this.maxParCoup &&
nbAllumettes <= this.allumettesRestantes;
}
@Override
public Iterator<AbstractPly> iterator() {
if (this.gameOver) {
throw new NullPointerException("Le jeu est terminé");
}
ArrayList<AbstractPly> coups = new ArrayList<>();
int maxRetirage = Math.min(this.maxParCoup, this.allumettesRestantes);
for (int i = 1; i <= maxRetirage; i++) {
coups.add(new NimPly(this.currentPlayer, i));
}
return coups.iterator();
}
@Override
public void doPly(AbstractPly c) {
if (!(c instanceof NimPly)) {
throw new IllegalArgumentException("Le coup doit être un NimPly");
}
if (!isLegal(c)) {
throw new IllegalStateException("Ce coup n'est pas légal");
}
NimPly coup = (NimPly) c;
// Retirer les allumettes
this.allumettesRestantes -= coup.getNombreAllumettesPrises();
// Ajouter le coup à l'historique
this.history.addLast(c);
// Vérifier si le jeu est terminé
if (this.allumettesRestantes == 0) {
this.gameOver = true;
// Dans la variante misère : celui qui prend la dernière allumette perd
if (this.currentPlayer == Player.PLAYER1) {
this.result = Result.LOSS;
} else {
this.result = Result.WIN;
}
}
// Changer de joueur
setNextPlayer();
}
@Override
public void undoPly() {
if (this.history.isEmpty()) {
throw new IllegalStateException("Rien à annuler dans l'historique");
}
AbstractPly dernierCoup = this.history.removeLast();
NimPly coup = (NimPly) dernierCoup;
// Remettre les allumettes
this.allumettesRestantes += coup.getNombreAllumettesPrises();
// Revenir au joueur précédent
setNextPlayer();
// Réinitialiser l'état du jeu
this.gameOver = false;
this.result = null;
}
/**
* Change le joueur courant
*/
private void setNextPlayer() {
if (this.currentPlayer == Player.PLAYER1) {
this.currentPlayer = Player.PLAYER2;
} else {
this.currentPlayer = Player.PLAYER1;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Jeu de Nim\n");
sb.append("Allumettes restantes : ").append(allumettesRestantes).append("\n");
sb.append("Maximum par coup : ").append(maxParCoup).append("\n");
sb.append("Joueur courant : ").append(currentPlayer).append("\n");
if (gameOver) {
sb.append("Jeu terminé - Résultat (du point de vue de PLAYER1) : ").append(result).append("\n");
}
return sb.toString();
}
}