/
CustomCollectionsDeckOfCardsAsList.java
114 lines (97 loc) · 3.39 KB
/
CustomCollectionsDeckOfCardsAsList.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Copyright 2022 The Bank of New York Mellon.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package bnymellon.codekatas.deckofcards.custom.collections;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Random;
import java.util.stream.IntStream;
import bnymellon.codekatas.deckofcards.Card;
import bnymellon.codekatas.deckofcards.Rank;
import bnymellon.codekatas.deckofcards.Suit;
public class CustomCollectionsDeckOfCardsAsList
{
private ImmutableList<Card> cards;
private MutableListMultimap<Suit, Card> cardsBySuit;
/**
* Use Custom Collections with {@link Card#streamCards()} to create an "immutable" List and store that in cards.
* Group all of the cards by {@link Card#suit()} into an "immutable" Map and stored that in cardsBySuit.
*/
public CustomCollectionsDeckOfCardsAsList()
{
// There are two ways to build an ImmutableList from a Stream
// this.cards = Card.streamCards().sorted().collect(ImmutableList.collector());
this.cards = ImmutableList.fromStream(Card.streamCards().sorted());
this.cardsBySuit = this.cards.groupByUnmodifiable(Card::suit);
}
public Deque<Card> shuffle(Random random)
{
// Shuffle the deck 3 times with the Random parameter and push the shuffled cards onto an ArrayDeque
return this.cards.toList()
.shuffle(random)
.shuffle(random)
.shuffle(random)
.toCollection(ArrayDeque::new, ArrayDeque::push);
}
public Set<Card> deal(Deque<Card> deque, int count)
{
var hand = MutableSet.<Card>empty();
IntStream.range(0, count).forEach(i -> hand.add(deque.pop()));
return hand;
}
public List<Set<Card>> shuffleAndDeal(Random random, int hands, int cardsPerHand)
{
var shuffled = this.shuffle(random);
return this.dealHands(shuffled, hands, cardsPerHand);
}
public List<Set<Card>> dealHands(Deque<Card> shuffled, int hands, int cardsPerHand)
{
return IntStream.range(0, hands)
.mapToObj(each -> this.deal(shuffled, cardsPerHand))
.collect(ImmutableList.collector());
}
public List<Card> diamonds()
{
return this.cardsBySuit.get(Suit.DIAMONDS);
}
public List<Card> hearts()
{
return this.cardsBySuit.get(Suit.HEARTS);
}
public List<Card> spades()
{
return this.cardsBySuit.get(Suit.SPADES);
}
public List<Card> clubs()
{
return this.cardsBySuit.get(Suit.CLUBS);
}
public Bag<Suit> countsBySuit()
{
return this.cards.countBy(Card::suit);
}
public Bag<Rank> countsByRank()
{
return this.cards.countBy(Card::rank);
}
public List<Card> getCards()
{
return this.cards;
}
public MutableListMultimap<Suit, Card> getCardsBySuit()
{
return this.cardsBySuit;
}
}