2025-09-18 15:15:37 +02:00
|
|
|
package fr.iut_fbleau.GameAPI;
|
|
|
|
|
2025-09-19 15:22:44 +02:00
|
|
|
import java.util.NoSuchElementException;
|
2025-09-18 15:15:37 +02:00
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.Deque;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An abstract class implementing the interface IBoard.
|
|
|
|
*
|
2025-09-19 09:59:13 +02:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*
|
2025-09-18 15:15:37 +02:00
|
|
|
*/
|
|
|
|
public abstract class AbstractBoard implements IBoard{
|
|
|
|
|
2025-09-19 15:22:44 +02:00
|
|
|
// the player, the turn of which it is to play.
|
2025-09-18 15:15:37 +02:00
|
|
|
private Player currentPlayer ;
|
|
|
|
|
2025-09-19 15:22:44 +02:00
|
|
|
// used as a stack.
|
2025-09-18 15:15:37 +02:00
|
|
|
private Deque<AbstractPly> history;
|
2025-10-09 11:34:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
// constructeur à appeler dans le constructeur d'un fils concret avec super.
|
|
|
|
public AbstractBoard(Player p, Deque<AbstractPly> h){
|
|
|
|
this.currentPlayer = p;
|
|
|
|
this.history = h;
|
|
|
|
}
|
|
|
|
|
2025-09-19 15:22:44 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* set current player to the other player.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
protected void setNextPlayer(){
|
2025-09-18 15:15:37 +02:00
|
|
|
if (this.currentPlayer==Player.PLAYER1){
|
|
|
|
this.currentPlayer= Player.PLAYER2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
this.currentPlayer= Player.PLAYER1;
|
|
|
|
}
|
|
|
|
|
2025-09-19 15:22:44 +02:00
|
|
|
/**
|
|
|
|
* add the given ply to history so that it becomes the last one.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
protected void addPlyToHistory(AbstractPly c){
|
|
|
|
this.history.addFirst(c);
|
2025-09-18 15:15:37 +02:00
|
|
|
}
|
|
|
|
|
2025-09-19 15:22:44 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* removes the last ply from history.
|
|
|
|
*
|
|
|
|
*@throws NoSuchElementException if empty history.
|
|
|
|
* @return the last ply from history.
|
|
|
|
*/
|
|
|
|
protected AbstractPly removePlyFromHistory(){
|
|
|
|
return this.history.removeFirst();
|
2025-09-18 15:15:37 +02:00
|
|
|
}
|
|
|
|
|
2025-09-19 15:22:44 +02:00
|
|
|
/**
|
|
|
|
* @return the last ply from history or null if none.
|
|
|
|
*/
|
|
|
|
protected AbstractPly getLastPlyFromHistory(){
|
|
|
|
return this.history.peekFirst();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-09-18 15:15:37 +02:00
|
|
|
/**
|
|
|
|
* @return the current player
|
|
|
|
*/
|
2025-09-19 09:59:13 +02:00
|
|
|
public Player getCurrentPlayer(){
|
2025-09-18 15:15:37 +02:00
|
|
|
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();
|
|
|
|
|
2025-09-19 09:59:13 +02:00
|
|
|
|
2025-09-18 15:15:37 +02:00
|
|
|
/**
|
2025-09-19 09:59:13 +02:00
|
|
|
* checker of the legality of a ply from this position
|
2025-09-18 15:15:37 +02:00
|
|
|
*
|
2025-09-19 09:59:13 +02:00
|
|
|
* @return true iff the ply is legal
|
2025-09-18 15:15:37 +02:00
|
|
|
*/
|
|
|
|
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.
|
2025-09-19 15:22:44 +02:00
|
|
|
*
|
|
|
|
* A daughter class should call super of this last if the move has been done.
|
2025-09-19 09:59:13 +02:00
|
|
|
*
|
2025-09-18 15:15:37 +02:00
|
|
|
* @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
|
|
|
|
*
|
|
|
|
*/
|
2025-09-19 15:22:44 +02:00
|
|
|
public void doPly(AbstractPly c){
|
|
|
|
// Should update history
|
|
|
|
this.addPlyToHistory(c);
|
|
|
|
// swap players
|
|
|
|
this.setNextPlayer();
|
|
|
|
}
|
2025-09-18 15:15:37 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Resets the plateau to the position before the last move.
|
|
|
|
*
|
2025-09-19 15:22:44 +02:00
|
|
|
* 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.
|
|
|
|
*
|
2025-09-18 15:15:37 +02:00
|
|
|
* @throws IllegalStateException if nothing to undo in history
|
|
|
|
*
|
|
|
|
*/
|
2025-09-19 15:22:44 +02:00
|
|
|
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();
|
|
|
|
}
|
2025-09-18 15:15:37 +02:00
|
|
|
|
2025-09-19 09:59:13 +02:00
|
|
|
/**
|
|
|
|
* creates a safe copy of the board.
|
|
|
|
*
|
|
|
|
* @return the copy
|
|
|
|
*/
|
|
|
|
public abstract IBoard safeCopy();
|
2025-09-18 15:15:37 +02:00
|
|
|
}
|