]> wirehaze git hosting - solitaire.git/commitdiff

wirehaze git hosting

add Depot
authorphfr24 <phfr24@inf.ufpr.br>
Mon, 10 Aug 2026 00:59:39 +0000 (21:59 -0300)
committerphfr24 <phfr24@inf.ufpr.br>
Mon, 10 Aug 2026 00:59:39 +0000 (21:59 -0300)
src/solitaire/Depot.java [new file with mode: 0644]
src/solitaire/Foundation.java

diff --git a/src/solitaire/Depot.java b/src/solitaire/Depot.java
new file mode 100644 (file)
index 0000000..ad99aff
--- /dev/null
@@ -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<Card> cards;
+
+    Depot(List<Card> 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<Card> 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<Card> 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<List<Card>> remove(int size) {
+       if (size < 1)
+           throw new IllegalArgumentException("Size must be a positive integer");
+
+       if (cards.size() < size)
+           return Optional.empty();
+
+       List<Card> slice = cards.subList(cards.size() - size, cards.size());
+
+       if (!isValidRun(slice))
+           return Optional.empty();
+
+       List<Card> 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"));
+    }
+}
index 54d4162f00abe31f459f536c8bb9bcec8d389e73..af9751084cae537a917447687f7799c87417d6ac 100644 (file)
@@ -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) {