From: phfr24 Date: Mon, 10 Aug 2026 00:59:39 +0000 (-0300) Subject: add Depot X-Git-Url: https://git.wirehaze.ovh/solitaire.git/commitdiff_plain/626d75d21593081644437dc6fa7392d6990df782?hp=7cd86679b79a117283843210ae45ed1e78079e97 add Depot --- diff --git a/src/solitaire/Depot.java b/src/solitaire/Depot.java new file mode 100644 index 0000000..ad99aff --- /dev/null +++ b/src/solitaire/Depot.java @@ -0,0 +1,90 @@ +package solitaire; + +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +final class Depot { + private final List cards; + + Depot(List cards) { + if (cards.isEmpty()) + throw new IllegalArgumentException("Depot should be initialized with at least one card"); + + this.cards = new LinkedList<>(cards); + this.cards.getLast().reveal(); + } + + private static boolean isValidNextCard(Card lastCard, Card nextCard) { + if (nextCard.getSuit().isRed() == lastCard.getSuit().isRed()) + return false; + + return lastCard.getRank().isSuccessorOf(nextCard.getRank()); + } + + private boolean isValidPlacement(Card card) { + if (cards.isEmpty()) + return card.getRank() == Rank.KING; + + return isValidNextCard(cards.getLast(), card); + } + + private static boolean isValidRun(List run) { + Card prev = null; + + for (Card next : run) { + if (next.isHidden() || (prev != null && !isValidNextCard(prev, next))) + return false; + + prev = next; + } + + return true; + } + + boolean add(List run) { + /* + * no invalid run can be generated by the game, so we only need to check + * placement. + */ + if (!isValidPlacement(run.getFirst())) + return false; + + cards.addAll(run); + return true; + } + + boolean add(Card card) { + return add(List.of(card)); + } + + Optional> remove(int size) { + if (size < 1) + throw new IllegalArgumentException("Size must be a positive integer"); + + if (cards.size() < size) + return Optional.empty(); + + List slice = cards.subList(cards.size() - size, cards.size()); + + if (!isValidRun(slice)) + return Optional.empty(); + + List run = List.copyOf(slice); + slice.clear(); + + if (!cards.isEmpty()) + cards.getLast().reveal(); + + return Optional.of(run); + } + + @Override + public String toString() { + if (cards.isEmpty()) + return "< >"; + + return cards.stream().map(String::valueOf).collect(Collectors.joining("\n")); + } +} diff --git a/src/solitaire/Foundation.java b/src/solitaire/Foundation.java index 54d4162..af97510 100644 --- a/src/solitaire/Foundation.java +++ b/src/solitaire/Foundation.java @@ -20,20 +20,16 @@ final class Foundation { return cards.size() == Rank.RANKS.size(); } - private boolean isValidNextCard(Card card) { - Rank cardRank, lastRank; - - if (card.getSuit() != this.suit) + private boolean isValidNextCard(Card nextCard) { + if (nextCard.getSuit() != this.suit) return false; - cardRank = card.getRank(); - if (cards.isEmpty()) - return cardRank == Rank.ACE; + return nextCard.getRank() == Rank.ACE; - lastRank = cards.getLast().getRank(); + Card lastCard = cards.getLast(); - return cardRank.isSuccessorOf(lastRank); + return nextCard.getRank().isSuccessorOf(lastCard.getRank()); } boolean add(Card card) {