holdem 1.0.1 → 1.1.0
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 +5 -5
- data/README.md +8 -8
- data/holdem.gemspec +4 -4
- data/lib/holdem/card.rb +28 -26
- data/lib/holdem/card_generator.rb +10 -8
- data/lib/holdem/deck.rb +16 -14
- data/lib/holdem/poker_hand.rb +32 -30
- data/lib/holdem/poker_rank.rb +144 -139
- data/lib/holdem/version.rb +1 -1
- data/lib/holdem.rb +0 -2
- data/test/card_test.rb +10 -10
- data/test/deck_test.rb +2 -2
- data/test/poker_hand_test.rb +13 -13
- data/test/poker_rank_test.rb +33 -34
- metadata +13 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 92cbd539b57a476cbfb641feded5f46b1301582b9217e85b01bd6eeb9cc0756b
|
4
|
+
data.tar.gz: 583437e52a957684f41b1eefc199ad20c61d8d87357d423c9da47872698575f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 811078542e6aeb58d340f8c1713551ac15b5f37ce4207f6f1d03a5569a92fa1aef6f44e80554309b96677863e90ab8ba9e143c4ccde6c7e269a79fb8333e06c8
|
7
|
+
data.tar.gz: 24fe1195115613d30c418e7c6c58150ef390b08d18fdfac5a6f20186199fd31e8cd6c884a9058ae5e23d5775f74e5fad62c7316c33a7616276ba67590d0fc3e2
|
data/README.md
CHANGED
@@ -20,12 +20,12 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
require 'holdem'
|
22
22
|
|
23
|
-
deck = Deck.new
|
23
|
+
deck = Holdem::Deck.new
|
24
24
|
deck.shuffle!
|
25
25
|
|
26
|
-
hand1 = PokerHand.new(deck.deal(7))
|
27
|
-
hand2 = PokerHand.new(deck.deal(7))
|
28
|
-
hand3 = PokerHand.new("4c Kc 4h 5d 6s Kd Qs")
|
26
|
+
hand1 = Holdem::PokerHand.new(deck.deal(7))
|
27
|
+
hand2 = Holdem::PokerHand.new(deck.deal(7))
|
28
|
+
hand3 = Holdem::PokerHand.new("4c Kc 4h 5d 6s Kd Qs")
|
29
29
|
|
30
30
|
puts hand1 # => 5♦ K♣ T♠ J♥ 8♥ 8♠ 2♥ -> Pair of 8s
|
31
31
|
puts hand2 # => Q♦ 6♦ 2♦ 6♣ 5♥ 6♠ T♦ -> Three of a Kind (trip 6s)
|
@@ -45,16 +45,16 @@ Face cards (ten, jack, queen, king, and ace) are represented by (T, J, Q, K, A).
|
|
45
45
|
|
46
46
|
Suits (club, diamond, spade, heart) are represented by (c, d, s, h).
|
47
47
|
|
48
|
-
puts PokerHand.new('Ac 7d 4c Td Qc Qh Ks') # => A♣ 7♦ 4♣ T♦ Q♣ Q♥ K♠ -> Pair of Qs
|
48
|
+
puts Holdem::PokerHand.new('Ac 7d 4c Td Qc Qh Ks') # => A♣ 7♦ 4♣ T♦ Q♣ Q♥ K♠ -> Pair of Qs
|
49
49
|
|
50
50
|
card1, card2 = Card.new('Ad'), Card.new('Ah')
|
51
|
-
puts PokerHand.new([card1, card2]) # => A♦ A♥ -> Pair of As
|
51
|
+
puts Holdem::PokerHand.new([card1, card2]) # => A♦ A♥ -> Pair of As
|
52
52
|
|
53
53
|
There is also a Deck class to facilitate random poker hands:
|
54
54
|
|
55
|
-
deck = Deck.new.shuffle!
|
55
|
+
deck = Holdem::Deck.new.shuffle!
|
56
56
|
cards = deck.deal(7)
|
57
|
-
hand = PokerHand.new(cards)
|
57
|
+
hand = Holdem::PokerHand.new(cards)
|
58
58
|
puts hand # => K♦ 5♣ 4♣ 8♣ J♠ 3♣ 7♦ -> K high
|
59
59
|
|
60
60
|
A number of ranks can be asked about a hand:
|
data/holdem.gemspec
CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.
|
22
|
-
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency 'minitest', '~> 5.
|
24
|
-
spec.add_development_dependency 'minitest-reporters', '~> 1.
|
21
|
+
spec.add_development_dependency "bundler", "~> 2.1.4"
|
22
|
+
spec.add_development_dependency "rake", "~> 13.0.1"
|
23
|
+
spec.add_development_dependency 'minitest', '~> 5.14.1'
|
24
|
+
spec.add_development_dependency 'minitest-reporters', '~> 1.4.2'
|
25
25
|
end
|
data/lib/holdem/card.rb
CHANGED
@@ -1,35 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Holdem
|
2
|
+
class Card
|
3
|
+
include Comparable
|
4
|
+
attr_reader :rank, :suit, :icon
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
RANKS = %w(2 3 4 5 6 7 8 9 T J Q K A)
|
7
|
+
SUITS = %w(c s d h)
|
8
|
+
ICONS = { 'c' => '♣', 's' => '♠', 'd' => '♦', 'h' => '♥' }
|
9
|
+
FACE_CARDS = { 'T' => 10, 'J' => 11, 'Q' => 12, 'K' => 13, 'A' => 14 }
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def initialize(card)
|
12
|
+
@rank, @suit = card.chars if card.respond_to?(:chars)
|
13
|
+
@icon = ICONS[suit]
|
14
|
+
validate(card)
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
def value
|
18
|
+
rank[/\d/] ? rank.to_i : FACE_CARDS[rank]
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
def to_s
|
22
|
+
"#{rank}#{icon}"
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
def <=>(other)
|
26
|
+
value <=> other.value
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
+
private
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def validate(card)
|
32
|
+
unless RANKS.include?(rank) && SUITS.include?(suit)
|
33
|
+
fail ArgumentError
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
35
|
-
end
|
37
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Holdem
|
2
|
+
class CardGenerator
|
3
|
+
def self.build(cards)
|
4
|
+
new(cards).cards
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
attr_reader :cards
|
8
|
+
|
9
|
+
def initialize(cards)
|
10
|
+
@cards = cards.each.map { |c| Card.new(c) }
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
data/lib/holdem/deck.rb
CHANGED
@@ -1,23 +1,25 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Holdem
|
4
|
+
class Deck
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators :@deck, :shuffle, :shuffle!, :pop, :size
|
7
|
+
attr_reader :deck
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def initialize
|
10
|
+
@deck = []
|
11
|
+
build_deck
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
alias_method :deal, :pop
|
15
|
+
alias_method :count, :size
|
15
16
|
|
16
|
-
|
17
|
+
private
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def build_deck
|
20
|
+
Card::RANKS.each do |rank|
|
21
|
+
Card::SUITS.each { |suit| deck << Card.new(rank + suit) }
|
22
|
+
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
data/lib/holdem/poker_hand.rb
CHANGED
@@ -1,34 +1,36 @@
|
|
1
1
|
require 'forwardable'
|
2
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
|
-
|
3
|
+
module Holdem
|
4
|
+
class PokerHand
|
5
|
+
include Comparable
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
rank_methods = [ :rank, :score, :straight_flush?, :quads?, :four_of_a_kind?,
|
9
|
+
:boat?, :full_house?, :flush?, :straight?, :three_of_a_kind?,
|
10
|
+
:trips?, :two_pairs?, :two_pair?, :pair? ]
|
11
|
+
def_delegators :@poker_rank, *rank_methods
|
12
|
+
|
13
|
+
attr_reader :cards, :poker_rank
|
14
|
+
|
15
|
+
def initialize(cards)
|
16
|
+
@cards = cards.is_a?(String) ? CardGenerator.build(cards.split) : cards
|
17
|
+
@poker_rank = PokerRank.new(@cards)
|
18
|
+
end
|
19
|
+
|
20
|
+
def count
|
21
|
+
cards.size
|
22
|
+
end
|
23
|
+
|
24
|
+
def <=>(other)
|
25
|
+
score <=> other.score
|
26
|
+
end
|
27
|
+
|
28
|
+
def just_cards
|
29
|
+
"#{cards.map{ |card| card.to_s }.join(' ')}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
"#{just_cards} -> #{rank}"
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
data/lib/holdem/poker_rank.rb
CHANGED
@@ -1,183 +1,188 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Holdem
|
2
|
+
class PokerRank
|
3
|
+
attr_reader :cards, :score, :rank
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(cards)
|
6
|
+
@cards = cards
|
7
|
+
@score, @rank = build_ranking
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
def build_ranking
|
11
|
+
case
|
12
|
+
when straight_flush? then build_straight_flush
|
13
|
+
when four_of_a_kind? then build_four_kind
|
14
|
+
when full_house? then build_full_house
|
15
|
+
when flush? then build_flush
|
16
|
+
when straight? then build_straight
|
17
|
+
when three_of_a_kind? then build_three_kind
|
18
|
+
when two_pairs? then build_two_pairs
|
19
|
+
when pair? then build_pair
|
20
|
+
else
|
21
|
+
build_high_card
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
# POKER HAND RANKINGS
|
25
|
-
# These methods determine type of poker hand. Hands are sorted by pair, then by
|
26
|
-
# values in descending order using the #pairs method. The hand ranking methods
|
27
|
-
# below filter the pairs array to determine type of hand.
|
25
|
+
# POKER HAND RANKINGS
|
26
|
+
# These methods determine type of poker hand. Hands are sorted by pair, then by
|
27
|
+
# values in descending order using the #pairs method. The hand ranking methods
|
28
|
+
# below filter the pairs array to determine type of hand.
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
def straight_flush?
|
31
|
+
sorted_cards.each_cons(5) do |check_cards|
|
32
|
+
return true if five_card_straight?(check_cards.map(&:value)) && check_cards.map(&:suit).uniq.one?
|
33
|
+
end
|
34
|
+
false
|
35
|
+
end
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
def four_of_a_kind?
|
38
|
+
kinds?(4)
|
39
|
+
end
|
37
40
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
+
def full_house?
|
42
|
+
three_of_a_kind? && pair?
|
43
|
+
end
|
41
44
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
+
def flush?
|
46
|
+
suits.any? { |_,count| count >= 5 }
|
47
|
+
end
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
def straight?
|
50
|
+
card_values = sorted_values
|
51
|
+
# check for low ace straight
|
52
|
+
card_values.push(1) if card_values.include?(14)
|
53
|
+
card_values.each_cons(5) do |vals|
|
54
|
+
return true if five_card_straight?(vals)
|
55
|
+
end
|
56
|
+
false
|
52
57
|
end
|
53
|
-
false
|
54
|
-
end
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
+
def five_card_straight?(list)
|
60
|
+
(list.first - list.last).abs == 4 && list.uniq.length == 5
|
61
|
+
end
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
+
def three_of_a_kind?
|
64
|
+
kinds?(3)
|
65
|
+
end
|
63
66
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
def two_pairs?
|
68
|
+
num_of_pairs = pairs.select { |count,_cards| count == 2 }.size
|
69
|
+
num_of_pairs > 1
|
70
|
+
end
|
68
71
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
+
def pair?
|
73
|
+
kinds?(2)
|
74
|
+
end
|
72
75
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
+
def kinds?(size)
|
77
|
+
pairs.any? { |count,_cards| count == size }
|
78
|
+
end
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
alias_method :quads?, :four_of_a_kind?
|
81
|
+
alias_method :trips?, :three_of_a_kind?
|
82
|
+
alias_method :boat?, :full_house?
|
83
|
+
alias_method :two_pair?, :two_pairs?
|
81
84
|
|
82
85
|
|
83
|
-
# BUILD HAND RANKINGS
|
84
|
-
# Score are first ranked by type of hand [0-9]. If equal, then compared by pairs,
|
85
|
-
# high cards, and/or remaining cards. Also includes description of hand.
|
86
|
+
# BUILD HAND RANKINGS
|
87
|
+
# Score are first ranked by type of hand [0-9]. If equal, then compared by pairs,
|
88
|
+
# high cards, and/or remaining cards. Also includes description of hand.
|
86
89
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
+
def build_high_card
|
91
|
+
[ [0] + sorted_values, "#{high_card.rank} high" ]
|
92
|
+
end
|
90
93
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
+
def build_pair
|
95
|
+
[ [1] + pair_card_values, "Pair of #{pair_card.rank}s" ]
|
96
|
+
end
|
94
97
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
98
|
+
def build_two_pairs
|
99
|
+
[ [2] + pair_card_values,
|
100
|
+
"Two Pairs (#{pair_card(1).rank}s and #{pair_card(2).rank}s)",
|
101
|
+
]
|
102
|
+
end
|
100
103
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
+
def build_three_kind
|
105
|
+
[ [3] + pair_card_values, "Three of a Kind (trip #{pair_card.rank}s)" ]
|
106
|
+
end
|
104
107
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
+
def build_straight
|
109
|
+
[ [4, highest_straight_card], "Straight" ]
|
110
|
+
end
|
108
111
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
+
def build_flush
|
113
|
+
[ [5, highest_flush_card], "Flush" ]
|
114
|
+
end
|
112
115
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
116
|
+
def build_full_house
|
117
|
+
[ [6] + pair_card_values,
|
118
|
+
"Full House (#{pair_card(1).rank}s over #{pair_card(2).rank}s)",
|
119
|
+
]
|
120
|
+
end
|
118
121
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
def build_four_kind
|
123
|
+
[ [7] + pair_card_values,
|
124
|
+
"Four of a kind (quad #{pair_card(1).rank}s)",
|
125
|
+
]
|
126
|
+
end
|
124
127
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
+
def build_straight_flush
|
129
|
+
[ [8, highest_straight_card], "Straight Flush" ]
|
130
|
+
end
|
128
131
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
132
|
+
# HELPER METHODS
|
133
|
+
def high_card
|
134
|
+
sorted_cards.first
|
135
|
+
end
|
133
136
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
+
def highest_straight_card
|
138
|
+
sorted_values.each_cons(5) do |vals|
|
139
|
+
return vals.first if five_card_straight?(vals)
|
140
|
+
end
|
137
141
|
end
|
138
|
-
end
|
139
142
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
+
def highest_flush_card
|
144
|
+
cards.select { |card| card.suit == flush_suit }.max.value
|
145
|
+
end
|
143
146
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
147
|
+
def flush_suit
|
148
|
+
suit, count = suits.first
|
149
|
+
return suit if count >= 5
|
150
|
+
end
|
148
151
|
|
149
|
-
|
152
|
+
private
|
150
153
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
154
|
+
# helper method to retrieve card value/rank for each pair
|
155
|
+
def pair_card(num=1)
|
156
|
+
pairs.take(num).map { |_count, cards| cards.last }.last
|
157
|
+
end
|
155
158
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
159
|
+
# helper method to calculate poker scores
|
160
|
+
def pair_card_values
|
161
|
+
pairs.map { |_count, cards| cards.first.value }
|
162
|
+
end
|
160
163
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
+
def sorted_cards
|
165
|
+
@sorted_cards ||= cards.sort_by { |card| card.value * -1 }
|
166
|
+
end
|
164
167
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
168
|
+
def pairs
|
169
|
+
@pairs ||= cards.group_by { |card| card.value }
|
170
|
+
.map { |_val,cards| [cards.count, cards] }
|
171
|
+
.sort_by { |count,cards| [count*-1, cards.first.value*-1] }
|
172
|
+
end
|
170
173
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
174
|
+
def suits
|
175
|
+
@suits ||= cards.group_by { |card| card.suit }
|
176
|
+
.map { |k,v| [k, v.count] }
|
177
|
+
.sort_by { |k,count| [count*-1] }
|
178
|
+
end
|
176
179
|
|
177
|
-
|
178
|
-
|
180
|
+
def sorted_values
|
181
|
+
@sorted_values ||= sorted_cards.map(&:value)
|
182
|
+
end
|
179
183
|
end
|
180
184
|
end
|
181
185
|
|
182
186
|
|
183
187
|
|
188
|
+
|
data/lib/holdem/version.rb
CHANGED
data/lib/holdem.rb
CHANGED
data/test/card_test.rb
CHANGED
@@ -2,10 +2,10 @@ require_relative 'test_helper'
|
|
2
2
|
|
3
3
|
class CardTest < Minitest::Test
|
4
4
|
def setup
|
5
|
-
@card1 = Card.new('Kd')
|
6
|
-
@card2 = Card.new('Th')
|
7
|
-
@card3 = Card.new('4s')
|
8
|
-
@card4 = Card.new('7c')
|
5
|
+
@card1 = Holdem::Card.new('Kd')
|
6
|
+
@card2 = Holdem::Card.new('Th')
|
7
|
+
@card3 = Holdem::Card.new('4s')
|
8
|
+
@card4 = Holdem::Card.new('7c')
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_card_rank
|
@@ -21,15 +21,15 @@ class CardTest < Minitest::Test
|
|
21
21
|
assert_equal 'c', @card4.suit
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
def test_card_icons
|
25
25
|
assert_equal '♦', @card1.icon
|
26
26
|
assert_equal '♥', @card2.icon
|
27
27
|
end
|
28
28
|
|
29
29
|
def test_invalid_cards
|
30
|
-
assert_raises(ArgumentError) { Card.new(56) }
|
31
|
-
assert_raises(ArgumentError) { Card.new('9k') }
|
32
|
-
assert_raises(ArgumentError) { Card.new('d2') }
|
33
|
-
assert_raises(ArgumentError) { Card.new('a card') }
|
30
|
+
assert_raises(ArgumentError) { Holdem::Card.new(56) }
|
31
|
+
assert_raises(ArgumentError) { Holdem::Card.new('9k') }
|
32
|
+
assert_raises(ArgumentError) { Holdem::Card.new('d2') }
|
33
|
+
assert_raises(ArgumentError) { Holdem::Card.new('a card') }
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
data/test/deck_test.rb
CHANGED
@@ -3,7 +3,7 @@ require_relative 'test_helper'
|
|
3
3
|
class DeckTest < Minitest::Test
|
4
4
|
|
5
5
|
def setup
|
6
|
-
@deck = Deck.new
|
6
|
+
@deck = Holdem::Deck.new
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_deck_has_52_cards
|
@@ -11,7 +11,7 @@ class DeckTest < Minitest::Test
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_deck_next_card
|
14
|
-
card = Deck.new.pop
|
14
|
+
card = Holdem::Deck.new.pop
|
15
15
|
assert_equal card, @deck.pop
|
16
16
|
assert_equal 51, @deck.size
|
17
17
|
end
|
data/test/poker_hand_test.rb
CHANGED
@@ -2,22 +2,22 @@ require_relative 'test_helper'
|
|
2
2
|
|
3
3
|
class PokerHandTest < Minitest::Test
|
4
4
|
def setup
|
5
|
-
hand1 = CardGenerator.build(%w(4c 4h 5s Qs Jc 9c Tc))
|
6
|
-
hand2 = CardGenerator.build(%w(7c 4h 7s Qs Kc Qc Tc))
|
7
|
-
hand3 = CardGenerator.build(%w(Ac 2c 3h 4h 5s 6c Qd))
|
8
|
-
hand4 = CardGenerator.build(%w(Ac 9c 9h 9h 5s 6c Qd))
|
9
|
-
@pair = PokerHand.new(hand1)
|
10
|
-
@two_pairs = PokerHand.new(hand2)
|
11
|
-
@three_kind = PokerHand.new(hand4)
|
12
|
-
@straight = PokerHand.new(hand3)
|
5
|
+
hand1 = Holdem::CardGenerator.build(%w(4c 4h 5s Qs Jc 9c Tc))
|
6
|
+
hand2 = Holdem::CardGenerator.build(%w(7c 4h 7s Qs Kc Qc Tc))
|
7
|
+
hand3 = Holdem::CardGenerator.build(%w(Ac 2c 3h 4h 5s 6c Qd))
|
8
|
+
hand4 = Holdem::CardGenerator.build(%w(Ac 9c 9h 9h 5s 6c Qd))
|
9
|
+
@pair = Holdem::PokerHand.new(hand1)
|
10
|
+
@two_pairs = Holdem::PokerHand.new(hand2)
|
11
|
+
@three_kind = Holdem::PokerHand.new(hand4)
|
12
|
+
@straight = Holdem::PokerHand.new(hand3)
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_poker_ranking_dependency
|
16
|
-
assert_equal @pair.poker_rank.class, PokerRank
|
16
|
+
assert_equal @pair.poker_rank.class, Holdem::PokerRank
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_initialize_with_string_representation
|
20
|
-
assert_equal 7, PokerHand.new("Ac Ad Kd 5s 5h 4c 5c").count
|
20
|
+
assert_equal 7, Holdem::PokerHand.new("Ac Ad Kd 5s 5h 4c 5c").count
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_rank
|
@@ -39,8 +39,8 @@ class PokerHandTest < Minitest::Test
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def test_comparison_with_kicker
|
42
|
-
other_cards = CardGenerator.build(%w(Ac 4c 4h 9h 6c Jh Qd))
|
43
|
-
other_pair = PokerHand.new(other_cards)
|
42
|
+
other_cards = Holdem::CardGenerator.build(%w(Ac 4c 4h 9h 6c Jh Qd))
|
43
|
+
other_pair = Holdem::PokerHand.new(other_cards)
|
44
44
|
assert_equal [1, 4, 14, 12, 11, 9, 6], other_pair.score
|
45
45
|
assert_equal [1, 4, 12, 11, 10, 9, 5], @pair.score
|
46
46
|
assert other_pair > @pair
|
@@ -54,4 +54,4 @@ class PokerHandTest < Minitest::Test
|
|
54
54
|
assert @two_pairs.two_pairs?
|
55
55
|
assert @straight.straight?
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end
|
data/test/poker_rank_test.rb
CHANGED
@@ -3,90 +3,89 @@ require_relative 'test_helper'
|
|
3
3
|
class PokerRankingTest < Minitest::Test
|
4
4
|
|
5
5
|
def test_pair
|
6
|
-
cards = CardGenerator.build(%w(Kd 8s 5s Kh Kc 5c Kc))
|
7
|
-
hand =
|
6
|
+
cards = Holdem::CardGenerator.build(%w(Kd 8s 5s Kh Kc 5c Kc))
|
7
|
+
hand = Holdem::PokerHand.new(cards)
|
8
8
|
assert hand.pair?
|
9
|
-
hand =
|
9
|
+
hand = Holdem::PokerHand.new(cards.first(3))
|
10
10
|
refute hand.pair?
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_two_pair
|
14
|
-
cards = CardGenerator.build(%w(7d 8s 5s 7h Kc 5c Kc))
|
15
|
-
hand =
|
14
|
+
cards = Holdem::CardGenerator.build(%w(7d 8s 5s 7h Kc 5c Kc))
|
15
|
+
hand = Holdem::PokerHand.new(cards)
|
16
16
|
assert hand.two_pairs?
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_three_of_a_kind
|
20
|
-
cards = CardGenerator.build(%w(Kh Kc 5c Kc))
|
21
|
-
hand =
|
20
|
+
cards = Holdem::CardGenerator.build(%w(Kh Kc 5c Kc))
|
21
|
+
hand = Holdem::PokerHand.new(cards)
|
22
22
|
assert hand.three_of_a_kind?
|
23
23
|
refute hand.pair?
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_four_of_a_kind
|
27
|
-
cards = CardGenerator.build(%w(Ah Ac 5c 4c As Ad))
|
28
|
-
hand =
|
27
|
+
cards = Holdem::CardGenerator.build(%w(Ah Ac 5c 4c As Ad))
|
28
|
+
hand = Holdem::PokerHand.new(cards)
|
29
29
|
assert_equal true, hand.four_of_a_kind?
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_flush?
|
33
|
-
cards = CardGenerator.build(%w(6c Tc 2c 4c As Ac Qh))
|
34
|
-
hand =
|
33
|
+
cards = Holdem::CardGenerator.build(%w(6c Tc 2c 4c As Ac Qh))
|
34
|
+
hand = Holdem::PokerHand.new(cards)
|
35
35
|
assert hand.flush?
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_not_a_flush?
|
39
|
-
cards = CardGenerator.build(%w(6c Ts 2d 4c As Ac Qh))
|
40
|
-
hand =
|
39
|
+
cards = Holdem::CardGenerator.build(%w(6c Ts 2d 4c As Ac Qh))
|
40
|
+
hand = Holdem::PokerHand.new(cards)
|
41
41
|
refute hand.flush?
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_for_straight?
|
45
|
-
cards = CardGenerator.build(%w(Td Kd Js Qd Kh Ad 9c 8c))
|
46
|
-
hand =
|
45
|
+
cards = Holdem::CardGenerator.build(%w(Td Kd Js Qd Kh Ad 9c 8c))
|
46
|
+
hand = Holdem::PokerHand.new(cards)
|
47
47
|
assert_equal true, hand.straight?
|
48
|
-
hand =
|
48
|
+
hand = Holdem::PokerHand.new(cards.drop(1))
|
49
49
|
refute hand.straight?
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_low_ace_straight?
|
53
|
-
cards = CardGenerator.build(%w(2d 3s Ad 5h 4d Td 9c 8c))
|
54
|
-
hand =
|
53
|
+
cards = Holdem::CardGenerator.build(%w(2d 3s Ad 5h 4d Td 9c 8c))
|
54
|
+
hand = Holdem::PokerHand.new(cards)
|
55
55
|
assert_equal true, hand.straight?
|
56
56
|
end
|
57
57
|
|
58
|
-
|
59
|
-
cards = CardGenerator.build(%w(Jd 8s Jh 5h 8d Jd Tc))
|
60
|
-
hand =
|
58
|
+
def test_full_house?
|
59
|
+
cards = Holdem::CardGenerator.build(%w(Jd 8s Jh 5h 8d Jd Tc))
|
60
|
+
hand = Holdem::PokerHand.new(cards)
|
61
61
|
assert_equal true, hand.full_house?
|
62
62
|
end
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
hand2 = PokerRank.new(cards2)
|
64
|
+
def test_straight_flush?
|
65
|
+
cards1 = Holdem::CardGenerator.build(%w(Jd Qd Ad Kd Td 7d Tc))
|
66
|
+
hand1 = Holdem::PokerHand.new(cards1)
|
67
|
+
cards2 = Holdem::CardGenerator.build(%w(2d 3h 4h 5h 6h 7d 8h))
|
68
|
+
hand2 = Holdem::PokerHand.new(cards2)
|
70
69
|
assert hand1.straight_flush?
|
71
70
|
refute hand2.straight_flush?
|
72
71
|
end
|
73
72
|
|
74
73
|
def test_alias_method_trips?
|
75
|
-
cards = CardGenerator.build(%w(Jd Qd Jd Jd Td 7d Tc))
|
76
|
-
hand =
|
74
|
+
cards = Holdem::CardGenerator.build(%w(Jd Qd Jd Jd Td 7d Tc))
|
75
|
+
hand = Holdem::PokerHand.new(cards)
|
77
76
|
assert hand.trips?
|
78
77
|
end
|
79
78
|
|
80
79
|
def test_alias_method_quads?
|
81
|
-
cards = CardGenerator.build(%w(Jd Jd Jd Jd Td 7d Tc))
|
82
|
-
hand =
|
80
|
+
cards = Holdem::CardGenerator.build(%w(Jd Jd Jd Jd Td 7d Tc))
|
81
|
+
hand = Holdem::PokerHand.new(cards)
|
83
82
|
assert hand.quads?
|
84
83
|
end
|
85
84
|
|
86
85
|
def test_alias_method_boat?
|
87
|
-
cards = CardGenerator.build(%w(Jd Jd Jd Td Td 7d 6c))
|
88
|
-
hand =
|
86
|
+
cards = Holdem::CardGenerator.build(%w(Jd Jd Jd Td Td 7d 6c))
|
87
|
+
hand = Holdem::PokerHand.new(cards)
|
89
88
|
assert hand.boat?
|
90
89
|
end
|
91
90
|
|
92
|
-
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: holdem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie Berczel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.1.4
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.1.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 13.0.1
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 13.0.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 5.
|
47
|
+
version: 5.14.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 5.
|
54
|
+
version: 5.14.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: minitest-reporters
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
61
|
+
version: 1.4.2
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.
|
68
|
+
version: 1.4.2
|
69
69
|
description: A ruby module for creating and comparing Texas Holdem poker hands.
|
70
70
|
email:
|
71
71
|
- jxberc@gmail.com
|
@@ -110,8 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
requirements: []
|
113
|
-
|
114
|
-
rubygems_version: 2.4.5
|
113
|
+
rubygems_version: 3.1.3
|
115
114
|
signing_key:
|
116
115
|
specification_version: 4
|
117
116
|
summary: A ruby module for creating and comparing Texas Holdem poker hands.
|