holdem 1.0.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 +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +88 -0
- data/Rakefile +8 -0
- data/holdem.gemspec +24 -0
- data/lib/holdem/card.rb +35 -0
- data/lib/holdem/card_generator.rb +11 -0
- data/lib/holdem/deck.rb +16 -0
- data/lib/holdem/poker_hand.rb +33 -0
- data/lib/holdem/poker_rank.rb +191 -0
- data/lib/holdem/version.rb +3 -0
- data/lib/holdem.rb +9 -0
- data/test/card_test.rb +34 -0
- data/test/deck_test.rb +25 -0
- data/test/poker_hand_test.rb +58 -0
- data/test/poker_rank_test.rb +93 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0754af8abb3299e3d216afe08268d3a598d36b7f
|
4
|
+
data.tar.gz: 94286f69b8e84cf14d20c5592cef849621d3ddf0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b32781200a316d37424ea3723c49ef28fdaf2dc0f13db71a64e213008ab7bb064c08edb21cd59bf3d0b4d6215dd0a108400c98dd7f4bbfb35f93bebdaa1265c7
|
7
|
+
data.tar.gz: aec81c6ca0f148bc738482434c1dc1b8ad2f135beeaba5b3095093ec164c21fe5d5c18a0ea7f219eeaeccc9e8354059d86343a7ff6ac23e0c52468d6d3218f60
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Jamie
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Holdem
|
2
|
+
|
3
|
+
A ruby module for creating and comparing Texas Holdem poker hands.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'holdem'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install holdem
|
18
|
+
|
19
|
+
## Example
|
20
|
+
|
21
|
+
require 'holdem'
|
22
|
+
|
23
|
+
deck = Deck.new
|
24
|
+
deck.shuffle!
|
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")
|
29
|
+
|
30
|
+
puts hand1 # => 5♦ K♣ T♠ J♥ 8♥ 8♠ 2♥ -> Pair of 8s
|
31
|
+
puts hand2 # => Q♦ 6♦ 2♦ 6♣ 5♥ 6♠ T♦ -> Three of a Kind (trip 6s)
|
32
|
+
puts hand3 # => 4♣ K♣ 4♥ 5♦ 6♠ K♦ Q♠ -> Two Pairs (Ks and 4s)
|
33
|
+
|
34
|
+
puts hand1 > hand2 # => false
|
35
|
+
puts hand2 < hand3 # => false
|
36
|
+
puts [hand1, hand2, hand3].max # => Q♦ 6♦ 2♦ 6♣ 5♥ 6♠ T♦ -> Three of a Kind (trip 6s)
|
37
|
+
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
Cards can be passed to the PokerHand constructor as a string of card representations
|
42
|
+
or as an array of card objects.
|
43
|
+
|
44
|
+
Face cards (ten, jack, queen, king, and ace) are represented by (T, J, Q, K, A).
|
45
|
+
|
46
|
+
Suits (club, diamond, spade, heart) are represented by (c, d, s, h).
|
47
|
+
|
48
|
+
puts PokerHand.new('Ac 7d 4c Td Qc Qh Ks') # => A♣ 7♦ 4♣ T♦ Q♣ Q♥ K♠ -> Pair of Qs
|
49
|
+
|
50
|
+
card1, card2 = Card.new('Ad'), Card.new('Ah')
|
51
|
+
puts PokerHand.new([card1, card2]) # => A♦ A♥ -> Pair of As
|
52
|
+
|
53
|
+
There is also a Deck class to facilitate random poker hands:
|
54
|
+
|
55
|
+
deck = Deck.new.shuffle!
|
56
|
+
cards = deck.deal(7)
|
57
|
+
hand = PokerHand.new(cards)
|
58
|
+
puts hand # => K♦ 5♣ 4♣ 8♣ J♠ 3♣ 7♦ -> K high
|
59
|
+
|
60
|
+
A number of ranks can be asked about a hand:
|
61
|
+
|
62
|
+
hand.straight_flush?
|
63
|
+
hand.quads? # or hand.four_of_a_kind?
|
64
|
+
hand.boat? # or hand.full_house?
|
65
|
+
hand.flush?
|
66
|
+
hand.straight?
|
67
|
+
hand.trips? # or hand.three_of_a_kind?
|
68
|
+
hand.two_pairs?
|
69
|
+
hand.pair?
|
70
|
+
|
71
|
+
## TODO
|
72
|
+
|
73
|
+
Build Simulations, players, table, chips, and game objects.
|
74
|
+
|
75
|
+
Add methods to PokerRank for:
|
76
|
+
|
77
|
+
hand.open_ended?
|
78
|
+
hand.four_to_flush?
|
79
|
+
hand.gutshot?
|
80
|
+
|
81
|
+
|
82
|
+
## Contributing
|
83
|
+
|
84
|
+
1. Fork it ( https://github.com/[my-github-username]/holdem/fork )
|
85
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
86
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
87
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
88
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/holdem.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'holdem/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "holdem"
|
8
|
+
spec.version = Holdem::VERSION
|
9
|
+
spec.authors = ["Jamie Berczel"]
|
10
|
+
spec.email = ["jxberc@gmail.com"]
|
11
|
+
spec.summary = %q{A ruby module for creating and comparing Texas Holdem poker hands.}
|
12
|
+
spec.description = %q{A ruby module for creating and comparing Texas Holdem poker hands.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency 'minitest', '~> 5.4.3'
|
24
|
+
end
|
data/lib/holdem/card.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Card
|
2
|
+
include Comparable
|
3
|
+
attr_reader :rank, :suit, :icon
|
4
|
+
|
5
|
+
RANKS = %w(2 3 4 5 6 7 8 9 T J Q K A)
|
6
|
+
SUITS = %w(c s d h)
|
7
|
+
ICONS = { 'c' => '♣', 's' => '♠', 'd' => '♦', 'h' => '♥' }
|
8
|
+
FACE_CARDS = { 'T' => 10, 'J' => 11, 'Q' => 12, 'K' => 13, 'A' => 14 }
|
9
|
+
|
10
|
+
def initialize(card)
|
11
|
+
@rank, @suit = card.split(//)
|
12
|
+
@icon = ICONS[suit]
|
13
|
+
validate(card)
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
rank[/\d/] ? rank.to_i : FACE_CARDS[rank]
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"#{rank}#{icon}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def <=>(other)
|
25
|
+
value <=> other.value
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def validate(card)
|
31
|
+
unless RANKS.include?(rank) && SUITS.include?(suit)
|
32
|
+
fail ArgumentError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/holdem/deck.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class Deck < Array
|
2
|
+
def initialize
|
3
|
+
build_deck
|
4
|
+
end
|
5
|
+
|
6
|
+
# add test for #deal
|
7
|
+
alias_method :deal, :pop
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def build_deck
|
12
|
+
Card::RANKS.each do |rank|
|
13
|
+
Card::SUITS.each { |suit| self << Card.new(rank + suit) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class PokerHand
|
2
|
+
include Comparable
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
def_delegators :@poker_rank, :rank, :score
|
6
|
+
rank_methods = [ :straight_flush?, :quads?, :four_of_a_kind?, :boat?,
|
7
|
+
:full_house?, :flush?, :straight?, :three_of_a_kind?,
|
8
|
+
:trips?, :two_pairs?, :two_pair?, :pair? ]
|
9
|
+
def_delegators :@poker_rank, *rank_methods
|
10
|
+
|
11
|
+
attr_reader :cards, :poker_rank
|
12
|
+
|
13
|
+
def initialize(cards)
|
14
|
+
@cards = cards.is_a?(String) ? CardGenerator.build(cards.split) : cards
|
15
|
+
@poker_rank = PokerRank.new(@cards)
|
16
|
+
end
|
17
|
+
|
18
|
+
def count
|
19
|
+
cards.size
|
20
|
+
end
|
21
|
+
|
22
|
+
def <=>(other)
|
23
|
+
score <=> other.score
|
24
|
+
end
|
25
|
+
|
26
|
+
def just_cards
|
27
|
+
"#{cards.map{ |card| card.to_s }.join(' ')}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
"#{just_cards} -> #{rank}"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
class PokerRank
|
2
|
+
attr_reader :cards, :score, :rank
|
3
|
+
|
4
|
+
def initialize(cards)
|
5
|
+
@cards = cards
|
6
|
+
@score, @rank = build_ranking
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_ranking
|
10
|
+
# return ["Straight flush", straight_flush_score] if straight_flush?
|
11
|
+
# return ["Four of a kind", four_kind_score] if four_of_a_kind?
|
12
|
+
# return ["Full House", full_house_score] if full_house?
|
13
|
+
# return ["Flush", flush_score] if flush?
|
14
|
+
# return ["Straight", straight_score] if straight?
|
15
|
+
# return ["Three of a Kind", three_kind_score] if three_of_a_kind?
|
16
|
+
# return ["Two Pairs", two_pairs_score] if two_pairs?
|
17
|
+
# return ["One Pair", pair_score] if pair?
|
18
|
+
#
|
19
|
+
case
|
20
|
+
when straight_flush? then build_straight_flush
|
21
|
+
when four_of_a_kind? then build_four_kind
|
22
|
+
when full_house? then build_full_house
|
23
|
+
when flush? then build_flush
|
24
|
+
when straight? then build_straight
|
25
|
+
when three_of_a_kind? then build_three_kind
|
26
|
+
when two_pairs? then build_two_pairs
|
27
|
+
when pair? then build_pair
|
28
|
+
else
|
29
|
+
build_high_card
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# POKER HAND RANKINGS
|
34
|
+
# These methods determine type of poker hand. Hands are sorted by pair, then by
|
35
|
+
# values in descending order using the #pairs method. The hand ranking methods
|
36
|
+
# below filter the pairs array to determine type of hand.
|
37
|
+
|
38
|
+
#need to fix
|
39
|
+
def straight_flush?
|
40
|
+
straight? && flush?
|
41
|
+
end
|
42
|
+
|
43
|
+
def four_of_a_kind?
|
44
|
+
kinds?(4)
|
45
|
+
end
|
46
|
+
|
47
|
+
def full_house?
|
48
|
+
three_of_a_kind? && pair?
|
49
|
+
end
|
50
|
+
|
51
|
+
def flush?
|
52
|
+
suits.any? { |_,count| count >= 5 }
|
53
|
+
end
|
54
|
+
|
55
|
+
def straight?
|
56
|
+
card_values = sorted_values
|
57
|
+
# check for low ace straight
|
58
|
+
card_values.push(1) if card_values.include?(14)
|
59
|
+
card_values.each_cons(5) do |vals|
|
60
|
+
return true if five_card_straight?(vals)
|
61
|
+
end
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
def five_card_straight?(list)
|
66
|
+
(list.first - list.last).abs == 4 && list.uniq.length == 5
|
67
|
+
end
|
68
|
+
|
69
|
+
def three_of_a_kind?
|
70
|
+
kinds?(3)
|
71
|
+
end
|
72
|
+
|
73
|
+
def two_pairs?
|
74
|
+
num_of_pairs = pairs.select { |count,_cards| count == 2 }.size
|
75
|
+
num_of_pairs > 1
|
76
|
+
end
|
77
|
+
|
78
|
+
def pair?
|
79
|
+
kinds?(2)
|
80
|
+
end
|
81
|
+
|
82
|
+
def kinds?(size)
|
83
|
+
pairs.any? { |count,_cards| count == size }
|
84
|
+
end
|
85
|
+
|
86
|
+
alias_method :quads?, :four_of_a_kind?
|
87
|
+
alias_method :trips?, :three_of_a_kind?
|
88
|
+
alias_method :boat?, :full_house?
|
89
|
+
alias_method :two_pair?, :two_pairs?
|
90
|
+
|
91
|
+
|
92
|
+
# BUILD HAND RANKINGS
|
93
|
+
# Score are first ranked by type of hand [0-9]. If equal, then compared by pairs,
|
94
|
+
# high cards, and/or remaining cards. Also includes description of hand.
|
95
|
+
|
96
|
+
def build_high_card
|
97
|
+
[ [0] + sorted_values, "#{high_card.rank} high" ]
|
98
|
+
end
|
99
|
+
|
100
|
+
def build_pair
|
101
|
+
[ [1] + pair_card_values, "Pair of #{pair_card.rank}s" ]
|
102
|
+
end
|
103
|
+
|
104
|
+
def build_two_pairs
|
105
|
+
[ [2] + pair_card_values,
|
106
|
+
"Two Pairs (#{pair_card(1).rank}s and #{pair_card(2).rank}s)",
|
107
|
+
]
|
108
|
+
end
|
109
|
+
|
110
|
+
def build_three_kind
|
111
|
+
[ [3] + pair_card_values, "Three of a Kind (trip #{pair_card.rank}s)" ]
|
112
|
+
end
|
113
|
+
|
114
|
+
def build_straight
|
115
|
+
[ [4, highest_straight_card], "Straight" ]
|
116
|
+
end
|
117
|
+
|
118
|
+
def build_flush
|
119
|
+
[ [5, highest_flush_card], "Flush" ]
|
120
|
+
end
|
121
|
+
|
122
|
+
def build_full_house
|
123
|
+
[ [6] + pair_card_values,
|
124
|
+
"Full House (#{pair_card(1).rank}s over #{pair_card(2).rank}s)",
|
125
|
+
]
|
126
|
+
end
|
127
|
+
|
128
|
+
def build_four_kind
|
129
|
+
[ [7] + pair_card_values,
|
130
|
+
"Four of a kind (quad #{pair_card(1).rank}s)",
|
131
|
+
]
|
132
|
+
end
|
133
|
+
|
134
|
+
def build_straight_flush
|
135
|
+
[ [8, highest_straight_card], "Straight Flush" ]
|
136
|
+
end
|
137
|
+
|
138
|
+
# HELPER METHODS
|
139
|
+
|
140
|
+
def pair_card_values
|
141
|
+
pairs.map { |_count, cards| cards.first.value }
|
142
|
+
end
|
143
|
+
|
144
|
+
def high_card
|
145
|
+
sorted_cards.first
|
146
|
+
end
|
147
|
+
|
148
|
+
def highest_straight_card
|
149
|
+
sorted_values.each_cons(5) do |vals|
|
150
|
+
return vals.first if five_card_straight?(vals)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def highest_flush_card
|
155
|
+
cards.select { |card| card.suit == flush_suit }.max.value
|
156
|
+
end
|
157
|
+
|
158
|
+
def flush_suit
|
159
|
+
suit, count = suits.first
|
160
|
+
return suit if count >= 5
|
161
|
+
end
|
162
|
+
|
163
|
+
def pair_card(num=1)
|
164
|
+
pairs.take(num).map { |_count, cards| cards.last }.last
|
165
|
+
end
|
166
|
+
|
167
|
+
#private
|
168
|
+
|
169
|
+
def sorted_cards
|
170
|
+
@sorted_cards ||= cards.sort_by { |card| card.value * -1 }
|
171
|
+
end
|
172
|
+
|
173
|
+
def pairs
|
174
|
+
@pairs ||= cards.group_by { |card| card.value }
|
175
|
+
.map { |_val,cards| [cards.count, cards] }
|
176
|
+
.sort_by { |count,cards| [count*-1, cards.first.value*-1] }
|
177
|
+
end
|
178
|
+
|
179
|
+
def suits
|
180
|
+
@suits ||= cards.group_by { |card| card.suit }
|
181
|
+
.map { |k,v| [k, v.count] }
|
182
|
+
.sort_by { |k,count| [count*-1] }
|
183
|
+
end
|
184
|
+
|
185
|
+
def sorted_values
|
186
|
+
@sorted_values ||= sorted_cards.map(&:value)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
|
data/lib/holdem.rb
ADDED
data/test/card_test.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'holdem'
|
3
|
+
|
4
|
+
class CardTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
@card1 = Card.new('Kd')
|
7
|
+
@card2 = Card.new('Th')
|
8
|
+
@card3 = Card.new('4s')
|
9
|
+
@card4 = Card.new('7c')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_card_rank
|
13
|
+
assert_equal 'K', @card1.rank
|
14
|
+
assert_equal 'T', @card2.rank
|
15
|
+
assert_equal '4', @card3.rank
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_card_suit
|
19
|
+
assert_equal 'd', @card1.suit
|
20
|
+
assert_equal 'h', @card2.suit
|
21
|
+
assert_equal 's', @card3.suit
|
22
|
+
assert_equal 'c', @card4.suit
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_has_icons
|
26
|
+
assert_equal '♦', @card1.icon
|
27
|
+
assert_equal '♥', @card2.icon
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_invalid_cards
|
31
|
+
assert_raises(ArgumentError) { Card.new('9k') }
|
32
|
+
assert_raises(ArgumentError) { Card.new('d2') }
|
33
|
+
end
|
34
|
+
end
|
data/test/deck_test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'holdem'
|
3
|
+
|
4
|
+
class DeckTest < Minitest::Test
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@deck = Deck.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_deck_has_52_cards
|
11
|
+
assert_equal 52, @deck.count
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_deck_next_card
|
15
|
+
card = @deck.dup.pop
|
16
|
+
assert_equal card, @deck.pop
|
17
|
+
assert_equal 51, @deck.size
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_shuffle
|
21
|
+
unshuffled = @deck.dup
|
22
|
+
shuffled = @deck.shuffle
|
23
|
+
refute_equal unshuffled, shuffled
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'holdem'
|
3
|
+
|
4
|
+
class PokerHandTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
hand1 = CardGenerator.build(%w(4c 4h 5s Qs Jc 9c Tc))
|
7
|
+
hand2 = CardGenerator.build(%w(7c 4h 7s Qs Kc Qc Tc))
|
8
|
+
hand3 = CardGenerator.build(%w(Ac 2c 3h 4h 5s 6c Qd))
|
9
|
+
hand4 = CardGenerator.build(%w(Ac 9c 9h 9h 5s 6c Qd))
|
10
|
+
@pair = PokerHand.new(hand1)
|
11
|
+
@two_pairs = PokerHand.new(hand2)
|
12
|
+
@three_kind = PokerHand.new(hand4)
|
13
|
+
@straight = PokerHand.new(hand3)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_poker_ranking_dependency
|
17
|
+
assert_equal @pair.poker_rank.class, PokerRank
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_initialize_with_string_representation
|
21
|
+
assert_equal 7, PokerHand.new("Ac Ad Kd 5s 5h 4c 5c").count
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_rank
|
25
|
+
assert_equal "Straight", @straight.rank
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_score
|
29
|
+
assert_equal [2, 12, 7, 13, 10, 4], @two_pairs.score
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_comparisons
|
33
|
+
assert @pair < @two_pairs
|
34
|
+
assert @pair < @straight
|
35
|
+
assert @three_kind > @two_pairs
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_three_kind_less_than_straight
|
39
|
+
assert @three_kind < @straight
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_comparison_with_kicker
|
43
|
+
other_cards = CardGenerator.build(%w(Ac 4c 4h 9h 6c Jh Qd))
|
44
|
+
other_pair = PokerHand.new(other_cards)
|
45
|
+
assert_equal [1, 4, 14, 12, 11, 9, 6], other_pair.score
|
46
|
+
assert_equal [1, 4, 12, 11, 10, 9, 5], @pair.score
|
47
|
+
assert other_pair > @pair
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_delegated_methods
|
51
|
+
refute @pair.quads?
|
52
|
+
refute @pair.straight_flush?
|
53
|
+
refute @pair.trips?
|
54
|
+
assert @pair.pair?
|
55
|
+
assert @two_pairs.two_pairs?
|
56
|
+
assert @straight.straight?
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'holdem'
|
3
|
+
|
4
|
+
class PokerRankingTest < Minitest::Test
|
5
|
+
|
6
|
+
def test_pair
|
7
|
+
cards = CardGenerator.build(%w(Kd 8s 5s Kh Kc 5c Kc))
|
8
|
+
hand = PokerRank.new(cards)
|
9
|
+
assert hand.pair?
|
10
|
+
hand = PokerRank.new(cards.first(3))
|
11
|
+
refute hand.pair?
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_two_pair
|
15
|
+
cards = CardGenerator.build(%w(7d 8s 5s 7h Kc 5c Kc))
|
16
|
+
hand = PokerRank.new(cards)
|
17
|
+
assert hand.two_pairs?
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_three_of_a_kind
|
21
|
+
cards = CardGenerator.build(%w(Kh Kc 5c Kc))
|
22
|
+
hand = PokerRank.new(cards)
|
23
|
+
assert hand.three_of_a_kind?
|
24
|
+
refute hand.pair?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_four_of_a_kind
|
28
|
+
cards = CardGenerator.build(%w(Ah Ac 5c 4c As Ad))
|
29
|
+
hand = PokerRank.new(cards)
|
30
|
+
assert_equal true, hand.four_of_a_kind?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_flush?
|
34
|
+
cards = CardGenerator.build(%w(6c Tc 2c 4c As Ac Qh))
|
35
|
+
hand = PokerRank.new(cards)
|
36
|
+
assert hand.flush?
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_not_a_flush?
|
40
|
+
cards = CardGenerator.build(%w(6c Ts 2d 4c As Ac Qh))
|
41
|
+
hand = PokerRank.new(cards)
|
42
|
+
refute hand.flush?
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_for_straight?
|
46
|
+
cards = CardGenerator.build(%w(Td Kd Js Qd Kh Ad 9c 8c))
|
47
|
+
hand = PokerRank.new(cards)
|
48
|
+
assert_equal true, hand.straight?
|
49
|
+
hand = PokerRank.new(cards.drop(1))
|
50
|
+
refute hand.straight?
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_low_ace_straight?
|
54
|
+
cards = CardGenerator.build(%w(2d 3s Ad 5h 4d Td 9c 8c))
|
55
|
+
hand = PokerRank.new(cards)
|
56
|
+
assert_equal true, hand.straight?
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_full_house?
|
60
|
+
cards = CardGenerator.build(%w(Jd 8s Jh 5h 8d Jd Tc))
|
61
|
+
hand = PokerRank.new(cards)
|
62
|
+
assert_equal true, hand.full_house?
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_straight_flush?
|
66
|
+
skip
|
67
|
+
cards1 = CardGenerator.build(%w(Jd Qd Ad Kd Td 7d Tc))
|
68
|
+
hand1 = PokerRank.new(cards1)
|
69
|
+
cards2 = CardGenerator.build(%w(2d 3h 4h 5h 6h 7d 8h))
|
70
|
+
hand2 = PokerRank.new(cards2)
|
71
|
+
assert hand1.straight_flush?
|
72
|
+
refute hand2.straight_flush?
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_alias_method_trips?
|
76
|
+
cards = CardGenerator.build(%w(Jd Qd Jd Jd Td 7d Tc))
|
77
|
+
hand = PokerRank.new(cards)
|
78
|
+
assert hand.trips?
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_alias_method_quads?
|
82
|
+
cards = CardGenerator.build(%w(Jd Jd Jd Jd Td 7d Tc))
|
83
|
+
hand = PokerRank.new(cards)
|
84
|
+
assert hand.quads?
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_alias_method_boat?
|
88
|
+
cards = CardGenerator.build(%w(Jd Jd Jd Td Td 7d 6c))
|
89
|
+
hand = PokerRank.new(cards)
|
90
|
+
assert hand.boat?
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: holdem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jamie Berczel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.4.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.4.3
|
55
|
+
description: A ruby module for creating and comparing Texas Holdem poker hands.
|
56
|
+
email:
|
57
|
+
- jxberc@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- holdem.gemspec
|
68
|
+
- lib/holdem.rb
|
69
|
+
- lib/holdem/card.rb
|
70
|
+
- lib/holdem/card_generator.rb
|
71
|
+
- lib/holdem/deck.rb
|
72
|
+
- lib/holdem/poker_hand.rb
|
73
|
+
- lib/holdem/poker_rank.rb
|
74
|
+
- lib/holdem/version.rb
|
75
|
+
- test/card_test.rb
|
76
|
+
- test/deck_test.rb
|
77
|
+
- test/poker_hand_test.rb
|
78
|
+
- test/poker_rank_test.rb
|
79
|
+
homepage: ''
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 2.4.4
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: A ruby module for creating and comparing Texas Holdem poker hands.
|
103
|
+
test_files:
|
104
|
+
- test/card_test.rb
|
105
|
+
- test/deck_test.rb
|
106
|
+
- test/poker_hand_test.rb
|
107
|
+
- test/poker_rank_test.rb
|