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

wirehaze git hosting

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