control loop in AbstractGame + minor update in API documentation + minor change of name in a getter

This commit is contained in:
2025-09-19 09:59:13 +02:00
parent bb2b77d208
commit f7f50f9ca8
3 changed files with 95 additions and 18 deletions

View File

@@ -6,9 +6,13 @@ import java.util.Deque;
/** /**
* An abstract class implementing the interface IBoard. * An abstract class implementing the interface IBoard.
* *
* used to implement some things to do with the update of the next player * It is used to implement some things to do with the update of the next player
* which is the same for all games and provides also a minimal * which is the same for all turn taking games using a round robin and provides
* implantation of the history mechanism. * also a minimal implantation of the history mechanism.
*
* The current implantation works only for two players.
*
*
*/ */
public abstract class AbstractBoard implements IBoard{ public abstract class AbstractBoard implements IBoard{
@@ -40,7 +44,7 @@ public abstract class AbstractBoard implements IBoard{
/** /**
* @return the current player * @return the current player
*/ */
public Player getcurrentPlayer(){ public Player getCurrentPlayer(){
return this.currentPlayer; return this.currentPlayer;
} }
@@ -57,20 +61,18 @@ public abstract class AbstractBoard implements IBoard{
*/ */
public abstract Result getResult(); public abstract 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 true iff the ply is legal
* @return the iterator
*/ */
public abstract boolean isLegal(AbstractPly c); public abstract boolean isLegal(AbstractPly c);
/** /**
* constructor of Iterator over legal moves from this position * constructor of Iterator over legal moves from this position
* *
* @throws NullPointerException if the game is over
* @return the iterator * @return the iterator
*/ */
public abstract Iterator<AbstractPly> iterator(); public abstract Iterator<AbstractPly> iterator();
@@ -79,7 +81,8 @@ public abstract class AbstractBoard implements IBoard{
/** /**
* Plays a given move on the plateau. * Plays a given move on the plateau.
* Should update history using * Should update history using removePlyFromHistory
*
* @throws IllegalArgumentException if the move is always illegal (say from the wrong game) * @throws IllegalArgumentException if the move is always illegal (say from the wrong game)
* @throws IllegalStateException if the move is not legal in this position * @throws IllegalStateException if the move is not legal in this position
* *
@@ -96,4 +99,10 @@ public abstract class AbstractBoard implements IBoard{
*/ */
public abstract void undoPly(); public abstract void undoPly();
/**
* creates a safe copy of the board.
*
* @return the copy
*/
public abstract IBoard safeCopy();
} }

View File

@@ -0,0 +1,58 @@
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<Player, AbstractGamePlayer> mapPlayers;
//NB. pas de constructeur possible on est abstrait, il faut faire une usine abstraite.
/**
* 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();
}
}

View File

@@ -11,7 +11,7 @@ public interface IBoard {
/** /**
* @return the current player * @return the current player
*/ */
public Player getcurrentPlayer(); public Player getCurrentPlayer();
/** /**
* Returns the game status * Returns the game status
@@ -27,10 +27,9 @@ public interface IBoard {
public Result getResult(); 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 true iff the ply is legal
* @return the iterator
*/ */
public boolean isLegal(AbstractPly c); public boolean isLegal(AbstractPly c);
@@ -39,7 +38,6 @@ public interface IBoard {
/** /**
* constructor of Iterator over legal moves from this position * constructor of Iterator over legal moves from this position
* *
* @throws NullPointerException if the game is over
* @return the iterator * @return the iterator
*/ */
public Iterator<AbstractPly> iterator(); public Iterator<AbstractPly> iterator();
@@ -48,7 +46,7 @@ public interface IBoard {
/** /**
* Plays a given move on the plateau. * 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 IllegalArgumentException if the move is always illegal (say from the wrong game)
* @throws IllegalStateException if the move is not legal in this position * @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. * 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(); 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;
}
} }