commit 8f38a511a3a2fa45569fe051b48057152f9bb52e Author: gentil Date: Thu Oct 16 10:19:29 2025 +0200 importation de l'API #2 diff --git a/javaAPI/fr/iut_fbleau/GameAPI/AbstractBoard.java b/javaAPI/fr/iut_fbleau/GameAPI/AbstractBoard.java new file mode 100644 index 0000000..95542ae --- /dev/null +++ b/javaAPI/fr/iut_fbleau/GameAPI/AbstractBoard.java @@ -0,0 +1,155 @@ +package fr.iut_fbleau.GameAPI; + +import java.util.NoSuchElementException; +import java.util.Iterator; +import java.util.Deque; + +/** + * An abstract class implementing the interface IBoard. + * + * It is used to implement some things to do with the update of the next player + * which is the same for all turn taking games using a round robin and provides + * also a minimal implantation of the history mechanism. + * + * The current implantation works only for two players. + * + * + */ +public abstract class AbstractBoard implements IBoard{ + + // the player, the turn of which it is to play. + private Player currentPlayer ; + + // used as a stack. + private Deque history; + + + // constructeur à appeler dans le constructeur d'un fils concret avec super. + public AbstractBoard(Player p, Deque h){ + this.currentPlayer = p; + this.history = h; + } + + + /** + * set current player to the other player. + * + */ + protected void setNextPlayer(){ + if (this.currentPlayer==Player.PLAYER1){ + this.currentPlayer= Player.PLAYER2; + } + else + this.currentPlayer= Player.PLAYER1; + } + + /** + * add the given ply to history so that it becomes the last one. + * + */ + protected void addPlyToHistory(AbstractPly c){ + this.history.addFirst(c); + } + + + /** + * removes the last ply from history. + * + *@throws NoSuchElementException if empty history. + * @return the last ply from history. + */ + protected AbstractPly removePlyFromHistory(){ + return this.history.removeFirst(); + } + + /** + * @return the last ply from history or null if none. + */ + protected AbstractPly getLastPlyFromHistory(){ + return this.history.peekFirst(); + } + + + /** + * @return the current player + */ + public Player getCurrentPlayer(){ + return this.currentPlayer; + } + + /** + * Returns the game status + * + * @return true iff the game is over + */ + public abstract boolean isGameOver(); + + /** + * + * @return the result (null if not over) + */ + public abstract Result getResult(); + + + /** + * checker of the legality of a ply from this position + * + * @return true iff the ply is legal + */ + public abstract boolean isLegal(AbstractPly c); + + + /** + * constructor of Iterator over legal moves from this position + * + * @return the iterator + */ + public abstract Iterator iterator(); + + + + /** + * Plays a given move on the plateau. + * + * A daughter class should call super of this last if the move has been done. + * + * @throws IllegalArgumentException if the move is always illegal (say from the wrong game) + * @throws IllegalStateException if the move is not legal in this position + * + * @param AbstractPly to be played + * + */ + public void doPly(AbstractPly c){ + // Should update history + this.addPlyToHistory(c); + // swap players + this.setNextPlayer(); + } + + /** + * Resets the plateau to the position before the last move. + * + * A daughter class should probably overwrite this class, but use this code as a base, as it will need to know the ply that needs to be undone. + * + * @throws IllegalStateException if nothing to undo in history + * + */ + public void undoPly(){ + AbstractPly p; + try{ + p=this.removePlyFromHistory(); + } + catch(NoSuchElementException e) { + throw new IllegalStateException("No ply in history, nothing can be undone"); + } + // swap players (works for two players, fairly dangerous if more players, great for a test exam). + this.setNextPlayer(); + } + + /** + * creates a safe copy of the board. + * + * @return the copy + */ + public abstract IBoard safeCopy(); +} diff --git a/javaAPI/fr/iut_fbleau/GameAPI/AbstractGame.java b/javaAPI/fr/iut_fbleau/GameAPI/AbstractGame.java new file mode 100644 index 0000000..55a6acc --- /dev/null +++ b/javaAPI/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/javaAPI/fr/iut_fbleau/GameAPI/AbstractGamePlayer.java b/javaAPI/fr/iut_fbleau/GameAPI/AbstractGamePlayer.java new file mode 100644 index 0000000..c459eab --- /dev/null +++ b/javaAPI/fr/iut_fbleau/GameAPI/AbstractGamePlayer.java @@ -0,0 +1,30 @@ +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. + + // constructeur à appeler dans le constructeur d'un fils concret avec super. + public AbstractGamePlayer(Player p){ + this.iAm=p; + } + + /** + * + * + * @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/javaAPI/fr/iut_fbleau/GameAPI/AbstractPly.java b/javaAPI/fr/iut_fbleau/GameAPI/AbstractPly.java new file mode 100644 index 0000000..211fc6f --- /dev/null +++ b/javaAPI/fr/iut_fbleau/GameAPI/AbstractPly.java @@ -0,0 +1,14 @@ +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/javaAPI/fr/iut_fbleau/GameAPI/IBoard.java b/javaAPI/fr/iut_fbleau/GameAPI/IBoard.java new file mode 100644 index 0000000..505e09b --- /dev/null +++ b/javaAPI/fr/iut_fbleau/GameAPI/IBoard.java @@ -0,0 +1,79 @@ +package fr.iut_fbleau.GameAPI; + +import java.util.Iterator; + +/** + * The interface Board. + */ +public interface IBoard { + + + /** + * @return the current player + */ + public Player getCurrentPlayer(); + + /** + * Returns the game status + * + * @return true iff the game is over + */ + public boolean isGameOver(); + + /** + * + * @return the result (null if not over) + */ + public Result getResult(); + + /** + * checker of the legality of a ply from this position + * + * @return true iff the ply is legal + */ + public boolean isLegal(AbstractPly c); + + + + /** + * constructor of Iterator over legal moves from this position + * + * @return the iterator + */ + public Iterator iterator(); + + + + /** + * Plays a given move on the plateau. + * + * @throws IllegalArgumentException if the move is always illegal (say from the wrong game) + * @throws IllegalStateException if the move is not legal in this position + * + * @param AbstractPly to be played + * + */ + public void doPly(AbstractPly c); + + /** + * Resets the plateau to the position before the last move. + * + * @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/javaAPI/fr/iut_fbleau/GameAPI/Player.java b/javaAPI/fr/iut_fbleau/GameAPI/Player.java new file mode 100644 index 0000000..2831093 --- /dev/null +++ b/javaAPI/fr/iut_fbleau/GameAPI/Player.java @@ -0,0 +1,6 @@ +package fr.iut_fbleau.GameAPI; + +public enum Player { + PLAYER1, + PLAYER2 +} diff --git a/javaAPI/fr/iut_fbleau/GameAPI/Result.java b/javaAPI/fr/iut_fbleau/GameAPI/Result.java new file mode 100644 index 0000000..9417e13 --- /dev/null +++ b/javaAPI/fr/iut_fbleau/GameAPI/Result.java @@ -0,0 +1,11 @@ +package fr.iut_fbleau.GameAPI; + +/** + * To output the result of a 2 player game that is symmetric. + * from the perspective of the player PLAYER1. + */ +public enum Result { + WIN, + DRAW, + LOSS; +}