diff --git a/TP3/fr/iut_fbleau/GameAPI/AbstractGame.class b/TP3/fr/iut_fbleau/GameAPI/AbstractGame.class new file mode 100644 index 0000000..9c63903 Binary files /dev/null and b/TP3/fr/iut_fbleau/GameAPI/AbstractGame.class differ diff --git a/TP3/fr/iut_fbleau/GameAPI/AbstractGame.java b/TP3/fr/iut_fbleau/GameAPI/AbstractGame.java new file mode 100644 index 0000000..55a6acc --- /dev/null +++ b/TP3/fr/iut_fbleau/GameAPI/AbstractGame.java @@ -0,0 +1,61 @@ +package fr.iut_fbleau.GameAPI; + +import java.util.EnumMap; + +/** + * The abstract class for an Abstract Game. + * All inheriting classes should be turn taking games (see method run). + * + * The abstract game knows the model of the current game state (something implementing + * an IBoard). It handles the players by providing a map from the Player class + * (an enum for the player order in the game) to the abstractGamePlayer class + * (a class that can choose a Ply from any given position). + * + * The control loop in the run method selects the appropriate player, sends him + * what should be a copy of the current game state to help him make his decision. + * If a player returns an illegal move, an exception is thrown and the game stops. + * Otherwise, when the game finishes the method returns the result. + * + * The logic of the game rule is handled in the class IBoard. + * In particular, it is possible that the turn taking does not take form of a round + * robin and switches between players in a non uniform ad hoc fashion. + * + * Potential evolution of this class could take into account clocks for the players, + * which would be better handled here than in the Abstractboard class. + * + */ +public abstract class AbstractGame { + + // board this game is played on + private IBoard currentBoard; + + // a map from the enum Player to the genuine Player AbstractGamePlayer + private EnumMap mapPlayers; + + // constructeur à appeler dans le constructeur d'un fils concret avec super. + public AbstractGame(IBoard b, EnumMap m){ + this.currentBoard=b; + this.mapPlayers=m; + } + + /** + * boucle de contrôle du jeu. + * + * @throws IllegalStateException if a player proposes an IllegalMove at some point + * @return the Result of the game from the perspective of the first player. + */ + public Result run(){ + while(! currentBoard.isGameOver()) { + AbstractGamePlayer player = mapPlayers.get(currentBoard.getCurrentPlayer()); + IBoard board = currentBoard.safeCopy(); + AbstractPly ply = player.giveYourMove(board); + + if (currentBoard.isLegal(ply)) { + currentBoard.doPly(ply); + } + else throw new IllegalStateException("Player "+ player + " is a bloody cheat. I give up."); + } + + return currentBoard.getResult(); + } +} diff --git a/TP3/fr/iut_fbleau/GameAPI/AbstractGamePlayer.java b/TP3/fr/iut_fbleau/GameAPI/AbstractGamePlayer.java deleted file mode 100644 index be251ee..0000000 --- a/TP3/fr/iut_fbleau/GameAPI/AbstractGamePlayer.java +++ /dev/null @@ -1,26 +0,0 @@ -package fr.iut_fbleau.GameAPI; - -import java.util.Iterator; - -/** - * The abstract class for a game Player. - */ -public abstract class AbstractGamePlayer { - - // not a band, but which type of player I am in the game (PLAYER1 or PLAYER2). - private Player iAm; - - // Le joueur réel pourrait avoir besoin de connaître un constructeur de coup? - // pas pour l'instant. - - - /** - * - * - * @throws UnsupportedOperationException if the method is not yet implemented - * - * @throws IllegalStateException if the Situation is already in the bookmarks - */ - public abstract AbstractPly giveYourMove(IBoard p); - -} diff --git a/TP3/fr/iut_fbleau/GameAPI/AbstractPly.class b/TP3/fr/iut_fbleau/GameAPI/AbstractPly.class index d7e2a47..5a3a4d2 100644 Binary files a/TP3/fr/iut_fbleau/GameAPI/AbstractPly.class and b/TP3/fr/iut_fbleau/GameAPI/AbstractPly.class differ diff --git a/TP3/fr/iut_fbleau/GameAPI/AbstractPly.java b/TP3/fr/iut_fbleau/GameAPI/AbstractPly.java index f831b22..211fc6f 100644 --- a/TP3/fr/iut_fbleau/GameAPI/AbstractPly.java +++ b/TP3/fr/iut_fbleau/GameAPI/AbstractPly.java @@ -2,4 +2,13 @@ package fr.iut_fbleau.GameAPI; public abstract class AbstractPly { private Player joueur; + + // constructeur à appeler dans le constructeur d'un fils concret avec super. + public AbstractPly(Player j){ + this.joueur=j; + } + + public Player getPlayer(){ + return this.joueur; + } } diff --git a/TP3/fr/iut_fbleau/GameAPI/IBoard.class b/TP3/fr/iut_fbleau/GameAPI/IBoard.class index 5728bcd..986c0b3 100644 Binary files a/TP3/fr/iut_fbleau/GameAPI/IBoard.class and b/TP3/fr/iut_fbleau/GameAPI/IBoard.class differ diff --git a/TP3/fr/iut_fbleau/GameAPI/IBoard.java b/TP3/fr/iut_fbleau/GameAPI/IBoard.java index 2bf6d91..505e09b 100644 --- a/TP3/fr/iut_fbleau/GameAPI/IBoard.java +++ b/TP3/fr/iut_fbleau/GameAPI/IBoard.java @@ -11,7 +11,7 @@ public interface IBoard { /** * @return the current player */ - public Player getcurrentPlayer(); + public Player getCurrentPlayer(); /** * Returns the game status @@ -27,10 +27,9 @@ public interface IBoard { public Result getResult(); /** - * checker of legal moves from this position + * checker of the legality of a ply from this position * - * @throws NullPointerException if the game is over - * @return the iterator + * @return true iff the ply is legal */ public boolean isLegal(AbstractPly c); @@ -39,7 +38,6 @@ public interface IBoard { /** * constructor of Iterator over legal moves from this position * - * @throws NullPointerException if the game is over * @return the iterator */ public Iterator iterator(); @@ -48,7 +46,7 @@ public interface IBoard { /** * Plays a given move on the plateau. - * Should update history using + * * @throws IllegalArgumentException if the move is always illegal (say from the wrong game) * @throws IllegalStateException if the move is not legal in this position * @@ -60,10 +58,22 @@ public interface IBoard { /** * Resets the plateau to the position before the last move. * - * @throws IllegalStateException if nothing to undo in history + * @throws IllegalStateException if nothing to undo * */ public void undoPly(); - + /** + * Creates a safe copy of the board. + * + * Intended to prevent cheating from a human via some interface, + * or from a bot playing via the API, or from a badly coded bot. + * + * Beware that the default implantation is unsafe and returns this. + * + * @return the copy + */ + public default IBoard safeCopy(){ + return this; + } } diff --git a/TP3/fr/iut_fbleau/Nim/NimBoard.class b/TP3/fr/iut_fbleau/Nim/NimBoard.class index d690ef3..09ae5b8 100644 Binary files a/TP3/fr/iut_fbleau/Nim/NimBoard.class and b/TP3/fr/iut_fbleau/Nim/NimBoard.class differ diff --git a/TP3/fr/iut_fbleau/Nim/NimBoard.java b/TP3/fr/iut_fbleau/Nim/NimBoard.java index 586adf3..c57392c 100644 --- a/TP3/fr/iut_fbleau/Nim/NimBoard.java +++ b/TP3/fr/iut_fbleau/Nim/NimBoard.java @@ -64,7 +64,7 @@ public class NimBoard extends AbstractBoard { } @Override - public Player getcurrentPlayer() { + public Player getCurrentPlayer() { return this.currentPlayer; } @@ -196,4 +196,3 @@ public class NimBoard extends AbstractBoard { return sb.toString(); } } - diff --git a/TP3/fr/iut_fbleau/Nim/NimPly.class b/TP3/fr/iut_fbleau/Nim/NimPly.class index b37ab20..c74df15 100644 Binary files a/TP3/fr/iut_fbleau/Nim/NimPly.class and b/TP3/fr/iut_fbleau/Nim/NimPly.class differ diff --git a/TP3/fr/iut_fbleau/Nim/NimPly.java b/TP3/fr/iut_fbleau/Nim/NimPly.java index 7c6396f..4d70760 100644 --- a/TP3/fr/iut_fbleau/Nim/NimPly.java +++ b/TP3/fr/iut_fbleau/Nim/NimPly.java @@ -8,31 +8,36 @@ import fr.iut_fbleau.GameAPI.Player; * Un coup consiste à retirer un certain nombre d'allumettes. */ public class NimPly extends AbstractPly { - - private Player joueur; + private int nombreAllumettesPrises; - + + /** + * Constructeur du coup de Nim. + * + * @param joueur le joueur qui effectue le coup + * @param nombreAllumettesPrises le nombre d'allumettes retirées + */ public NimPly(Player joueur, int nombreAllumettesPrises) { - this.joueur = joueur; + super(joueur); this.nombreAllumettesPrises = nombreAllumettesPrises; } - + /** - * @return le joueur qui effectue le coup + * @return le joueur qui a joué ce coup */ public Player getJoueur() { - return this.joueur; + return super.getPlayer(); } - + /** - * @return le nombre d'allumettes prises + * @return le nombre d'allumettes retirées */ public int getNombreAllumettesPrises() { return this.nombreAllumettesPrises; } - + + @Override public String toString() { - return "Joueur " + joueur + " retire " + nombreAllumettesPrises + " allumette(s)"; + return "Le joueur " + getJoueur() + " retire " + nombreAllumettesPrises + " allumette(s)."; } } -