javass/jass/TurnState.java
2019-09-30 13:17:35 +02:00

163 lines
5.5 KiB
Java

package javass.jass;
import javass.jass.Card.Color;
import static javass.Preconditions.*;
/**
* The representation of the state of a turn during a game of Jass.
* @author Charles BEAUVILLE
* @author Celia HOUSSIAUX
*
*/
public final class TurnState {
/**
* Creates the initial state of a turn
* @param trump the trump color of the turn
* @param score the score at the beginning of the turn
* @param firstPlayer the first player of the turn
* @return the initial state of the turn
*/
public static TurnState initial(Color trump, Score score, PlayerId firstPlayer) {
long aS = score.packed();
long uC = PackedCardSet.ALL_CARDS;
int aT = PackedTrick.firstEmpty(trump, firstPlayer);
return new TurnState(aS, uC, aT);
}
/**
* Creates a new turnstate given a packed score, a packed set of unplayed cards and a packed trick.
* @param pkScore the packed version of the score the turn will have.
* @param pkUnplayedCards the packed version of the set of cards that have not yet been played during the turn.
* @param pkTrick the packed version of the trick the turn will have
* @throws IllegalArgumentException if pkScore, pkUnplayedCards and pkTrick are not valid.
* @return the new turn state with the new score, set of unplayed cards and trick.
*/
public static TurnState ofPackedComponents(long pkScore, long pkUnplayedCards, int pkTrick) {
checkArgument(PackedScore.isValid(pkScore) && PackedCardSet.isValid(pkUnplayedCards) && PackedTrick.isValid(pkTrick));
return new TurnState(pkScore, pkUnplayedCards, pkTrick);
}
private final long currentScore;
private final long unplayedCards;
private final int currentTrick;
private TurnState(long aS, long uC, int aT){
currentScore = aS;
unplayedCards = uC;
currentTrick = aT;
}
/**
* Gets the packed version of the current score of the turn.
* @return a long the packed version of the score of the turn.
*/
public long packedScore() {
return currentScore;
}
/**
* Gets the packed version of the current unplayed cards of the turn.
* @return a long the packed version of the set of unplayed cards of the turn.
*/
public long packedUnplayedCards() {
return unplayedCards;
}
/**
* Gets the packed version of the current trick of the turn.
* @return a long the packed version of the trick of the turn.
*/
public int packedTrick() {
return currentTrick;
}
/**
* Gets the current score of the turn.
* @return the score of the turn.
*/
public Score score() {
return Score.ofPacked(currentScore);
}
/**
* Gets the current CardSet of unplayed cards of the turn.
* @return the CardSet of unplayed cards of the turn.
*/
public CardSet unplayedCards() {
return CardSet.ofPacked(unplayedCards);
}
/**
* Gets the current trick of the turn.
* @return the trick of the turn.
*/
public Trick trick() {
return Trick.ofPacked(currentTrick);
}
/**
* Checks if the trick is the last one before the end of the turn.
* @return a boolean if the trick is the last one.
*/
public boolean isTerminal() {
return currentTrick == PackedTrick.INVALID;
}
/**
* Get the next player that will play in the turn.
* @throws IllegalStateException if the current trick is full.
* @return the PlayerId of the next player of the trick.
*/
public PlayerId nextPlayer() {
if(trick().isFull())
throw new IllegalStateException();
return PackedTrick.player(currentTrick, PackedTrick.size(currentTrick));
}
/**
* Compute the new turnState when a given card has been played
* @param card the card to be played
* @throws IllegalStateException if the trick is full.
* @return the new turn state with the card played
*/
public TurnState withNewCardPlayed(Card card) {
if(trick().isFull() && unplayedCards().contains(card))
throw new IllegalStateException();
return ofPackedComponents(currentScore, PackedCardSet.remove(unplayedCards, card.packed()), PackedTrick.withAddedCard(currentTrick, card.packed()));
}
/**
* Computes a new turn state after the trick has been collected, with updated score and a new trick.
* @throws IllegalStateException the trick is not full.
* @return the new turn state with the next trick and the updated score
*/
public TurnState withTrickCollected() {
if(!trick().isFull())
throw new IllegalStateException();
return new TurnState(
PackedScore.withAdditionalTrick(currentScore, PackedTrick.winningPlayer(currentTrick).team(), PackedTrick.points(currentTrick)),
unplayedCards,
PackedTrick.nextEmpty(currentTrick));
}
/**
* Computes a new turn state with a new card and collects the trick if it is full
* @param card the card to be played
* @return the new turn state when the given card is played or the trick is full
*/
public TurnState withNewCardPlayedAndTrickCollected(Card card) {
TurnState t = withNewCardPlayed(card);
if(t.trick().isFull())
t = t.withTrickCollected();
return t;
}
}