deck_of_cards_handler 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +59 -0
- data/lib/deck_of_cards_handler/card/card.rb +8 -16
- data/lib/deck_of_cards_handler/packet/packet.rb +2 -2
- data/lib/deck_of_cards_handler/poker_hand.rb +123 -0
- data/lib/deck_of_cards_handler/version.rb +1 -1
- data/lib/deck_of_cards_handler.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ada5266ea6fced842e0110cfb42413202aecd0344b6e50d7e03284b148a3de12
|
4
|
+
data.tar.gz: 69e43292eb8d3476afd899093ec29391e96dcc97cc52c0378c08830c5b35b47e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b65f41b901b72be9ad9e8978b34cc2ada7f886ed5e6fe704d8fb630cd02cba94bbee162e9e09097b4496663e41cd50d251b653ed77ac9ff92bb7bb5f1458d19f
|
7
|
+
data.tar.gz: 62ce89b3c2cf352ad82a8fd3f8c2c86cfbe731cfe4c9f633b53dbd3ff6183d822d48916f6e1b5b66647c85e1e96a75038e1b00916f201119e51dc118e3cfc155
|
data/README.md
CHANGED
@@ -46,6 +46,62 @@ gem install deck_of_cards_handler
|
|
46
46
|
# assign a position value to the cards
|
47
47
|
deck.set_cards_positions
|
48
48
|
|
49
|
+
deck
|
50
|
+
# =>
|
51
|
+
# <Packet:0x000000012ae2b848
|
52
|
+
# @cards=
|
53
|
+
[#<Card:0x000000012ae2bd20 @position=1, @suit="S", @value="4">,
|
54
|
+
#<Card:0x000000012ae2cae0 @position=2, @suit="H", @value="2">,
|
55
|
+
#<Card:0x000000012ae2c220 @position=3, @suit="D", @value="7">,
|
56
|
+
#<Card:0x000000012ae2bd98 @position=4, @suit="S", @value="3">,
|
57
|
+
#<Card:0x000000012ae2c9f0 @position=5, @suit="H", @value="4">,
|
58
|
+
#<Card:0x000000012ae2c298 @position=6, @suit="D", @value="6">,
|
59
|
+
#<Card:0x000000012ae2df08 @position=7, @suit="C", @value="A">,
|
60
|
+
#<Card:0x000000012ae2c978 @position=8, @suit="H", @value="5">,
|
61
|
+
#<Card:0x000000012ae2ce00 @position=9, @suit="C", @value="9">,
|
62
|
+
#<Card:0x000000012ae2d260 @position=10, @suit="C", @value="2">,
|
63
|
+
#<Card:0x000000012ae2c630 @position=11, @suit="H", @value="Q">,
|
64
|
+
#<Card:0x000000012ae2c400 @position=12, @suit="D", @value="3">,
|
65
|
+
#<Card:0x000000012ae2b960 @position=13, @suit="S", @value="Q">,
|
66
|
+
#<Card:0x000000012ae2c810 @position=14, @suit="H", @value="8">,
|
67
|
+
#<Card:0x000000012ae2cf68 @position=15, @suit="C", @value="6">,
|
68
|
+
#<Card:0x000000012ae2cfe0 @position=16, @suit="C", @value="5">,
|
69
|
+
#<Card:0x000000012ae2c798 @position=17, @suit="H", @value="9">,
|
70
|
+
#<Card:0x000000012ae2b8e8 @position=18, @suit="S", @value="K">,
|
71
|
+
#<Card:0x000000012ae2c478 @position=19, @suit="D", @value="2">,
|
72
|
+
#<Card:0x000000012ae2c6a8 @position=20, @suit="H", @value="J">,
|
73
|
+
#<Card:0x000000012ae2d0d0 @position=21, @suit="C", @value="3">,
|
74
|
+
#<Card:0x000000012ae2ce78 @position=22, @suit="C", @value="8">,
|
75
|
+
#<Card:0x000000012ae2c900 @position=23, @suit="H", @value="6">,
|
76
|
+
#<Card:0x000000012ae2ba50 @position=24, @suit="S", @value="10">,
|
77
|
+
#<Card:0x000000012ae2c310 @position=25, @suit="D", @value="5">,
|
78
|
+
#<Card:0x000000012ae2bf50 @position=26, @suit="D", @value="K">,
|
79
|
+
#<Card:0x000000012ae2be10 @position=27, @suit="S", @value="2">,
|
80
|
+
#<Card:0x000000012ae2ca68 @position=28, @suit="H", @value="3">,
|
81
|
+
#<Card:0x000000012ae2c1a8 @position=29, @suit="D", @value="8">,
|
82
|
+
#<Card:0x000000012ae2bca8 @position=30, @suit="S", @value="5">,
|
83
|
+
#<Card:0x000000012ae2cc20 @position=31, @suit="C", @value="K">,
|
84
|
+
#<Card:0x000000012ae2c040 @position=32, @suit="D", @value="J">,
|
85
|
+
#<Card:0x000000012ae2bb40 @position=33, @suit="S", @value="8">,
|
86
|
+
#<Card:0x000000012ae2cd88 @position=34, @suit="C", @value="10">,
|
87
|
+
#<Card:0x000000012ae2c5b8 @position=35, @suit="H", @value="K">,
|
88
|
+
#<Card:0x000000012ae2b9d8 @position=36, @suit="S", @value="J">,
|
89
|
+
#<Card:0x000000012ae2cef0 @position=37, @suit="C", @value="7">,
|
90
|
+
#<Card:0x000000012ae2c720 @position=38, @suit="H", @value="10">,
|
91
|
+
#<Card:0x000000012ae2c4f0 @position=39, @suit="D", @value="A">,
|
92
|
+
#<Card:0x000000012ae2d058 @position=40, @suit="C", @value="4">,
|
93
|
+
#<Card:0x000000012ae2c888 @position=41, @suit="H", @value="7">,
|
94
|
+
#<Card:0x000000012ae2c388 @position=42, @suit="D", @value="4">,
|
95
|
+
#<Card:0x000000012ae2be88 @position=43, @suit="S", @value="A">,
|
96
|
+
#<Card:0x000000012ae2bac8 @position=44, @suit="S", @value="9">,
|
97
|
+
#<Card:0x000000012ae2cd10 @position=45, @suit="C", @value="J">,
|
98
|
+
#<Card:0x000000012ae2bfc8 @position=46, @suit="D", @value="Q">,
|
99
|
+
#<Card:0x000000012ae2bbb8 @position=47, @suit="S", @value="7">,
|
100
|
+
#<Card:0x000000012ae2cc98 @position=48, @suit="C", @value="Q">,
|
101
|
+
#<Card:0x000000012ae2c0b8 @position=49, @suit="D", @value="10">,
|
102
|
+
#<Card:0x000000012ae2bc30 @position=50, @suit="S", @value="6">,
|
103
|
+
#<Card:0x000000012ae2cb58 @position=51, @suit="H", @value="A">,
|
104
|
+
#<Card:0x000000012ae2c130 @position=52, @suit="D", @value="9">]>
|
49
105
|
```
|
50
106
|
|
51
107
|
</details>
|
@@ -68,6 +124,9 @@ gem install deck_of_cards_handler
|
|
68
124
|
deck.shuffle
|
69
125
|
|
70
126
|
hands = deck.deal_into_piles(number_of_piles: 5, number_of_cards: 5)
|
127
|
+
|
128
|
+
hands.map(&:to_s)
|
129
|
+
# => [["5 of D", "8 of C", "6 of S", "10 of D", "5 of C"], ["7 of C", "5 of S", "4 of C", "2 of D", "Q of D"], ["3 of S", "8 of D", "A of D", "2 of C", "7 of D"], ["Q of H", "4 of S", "3 of D", "J of S", "9 of S"], ["6 of C", "6 of H", "10 of C", "4 of D", "A of H"]]
|
71
130
|
```
|
72
131
|
|
73
132
|
</details>
|
@@ -50,28 +50,20 @@ class Card
|
|
50
50
|
other.suit == suit && other.value == value
|
51
51
|
end
|
52
52
|
|
53
|
-
sig {
|
54
|
-
def rank
|
53
|
+
sig { params(low_ace: T::Boolean).returns(Integer) }
|
54
|
+
def rank(low_ace: false)
|
55
55
|
case value
|
56
|
-
when "A" then
|
57
|
-
when "J" then
|
58
|
-
when "Q" then
|
59
|
-
when "K" then
|
60
|
-
else
|
56
|
+
when "A" then low_ace ? 1 : 14
|
57
|
+
when "J" then 11
|
58
|
+
when "Q" then 12
|
59
|
+
when "K" then 13
|
60
|
+
else value.to_i
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
sig { params(other: Card).returns(Integer) }
|
65
65
|
def <=>(other)
|
66
|
-
|
67
|
-
my_ranks = rank
|
68
|
-
other_ranks = other.rank
|
69
|
-
|
70
|
-
# check if any ranks overlap (Ace == 1 or 14)
|
71
|
-
return 0 if (my_ranks & other_ranks).any?
|
72
|
-
|
73
|
-
# otherwise compare by highest possible
|
74
|
-
T.must(my_ranks.max) <=> T.must(other_ranks.max)
|
66
|
+
rank <=> other.rank
|
75
67
|
end
|
76
68
|
|
77
69
|
class << self
|
@@ -52,9 +52,9 @@ class Packet
|
|
52
52
|
packet
|
53
53
|
end
|
54
54
|
|
55
|
-
sig { params(string: String).returns(Packet) }
|
55
|
+
sig { overridable.params(string: String).returns(Packet) }
|
56
56
|
def build_from_string(string:) # rubocop:disable Metrics
|
57
|
-
content = string.split(",")
|
57
|
+
content = string.split(",").map(&:strip)
|
58
58
|
cards = []
|
59
59
|
cards_set = Set.new
|
60
60
|
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# This represents a poker hands raking
|
5
|
+
class PokerHand < Packet
|
6
|
+
extend T::Sig
|
7
|
+
extend T::Helpers
|
8
|
+
|
9
|
+
sig { params(cards: T::Array[Card]).void }
|
10
|
+
def initialize(cards:)
|
11
|
+
raise ArgumentError if cards.size != 5
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
sig { override.params(string: String).returns(PokerHand) }
|
18
|
+
def build_from_string(string:)
|
19
|
+
result = super
|
20
|
+
PokerHand.new(cards: result.cards)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
HAND_RANKS = T.let(
|
25
|
+
{
|
26
|
+
nothing: 0,
|
27
|
+
pair: 1,
|
28
|
+
two_pairs: 2,
|
29
|
+
three_of_a_kind: 3,
|
30
|
+
straight: 4,
|
31
|
+
flush: 5,
|
32
|
+
full_house: 6,
|
33
|
+
four_of_a_kind: 7,
|
34
|
+
straight_flush: 8
|
35
|
+
}.freeze, T::Hash[Symbol, Integer]
|
36
|
+
)
|
37
|
+
|
38
|
+
sig { returns(Integer) }
|
39
|
+
def rank # rubocop:disable Metrics
|
40
|
+
return T.must(HAND_RANKS[:straight_flush]) if straight_flush?
|
41
|
+
return T.must(HAND_RANKS[:four_of_a_kind]) if four_of_a_kind?
|
42
|
+
return T.must(HAND_RANKS[:full_house]) if full_house?
|
43
|
+
return T.must(HAND_RANKS[:flush]) if flush?
|
44
|
+
return T.must(HAND_RANKS[:straight]) if straight?
|
45
|
+
return T.must(HAND_RANKS[:three_of_a_kind]) if three_of_a_kind?
|
46
|
+
return T.must(HAND_RANKS[:two_pairs]) if two_pairs?
|
47
|
+
return T.must(HAND_RANKS[:pair]) if pair?
|
48
|
+
|
49
|
+
T.must(HAND_RANKS[:nothing])
|
50
|
+
end
|
51
|
+
|
52
|
+
sig { returns(T::Boolean) }
|
53
|
+
def pair?
|
54
|
+
validate_hand_size
|
55
|
+
|
56
|
+
counts = cards.map(&:rank).flatten.tally
|
57
|
+
counts.values.count(2) == 1
|
58
|
+
end
|
59
|
+
|
60
|
+
sig { returns(T::Boolean) }
|
61
|
+
def two_pairs?
|
62
|
+
validate_hand_size
|
63
|
+
|
64
|
+
counts = cards.map(&:rank).flatten.tally
|
65
|
+
counts.values.count(2) == 2
|
66
|
+
end
|
67
|
+
|
68
|
+
sig { returns(T::Boolean) }
|
69
|
+
def three_of_a_kind?
|
70
|
+
validate_hand_size
|
71
|
+
|
72
|
+
counts = cards.map(&:rank).flatten.tally
|
73
|
+
counts.values.count(3) == 1
|
74
|
+
end
|
75
|
+
|
76
|
+
sig { returns(T::Boolean) }
|
77
|
+
def straight? # rubocop:disable Metrics/AbcSize
|
78
|
+
validate_hand_size
|
79
|
+
|
80
|
+
ranks = cards.map(&:rank).sort
|
81
|
+
return true if ranks.each_cons(2).all? { |a, b| b == T.must(a) + 1 }
|
82
|
+
|
83
|
+
ranks = cards.map { _1.rank(low_ace: true) }
|
84
|
+
ranks.each_cons(2).all? { |a, b| b == T.must(a) + 1 }
|
85
|
+
end
|
86
|
+
|
87
|
+
sig { returns(T::Boolean) }
|
88
|
+
def flush?
|
89
|
+
validate_hand_size
|
90
|
+
|
91
|
+
suit = T.must(cards.first).suit
|
92
|
+
cards.all? { _1.suit == suit }
|
93
|
+
end
|
94
|
+
|
95
|
+
sig { returns(T::Boolean) }
|
96
|
+
def full_house?
|
97
|
+
validate_hand_size
|
98
|
+
|
99
|
+
three_of_a_kind? && pair?
|
100
|
+
end
|
101
|
+
|
102
|
+
sig { returns(T::Boolean) }
|
103
|
+
def four_of_a_kind?
|
104
|
+
validate_hand_size
|
105
|
+
|
106
|
+
counts = cards.map(&:rank).flatten.tally
|
107
|
+
counts.values.count(4) == 1
|
108
|
+
end
|
109
|
+
|
110
|
+
sig { returns(T::Boolean) }
|
111
|
+
def straight_flush?
|
112
|
+
validate_hand_size
|
113
|
+
|
114
|
+
straight? && flush?
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
sig { void }
|
120
|
+
def validate_hand_size
|
121
|
+
raise StandardError unless size == 5
|
122
|
+
end
|
123
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deck_of_cards_handler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Bernard
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- lib/deck_of_cards_handler/packet/deals.rb
|
76
76
|
- lib/deck_of_cards_handler/packet/packet.rb
|
77
77
|
- lib/deck_of_cards_handler/packet/shuffles.rb
|
78
|
+
- lib/deck_of_cards_handler/poker_hand.rb
|
78
79
|
- lib/deck_of_cards_handler/version.rb
|
79
80
|
- sig/deck_of_cards.rbs
|
80
81
|
- sorbet/config
|