1er commit
This commit is contained in:
155
API_Prof/AbstractBoard.java
Normal file
155
API_Prof/AbstractBoard.java
Normal file
@@ -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<AbstractPly> history;
|
||||||
|
|
||||||
|
|
||||||
|
// constructeur à appeler dans le constructeur d'un fils concret avec super.
|
||||||
|
public AbstractBoard(Player p, Deque<AbstractPly> 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<AbstractPly> 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();
|
||||||
|
}
|
||||||
61
API_Prof/AbstractGame.java
Normal file
61
API_Prof/AbstractGame.java
Normal file
@@ -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<Player, AbstractGamePlayer> mapPlayers;
|
||||||
|
|
||||||
|
// constructeur à appeler dans le constructeur d'un fils concret avec super.
|
||||||
|
public AbstractGame(IBoard b, EnumMap<Player,AbstractGamePlayer> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
30
API_Prof/AbstractGamePlayer.java
Normal file
30
API_Prof/AbstractGamePlayer.java
Normal file
@@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
14
API_Prof/AbstractPly.java
Normal file
14
API_Prof/AbstractPly.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
79
API_Prof/IBoard.java
Normal file
79
API_Prof/IBoard.java
Normal file
@@ -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<AbstractPly> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
API_Prof/Player.java
Normal file
6
API_Prof/Player.java
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package fr.iut_fbleau.GameAPI;
|
||||||
|
|
||||||
|
public enum Player {
|
||||||
|
PLAYER1,
|
||||||
|
PLAYER2
|
||||||
|
}
|
||||||
11
API_Prof/Result.java
Normal file
11
API_Prof/Result.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user