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; } }