]> wirehaze git hosting - solitaire.git/blob - src/solitaire/Depot.java

wirehaze git hosting

add Depot
[solitaire.git] / src / solitaire / Depot.java
1 package solitaire;
2
3 import java.util.LinkedList;
4 import java.util.List;
5 import java.util.Optional;
6 import java.util.stream.Collectors;
7
8 final class Depot {
9 private final List<Card> cards;
10
11 Depot(List<Card> cards) {
12 if (cards.isEmpty())
13 throw new IllegalArgumentException("Depot should be initialized with at least one card");
14
15 this.cards = new LinkedList<>(cards);
16 this.cards.getLast().reveal();
17 }
18
19 private static boolean isValidNextCard(Card lastCard, Card nextCard) {
20 if (nextCard.getSuit().isRed() == lastCard.getSuit().isRed())
21 return false;
22
23 return lastCard.getRank().isSuccessorOf(nextCard.getRank());
24 }
25
26 private boolean isValidPlacement(Card card) {
27 if (cards.isEmpty())
28 return card.getRank() == Rank.KING;
29
30 return isValidNextCard(cards.getLast(), card);
31 }
32
33 private static boolean isValidRun(List<Card> run) {
34 Card prev = null;
35
36 for (Card next : run) {
37 if (next.isHidden() || (prev != null && !isValidNextCard(prev, next)))
38 return false;
39
40 prev = next;
41 }
42
43 return true;
44 }
45
46 boolean add(List<Card> run) {
47 /*
48 * no invalid run can be generated by the game, so we only need to check
49 * placement.
50 */
51 if (!isValidPlacement(run.getFirst()))
52 return false;
53
54 cards.addAll(run);
55 return true;
56 }
57
58 boolean add(Card card) {
59 return add(List.of(card));
60 }
61
62 Optional<List<Card>> remove(int size) {
63 if (size < 1)
64 throw new IllegalArgumentException("Size must be a positive integer");
65
66 if (cards.size() < size)
67 return Optional.empty();
68
69 List<Card> slice = cards.subList(cards.size() - size, cards.size());
70
71 if (!isValidRun(slice))
72 return Optional.empty();
73
74 List<Card> run = List.copyOf(slice);
75 slice.clear();
76
77 if (!cards.isEmpty())
78 cards.getLast().reveal();
79
80 return Optional.of(run);
81 }
82
83 @Override
84 public String toString() {
85 if (cards.isEmpty())
86 return "< >";
87
88 return cards.stream().map(String::valueOf).collect(Collectors.joining("\n"));
89 }
90 }