add more ways to construct a combination

main
jbb01 2 years ago
parent 0d1f51d868
commit 681942e02d

@ -1,18 +1,23 @@
package eu.jonahbauer.tichu.common.model; package eu.jonahbauer.tichu.common.model;
import eu.jonahbauer.tichu.common.model.combinations.*;
import eu.jonahbauer.tichu.common.model.exceptions.InvalidCombinationException;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
import java.util.function.Function;
/** /**
* A type of combination. * A type of combination.
*/ */
@RequiredArgsConstructor
public enum CombinationType { public enum CombinationType {
/** /**
* A single card, {@linkplain Card#isNormal() normal} or {@linkplain Card#isSpecial() special}. This is the * A single card, {@linkplain Card#isNormal() normal} or {@linkplain Card#isSpecial() special}. This is the
* correct {@code CombinationType} for playing the {@link Card#HOUND} or {@link Card#DRAGON}. * correct {@code CombinationType} for playing the {@link Card#HOUND} or {@link Card#DRAGON}.
*/ */
SINGLE { SINGLE(Single.class, Single::of) {
private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX, Card.MAHJONG, Card.DRAGON, Card.HOUND); private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX, Card.MAHJONG, Card.DRAGON, Card.HOUND);
@Override @Override
@ -24,7 +29,7 @@ public enum CombinationType {
* A pair, i.e. two {@linkplain Card#isNormal() normal cards} of the same {@linkplain Card#value() value} or the * A pair, i.e. two {@linkplain Card#isNormal() normal cards} of the same {@linkplain Card#value() value} or the
* {@link Card#PHOENIX} and a normal card. * {@link Card#PHOENIX} and a normal card.
*/ */
PAIR { PAIR(Pair.class, Pair::of) {
private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX); private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX);
private static final int[] INDICES = new int[] {0, 1}; private static final int[] INDICES = new int[] {0, 1};
@ -38,7 +43,7 @@ public enum CombinationType {
* A triple, i.e. three {@linkplain Card#isNormal() normal cards} of the same {@linkplain Card#value() value} * A triple, i.e. three {@linkplain Card#isNormal() normal cards} of the same {@linkplain Card#value() value}
* or the {@linkplain Card#PHOENIX} and two normal cards of the same value. * or the {@linkplain Card#PHOENIX} and two normal cards of the same value.
*/ */
TRIPLE { TRIPLE(Triple.class, Triple::of) {
private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX); private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX);
private static final int[] INDICES = new int[] {0, 1, 2}; private static final int[] INDICES = new int[] {0, 1, 2};
@ -53,7 +58,7 @@ public enum CombinationType {
* @apiNote A list of cards representing a full house must have the triple at the first three indices and the pair * @apiNote A list of cards representing a full house must have the triple at the first three indices and the pair
* at the last two. This prevents any ambiguity, e.g. when the full house consists of two pairs and the phoenix. * at the last two. This prevents any ambiguity, e.g. when the full house consists of two pairs and the phoenix.
*/ */
FULL_HOUSE { FULL_HOUSE(FullHouse.class, FullHouse::of) {
private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX); private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX);
private static final int[] INDICES_TRIPLE = new int[] {0, 1, 2}; private static final int[] INDICES_TRIPLE = new int[] {0, 1, 2};
@ -72,7 +77,7 @@ public enum CombinationType {
* @apiNote A list of cards representing a sequence must be sorted by ascending value. This allows to distinguish * @apiNote A list of cards representing a sequence must be sorted by ascending value. This allows to distinguish
* between a sequence starting with the phoenix and a sequence ending with the phoenix. * between a sequence starting with the phoenix and a sequence ending with the phoenix.
*/ */
SEQUENCE { SEQUENCE(SingleSequence.class, SingleSequence::of) {
private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX, Card.MAHJONG); private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX, Card.MAHJONG);
private int getStartValue(@NotNull List<@NotNull Card> cards) { private int getStartValue(@NotNull List<@NotNull Card> cards) {
@ -107,7 +112,7 @@ public enum CombinationType {
* @apiNote Although not strictly necessary, for consistency with {@link #SEQUENCE} a list of cards representing * @apiNote Although not strictly necessary, for consistency with {@link #SEQUENCE} a list of cards representing
* a sequence of pairs must be sorted by ascending value. * a sequence of pairs must be sorted by ascending value.
*/ */
PAIR_SEQUENCE { PAIR_SEQUENCE(PairSequence.class, PairSequence::of) {
private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX); private static final Set<Card> SPECIAL_CARDS = EnumSet.of(Card.PHOENIX);
private int getStartValue(@NotNull List<@NotNull Card> cards) { private int getStartValue(@NotNull List<@NotNull Card> cards) {
@ -137,7 +142,7 @@ public enum CombinationType {
/** /**
* A bomb, i.e. four {@linkplain Card#isNormal() normal cards} of the same {@linkplain Card#value() value}. * A bomb, i.e. four {@linkplain Card#isNormal() normal cards} of the same {@linkplain Card#value() value}.
*/ */
BOMB { BOMB(BombTuple.class, BombTuple::of) {
private static final int[] INDICES = new int[] {0, 1, 2, 3}; private static final int[] INDICES = new int[] {0, 1, 2, 3};
private static final Set<Card> SPECIAL_CARDS = Collections.emptySet(); private static final Set<Card> SPECIAL_CARDS = Collections.emptySet();
@ -154,7 +159,7 @@ public enum CombinationType {
* bomb sequence must be sorted by ascending value. * bomb sequence must be sorted by ascending value.
* @apiNote * @apiNote
*/ */
BOMB_SEQUENCE { BOMB_SEQUENCE(BombSequence.class, BombSequence::of) {
private static final Set<Card> SPECIAL_CARDS = Collections.emptySet(); private static final Set<Card> SPECIAL_CARDS = Collections.emptySet();
private int getStartValue(@NotNull List<@NotNull Card> cards) { private int getStartValue(@NotNull List<@NotNull Card> cards) {
@ -179,14 +184,48 @@ public enum CombinationType {
} }
}; };
private final @NotNull Class<? extends Combination> combinationClass;
private final @NotNull Function<@NotNull List<@NotNull Card>, @NotNull Combination> factory;
/** /**
* Checks whether the given cards form a valid combination of this type. See the documentation of a specific * Checks whether the given cards form a valid combination of this type. See the documentation of a specific
* {@code CombinationType} for more information on what cards form a combination of that particular type. * {@code CombinationType} for more information on what cards form a combination of that particular type.
* @param cards a list of cards * @param cards a list of cards
* @return {@code true} if the cards form a valid combination of this type. * @return {@code true} if the cards form a valid combination of this type.
* @throws NullPointerException if the list or any of its elements are {@code null}.
*/ */
public abstract boolean check(@NotNull List<@NotNull Card> cards); public abstract boolean check(@NotNull List<@NotNull Card> cards);
/**
* Creates a new combination of this type consisting of the given cards.
* @param cards a list of cards forming a {@linkplain #check(List) valid} combination
* @return a new combination.
* @throws InvalidCombinationException if the given cards do not form a valid combination.
* @throws NullPointerException if the list or any of its elements are {@code null}.
*/
public @NotNull Combination of(@NotNull List<@NotNull Card> cards) {
return factory.apply(cards);
}
/**
* Creates a new combination of this type consisting of the given cards.
* @param cards a list of cards forming a {@linkplain #check(List) valid} combination
* @return a new combination.
* @throws InvalidCombinationException if the given cards do not form a valid combination.
* @throws NullPointerException if the list or any of its elements are {@code null}.
*/
public @NotNull Combination of(@NotNull Card @NotNull... cards) {
return of(List.of(cards));
}
/**
* Returns the class representing a combination of this type.
* @return the class representing a combination of this type.
*/
public @NotNull Class<? extends Combination> getCombinationClass() {
return combinationClass;
}
//<editor-fold desc="Utility Methods" defaultstate="collapsed"> //<editor-fold desc="Utility Methods" defaultstate="collapsed">
/** /**
* Performs basic checks on a list of cards, i.e. this method checks * Performs basic checks on a list of cards, i.e. this method checks

@ -3,6 +3,7 @@ package eu.jonahbauer.tichu.common.model.combinations;
import eu.jonahbauer.tichu.common.model.Card; import eu.jonahbauer.tichu.common.model.Card;
import eu.jonahbauer.tichu.common.model.CombinationType; import eu.jonahbauer.tichu.common.model.CombinationType;
import eu.jonahbauer.tichu.common.model.Stack; import eu.jonahbauer.tichu.common.model.Stack;
import eu.jonahbauer.tichu.common.model.exceptions.InvalidCombinationException;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range; import org.jetbrains.annotations.Range;
@ -79,9 +80,11 @@ public sealed interface Combination extends Serializable permits AbstractCombina
/** /**
* Creates a new combination of the given type consisting of the given cards. * Creates a new combination of the given type consisting of the given cards.
* @param type a combination type
* @param cards a list of cards forming a {@linkplain CombinationType#check(List) valid} combination * @param cards a list of cards forming a {@linkplain CombinationType#check(List) valid} combination
* @return a new combination * @param type a combination type
* @return a new combination.
* @throws InvalidCombinationException if the given cards do not form a valid combination.
* @throws NullPointerException if the type, the list or any of its elements are {@code null}.
*/ */
@Contract("_, _ -> new") @Contract("_, _ -> new")
static Combination of(@NotNull CombinationType type, @NotNull List<@NotNull Card> cards) { static Combination of(@NotNull CombinationType type, @NotNull List<@NotNull Card> cards) {

Loading…
Cancel
Save