rholdem 0.0.1

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.
data/spec/hand_spec.rb ADDED
@@ -0,0 +1,350 @@
1
+ require File.dirname(__FILE__) + "/../lib/hand"
2
+ include Holdem
3
+
4
+ describe Hand do
5
+ it "should be creatable from a string of cards" do
6
+ h = Hand.new('2c 3c 4c 5c 6c')
7
+ h.cards.should_not be_nil
8
+ end
9
+
10
+ it "should be creatable from a set of cards" do
11
+ h = Hand.new(
12
+ Card.new('4c'),
13
+ Card.new('5c'),
14
+ Card.new('6c'),
15
+ Card.new('7c'),
16
+ Card.new('8c')
17
+ )
18
+ h.cards.should_not be_nil
19
+ end
20
+
21
+ it "should be creatable from an array of cards" do
22
+ h = Hand.new([
23
+ Card.new('4c'),
24
+ Card.new('5c'),
25
+ Card.new('6c'),
26
+ Card.new('7c'),
27
+ Card.new('8c')
28
+ ])
29
+ h.cards.should_not be_nil
30
+ end
31
+
32
+ it "should be creatable from two cards" do
33
+ h = Hand.new('2c 2d')
34
+ h.cards.should_not be_nil
35
+ end
36
+
37
+ it "should be creatable from seven cards" do
38
+ h = Hand.new('8d 2d 3d 4d 5d 6d 7d')
39
+ h.cards.should_not be_nil
40
+ end
41
+
42
+ it "should require at least two cards" do
43
+ lambda { Hand.new('2d') }.should raise_error
44
+ end
45
+
46
+ it "should require no more than seven cards" do
47
+ lambda { Hand.new('2c 3c 4c 5c 6c 7c 8c 9c') }.should raise_error
48
+ end
49
+
50
+ it "should require only Card objects in arrays" do
51
+ lambda { Hand.new(Object.new, Object.new) }.should raise_error
52
+ end
53
+
54
+ it "should receive an error with invalid Card constructors" do
55
+ lambda { Hand.new('2as 3cck') }.should raise_error
56
+ end
57
+ end
58
+
59
+ describe Hand, "finding the highest card" do
60
+ it "should find the highest card by rank" do
61
+ h = Hand.new('3c 4c 6s 7h 5d')
62
+ h.high_card.to_s.should == '7h'
63
+ end
64
+ end
65
+
66
+ describe Hand, "straight flush" do
67
+ it "should recognize a straight flush" do
68
+ h = Hand.new('Tc 9c 8c 7c 6c 2d')
69
+ h.ranking.should == :straight_flush
70
+ end
71
+
72
+ it "should need at least five cards" do
73
+ h = Hand.new('9c 8c 7c 6c')
74
+ h.ranking.should_not == :straight_flush
75
+ end
76
+
77
+ it "should recognize ace as the lowest in low straight" do
78
+ h = Hand.new('As 2s 3s 4s 5s')
79
+ h.high_card.to_s.should == '5s'
80
+ end
81
+
82
+ it "should recognize ace as the highest card otherwise" do
83
+ h = Hand.new('As Ks Qs Js Ts')
84
+ h.high_card.to_s.should == 'As'
85
+ end
86
+
87
+ it "should sort the best five cards" do
88
+ h = Hand.new('8s 7s 2s 3s 4s 5s 6s')
89
+ h.sorted_cards.join(' ').should == '4s 5s 6s 7s 8s'
90
+ end
91
+ end
92
+
93
+ describe Hand, "four of a kind" do
94
+ it "should recognize four of a kind in five cards" do
95
+ h = Hand.new('As Ad Ac Ah 2c')
96
+ h.ranking.should == :four_of_a_kind
97
+ end
98
+
99
+ it "should recognize four of a kind in four cards" do
100
+ h = Hand.new('As Ad Ac Ah')
101
+ h.ranking.should == :four_of_a_kind
102
+ end
103
+
104
+ it "should require at least four cards" do
105
+ h = Hand.new('As Ad Ac')
106
+ h.ranking.should_not == :four_of_a_kind
107
+ end
108
+
109
+ it "should sort the best five cards" do
110
+ h = Hand.new('3c 3s 3d 3h Kh Ad Ts')
111
+ s = h.sorted_cards.join(' ')
112
+ s.should include('3s')
113
+ s.should include('3c')
114
+ s.should include('3d')
115
+ s.should include('3h')
116
+ s.should include('Ad')
117
+ end
118
+
119
+ it "should move the kicker to the lowest card" do
120
+ h = Hand.new('3c 3s 3d 3h Kh Ad Ts')
121
+ h.sorted_cards[0].to_s.should == 'Ad'
122
+ end
123
+ end
124
+
125
+ describe Hand, "full house" do
126
+ it "should recognize a full house" do
127
+ h = Hand.new('3c 3d 3s 4c 4s 5c')
128
+ h.ranking.should == :full_house
129
+ end
130
+
131
+ it "should require at least five cards" do
132
+ h = Hand.new('4c 4d 3c 3s')
133
+ h.ranking.should_not == :full_house
134
+ end
135
+
136
+ it "should set the high card as 'over'" do
137
+ h = Hand.new('3c 3d 3s 5c 5d')
138
+ h.high_card.rank.should == Card.new('3c').rank
139
+ end
140
+
141
+ it "should find the highest full house in seven cards" do
142
+ h = Hand.new('3c 3d 3c 4h 4s 8s 8d')
143
+ h.high_card.rank.should == Card.new('3d').rank
144
+ h.sorted_cards[0].rank.should == Card.new('8h').rank
145
+ h.sorted_cards[1].rank.should == Card.new('8h').rank
146
+ end
147
+ end
148
+
149
+ describe Hand, "flush" do
150
+ it "should recognize a flush" do
151
+ h = Hand.new('3s 5s 7s Ks 2s Ac Qd')
152
+ h.ranking.should == :flush
153
+ end
154
+
155
+ it "should require at least five cards" do
156
+ h = Hand.new('3s 4s 7s 9s')
157
+ h.ranking.should_not == :flush
158
+ end
159
+ end
160
+
161
+ describe Hand, "straight" do
162
+ it "should recognize a straight" do
163
+ h = Hand.new('3c 4d 7c Ks 3d 5c 6h')
164
+ h.ranking.should == :straight
165
+ end
166
+
167
+ it "should recognize ace as the lowest in low straight" do
168
+ h = Hand.new('2c 5s 4d 8c Ts 3h Ad')
169
+ h.ranking.should == :straight
170
+ h.high_card.to_s.should == '5s'
171
+ end
172
+
173
+ it "should recognize ace as the highest card otherwise" do
174
+ h = Hand.new('Ac Td Kh 5d Qs 2s Jd')
175
+ h.ranking.should == :straight
176
+ h.high_card.to_s.should == 'Ac'
177
+ end
178
+
179
+ it "should require at least five cards" do
180
+ h = Hand.new('2c 4d 5s 3h')
181
+ h.ranking.should_not == :straight
182
+ end
183
+ end
184
+
185
+ describe Hand, "three of a kind" do
186
+ it "should recognize three of a kind" do
187
+ h = Hand.new('3s 3d 3h 4c 5s Td')
188
+ h.ranking.should == :three_of_a_kind
189
+ end
190
+
191
+ it "should set the trips to high card" do
192
+ h = Hand.new('3s 3d 3h 4c 5s Td')
193
+ h.high_card.rank.should == Card.new('3c').rank
194
+ end
195
+
196
+ it "should sort the kickers after the pair" do
197
+ h = Hand.new('3s 3d 3h 4c 5s Ac Td')
198
+ h.sorted_cards[0].to_s.should == 'Td'
199
+ h.sorted_cards[1].to_s.should == 'Ac'
200
+ end
201
+
202
+ it "should require at least three cards" do
203
+ h = Hand.new('3s 3d')
204
+ h.ranking.should_not == :three_of_a_kind
205
+ end
206
+ end
207
+
208
+ describe Hand, "two pair" do
209
+ it "should be recognized" do
210
+ h = Hand.new('3c 3s 8c 8h Ad Kh Ts')
211
+ h.ranking.should == :two_pair
212
+ end
213
+
214
+ it "should set the high pair to high card" do
215
+ h = Hand.new('3c 8c 3s 8h Ad Kh Ts')
216
+ h.high_card.rank.should == Card.new('8c').rank
217
+ end
218
+
219
+ it "should move the kicker to the lowest card" do
220
+ h = Hand.new('3c 3s 8c 8h Kh Ad Ts')
221
+ h.sorted_cards[0].to_s.should == 'Ad'
222
+ end
223
+ end
224
+
225
+ describe Hand, "pair" do
226
+ it "should be recognized" do
227
+ h = Hand.new('Ac Ad Kc Qd 3c 5h')
228
+ h.ranking.should == :pair
229
+ end
230
+
231
+ it "should set the high card to the pair" do
232
+ h = Hand.new('3c 3d Kc Qd 4c 5h')
233
+ h.high_card.rank.should == Card.new('3c').rank
234
+ end
235
+
236
+ it "should sort the kickers after the pair" do
237
+ h = Hand.new('3c 3d Kc Qd 4c 5h')
238
+ h.sorted_cards[0].to_s.should == '5h'
239
+ h.sorted_cards[1].to_s.should == 'Qd'
240
+ h.sorted_cards[2].to_s.should == 'Kc'
241
+ end
242
+ end
243
+
244
+ describe Hand, "high card" do
245
+ it "should be recognized" do
246
+ h = Hand.new('2c 5c Ad Kh Qs 9d 8h')
247
+ h.ranking.should == :high_card
248
+ end
249
+
250
+ it "should be sorted" do
251
+ h = Hand.new('2c 5c Ad Kh Qs 9d 8h')
252
+ h.sorted_cards.join(' ').should == '8h 9d Qs Kh Ad'
253
+ end
254
+ end
255
+
256
+ describe Hand, "comparing to other hands" do
257
+ it "should find the highest hand by ranking" do
258
+ h1 = Hand.new('3c 4c 5c 6c 7c 2d 4h')
259
+ h2 = Hand.new('3c 4c 5c 6d 7c 2d 4h')
260
+ (h1 <=> h2).should == 1
261
+ (h1 > h2).should be_true
262
+ (h1 < h2).should be_false
263
+ end
264
+
265
+ it "should find highest hand by high card when ranking same" do
266
+ h1 = Hand.new('2d 8d 7d 4d Ad')
267
+ h2 = Hand.new('2d 8d 7d 4d Qd')
268
+ (h1 <=> h2).should == 1
269
+ (h1 > h2).should be_true
270
+ (h1 < h2).should be_false
271
+ end
272
+
273
+ it "should look at highest card first not lowest when ranking same" do
274
+ h1 = Hand.new('2c 3c 4d 8s 9s')
275
+ h2 = Hand.new('3c 4c 5d 7s 9s')
276
+ (h1 <=> h2).should == 1
277
+ (h1 > h2).should be_true
278
+ (h1 < h2).should be_false
279
+ end
280
+
281
+ it "should equate hands with same cards" do
282
+ h1 = Hand.new('2c 3c 4c 5c 6c 7c 8c')
283
+ h2 = Hand.new('2c 3c 4c 5c 6c 7c 8c')
284
+ (h1 <=> h2).should == 0
285
+ h1.should == h2
286
+ end
287
+
288
+ it "should equate hands with same hand rankings and card ranks" do
289
+ h1 = Hand.new('2c 3d 4d 5d 6s')
290
+ h2 = Hand.new('2c 3h 4d 5h 6s')
291
+ (h1 <=> h2).should == 0
292
+ h1.should == h2
293
+ end
294
+
295
+ it "should not equate hands with different rankings" do
296
+ h1 = Hand.new('2c 3d 8d 9h Qs')
297
+ h2 = Hand.new('2c 3d Ah Ac Qs')
298
+ h1.should_not == h2
299
+ end
300
+
301
+ it "should not equate hands with same rankings but different card ranks" do
302
+ h1 = Hand.new('2c 3d 2h 4d 2s')
303
+ h2 = Hand.new('2c 3d 3h 4d 3s')
304
+ h1.should_not == h2
305
+ end
306
+
307
+ it "should not be affected in sorting when ace shifted down to front of sorted cards" do
308
+ h1 = Hand.new('3c 4c 5s 6h 7d')
309
+ h2 = Hand.new('2c 3c 4c 5s Ah')
310
+ (h1 > h2).should be_true
311
+ (h1 < h2).should be_false
312
+ end
313
+
314
+ it "should compare a full house by card with three of a kind" do
315
+ h1 = Hand.new('7c 7d 7h 8c 8h')
316
+ h2 = Hand.new('3c 3d 3h 9c 9h')
317
+ (h1 > h2).should be_true
318
+ (h1 < h2).should be_false
319
+ end
320
+
321
+ it "should compare a full house by card with two of a kind of three of a kind same" do
322
+ h2 = Hand.new('Kc Kd Kh As Ah')
323
+ h1 = Hand.new('Kc Kd Kh 9s 9h')
324
+ (h2 > h1).should be_true
325
+ (h2 < h1).should be_false
326
+ end
327
+
328
+ it "should raise an error when comparing short/mismatch hands" do
329
+ h1 = Hand.new('Kc Kd Ks')
330
+ h2 = Hand.new('Ac As')
331
+ lambda { h1 > h2 }.should raise_error
332
+ lambda { h1 < h2 }.should raise_error
333
+ lambda { h1 == h2 }.should raise_error
334
+ lambda { h1 <=> h2 }.should raise_error
335
+ end
336
+
337
+ it "should compare greater than correctly" do
338
+ h1 = Hand.new('Ac Ad')
339
+ h2 = Hand.new('Ac Kd')
340
+ (h1 > h2).should be_true
341
+ (h2 > h1).should be_false
342
+ end
343
+
344
+ it "should compare less than correctly" do
345
+ h1 = Hand.new('Ac Ad')
346
+ h2 = Hand.new('Ac Kd')
347
+ (h1 < h2).should be_false
348
+ (h2 < h1).should be_true
349
+ end
350
+ end
@@ -0,0 +1,103 @@
1
+ require File.dirname(__FILE__) + "/../lib/player"
2
+ require File.dirname(__FILE__) + "/../lib/game"
3
+ include Holdem
4
+
5
+ describe Player do
6
+ before(:each) do
7
+ @p = Player.new
8
+ @p.deal(Card.new('4c'))
9
+ @p.deal(Card.new('3c'))
10
+ end
11
+
12
+ it "should be creatable" do
13
+ @p.should_not be_nil
14
+
15
+ @p.hole_cards.length.should == 2
16
+ @p.actions.length.should == 0
17
+ @p.in_pot.should == 0.0
18
+ @p.in_round.should == 0.0
19
+ @p.folded.should == false
20
+ end
21
+
22
+ it "should set the player's in pot amount to zero when created" do
23
+ @p.in_pot.should == 0.0
24
+ end
25
+
26
+ it "should accept two cards for hole cards" do
27
+ @p.hole_cards.length.should == 2
28
+ @p.hole_cards.join(' ').should == '4c 3c'
29
+ end
30
+
31
+ it "should not accept more than two hole cards" do
32
+ lambda { @p.deal(Card.new('5c')) }.should raise_error
33
+ end
34
+
35
+ it "should be able to tell the best hand from hole cards and board" do
36
+ board = [
37
+ Card.new('2c'),
38
+ Card.new('5c'),
39
+ Card.new('Ks'),
40
+ Card.new('Ac'),
41
+ Card.new('Qs')
42
+ ]
43
+ @p.find_hand(board)
44
+ @p.hand.ranking.should == :straight_flush
45
+ end
46
+
47
+ it "should increase amount in pot when paying" do
48
+ @p.pay(100.0)
49
+ @p.in_pot.should == 100.0
50
+ end
51
+
52
+ it "should increase amount in round when paying" do
53
+ @p.pay(34.0)
54
+ @p.in_round.should == 34.0
55
+ end
56
+
57
+ it "should decrease delta when paying" do
58
+ @p.pay(350.75)
59
+ @p.delta.should == -350.75
60
+ end
61
+
62
+ it "should increase delta when awarding" do
63
+ @p.award(50.0)
64
+ @p.delta.should == 50.0
65
+ end
66
+
67
+ it "should reset amount in round when moving to next round" do
68
+ @p.pay(56.0)
69
+ @p.next_round
70
+ @p.in_round.should == 0.0
71
+ end
72
+
73
+ it "should set folded to true when folding" do
74
+ @p.fold
75
+ @p.folded.should be_true
76
+ end
77
+
78
+ it "should not reset folded on move to next round" do
79
+ @p.pay(456.0)
80
+ @p.fold
81
+ @p.next_round
82
+ @p.folded.should be_true
83
+ end
84
+
85
+ it "should be able to decide on an action ('neutral' default)" do
86
+ g = Game.new(1.0)
87
+ @p.act(g).should == :neutral
88
+ end
89
+
90
+ it "should record player actions" do
91
+ @p.record_action(:neutral)
92
+ @p.record_action(:aggressive)
93
+ @p.record_action(:weak)
94
+ @p.actions.should == [:neutral, :aggressive, :weak]
95
+ end
96
+
97
+ it "should only track my last 300 actions" do
98
+ 307.times do
99
+ @p.record_action(:weak)
100
+ end
101
+ @p.actions.length.should == 300
102
+ end
103
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + "/../lib/rholdem"
2
+ include Holdem
3
+
4
+ describe "Loading the rholdem library" do
5
+ it "should be able to create a new Card" do
6
+ lambda {Card.new('As')}.should_not raise_error
7
+ end
8
+
9
+ it "should be able to create a new Deck" do
10
+ lambda {Deck.new}.should_not raise_error
11
+ end
12
+
13
+ it "should be able to create a new Hand" do
14
+ lambda {Hand.new('3c 4c 5c 6c 7c 8c')}.should_not raise_error
15
+ end
16
+
17
+ it "should be able to create a new Player" do
18
+ lambda {Player.new}.should_not raise_error
19
+ end
20
+
21
+ it "should be able to create a new Game" do
22
+ lambda {Game.new(10.0)}.should_not raise_error
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: rholdem
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-09-30 00:00:00 -07:00
8
+ summary: Ruby Texas Hold'em Simulations Library
9
+ require_paths:
10
+ - lib
11
+ email: russell.authur@gmail.com
12
+ homepage: " by Russell Authur"
13
+ rubyforge_project: rholdem
14
+ description: "== FEATURES/PROBLEMS: - Simulate limit games of 2 to 11 players - Provide custom AI players to test out ideas - Track totals for each player to use with AI fitness evaluation == SYNOPSIS: # run a sample game, 5/10 limit, 10 players require 'rubygems' require 'rholdem'"
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Russell Authur
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - lib/rholdem.rb
37
+ - lib/card.rb
38
+ - lib/deck.rb
39
+ - lib/game.rb
40
+ - lib/hand.rb
41
+ - lib/player.rb
42
+ - spec/rholdem_spec.rb
43
+ - spec/card_spec.rb
44
+ - spec/deck_spec.rb
45
+ - spec/game_spec.rb
46
+ - spec/hand_spec.rb
47
+ - spec/player_spec.rb
48
+ test_files: []
49
+
50
+ rdoc_options:
51
+ - --main
52
+ - README.txt
53
+ extra_rdoc_files:
54
+ - History.txt
55
+ - Manifest.txt
56
+ - README.txt
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ requirements: []
62
+
63
+ dependencies:
64
+ - !ruby/object:Gem::Dependency
65
+ name: hoe
66
+ version_requirement:
67
+ version_requirements: !ruby/object:Gem::Version::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 1.3.0
72
+ version: