Oshuma-gambler 0.0.2 → 0.0.3
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/History.txt +5 -0
- data/Manifest.txt +4 -0
- data/README.txt +3 -0
- data/Rakefile +11 -9
- data/bin/gambler_client +1 -207
- data/gambler.gemspec +22 -0
- data/lib/gambler.rb +2 -1
- data/lib/gambler/deck.rb +1 -1
- data/lib/gambler/exceptions.rb +5 -0
- data/lib/gambler/game/basic_game.rb +68 -0
- data/lib/gambler/game/blackjack.rb +102 -2
- data/lib/gambler/player.rb +21 -0
- data/tasks/docs.rake +1 -0
- data/tasks/site.rake +1 -0
- data/test/client/test_client.rb +8 -0
- data/test/client/test_client_helper.rb +8 -0
- data/test/game/test_blackjack.rb +84 -2
- data/test/test_gambler.rb +1 -1
- data/test/test_player.rb +17 -0
- metadata +16 -3
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -8,6 +8,8 @@ bin/gambler_client
|
|
8
8
|
gambler.gemspec
|
9
9
|
lib/gambler.rb
|
10
10
|
lib/gambler/card.rb
|
11
|
+
lib/gambler/client.rb
|
12
|
+
lib/gambler/client/client_helper.rb
|
11
13
|
lib/gambler/deck.rb
|
12
14
|
lib/gambler/exceptions.rb
|
13
15
|
lib/gambler/game.rb
|
@@ -21,6 +23,8 @@ tasks/override_rake_task.rb
|
|
21
23
|
tasks/rcov.rake
|
22
24
|
tasks/site.rake
|
23
25
|
tasks/util.rb
|
26
|
+
test/client/test_client.rb
|
27
|
+
test/client/test_client_helper.rb
|
24
28
|
test/game/test_basic_game.rb
|
25
29
|
test/game/test_blackjack.rb
|
26
30
|
test/helper.rb
|
data/README.txt
CHANGED
@@ -27,6 +27,9 @@ Pure Ruby, so far.
|
|
27
27
|
$ gem sources -a http://gems.github.com/ (You only need to do this once.)
|
28
28
|
$ gem install Oshuma-gambler
|
29
29
|
|
30
|
+
== USAGE:
|
31
|
+
See http://gambler.rubyforge.org/api/ for usage documentation.
|
32
|
+
|
30
33
|
== LICENSE:
|
31
34
|
|
32
35
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
data/Rakefile
CHANGED
@@ -29,15 +29,17 @@ Dir["#{GAMBLER_ROOT}/tasks/**/*.rake"].sort.each { |task| load task }
|
|
29
29
|
|
30
30
|
task :default => [ :test, :rcov ]
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
namespace :gambler do
|
33
|
+
desc 'Clean up dynamically generated files'
|
34
|
+
task :cleanup do
|
35
|
+
%w{
|
36
|
+
docs:clear
|
37
|
+
issues:report:clear
|
38
|
+
rcov:clear
|
39
|
+
site:clear_local
|
40
|
+
}.each do |clean|
|
41
|
+
Rake::Task[clean].invoke
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
data/bin/gambler_client
CHANGED
@@ -4,211 +4,5 @@ GAMBLER_ROOT = File.join(File.dirname(__FILE__), '..')
|
|
4
4
|
$LOAD_PATH.unshift File.join(GAMBLER_ROOT, 'lib')
|
5
5
|
require 'gambler'
|
6
6
|
|
7
|
-
|
8
|
-
# A simple Client which allows you to play around with Gambler.
|
9
|
-
# Most of this class can be ignored, as it just sets up the gaming
|
10
|
-
# environment. The method to pay attention to is +play_blackjack+.
|
11
|
-
# This is the method that actually creates and deals a Blackjack game.
|
12
|
-
class Client
|
13
|
-
WIDTH = 50
|
14
|
-
|
15
|
-
$player_quits = false
|
16
|
-
|
17
|
-
attr_accessor :bots
|
18
|
-
attr_accessor :player
|
19
|
-
|
20
|
-
def initialize
|
21
|
-
@player = setup_player
|
22
|
-
@bots = Array.new
|
23
|
-
end
|
24
|
-
|
25
|
-
# This is the main client menu.
|
26
|
-
def menu
|
27
|
-
display_header
|
28
|
-
until $player_quits do
|
29
|
-
display_player_stats
|
30
|
-
display_game_menu
|
31
|
-
choice = STDIN.gets.chomp
|
32
|
-
|
33
|
-
case choice
|
34
|
-
when '1':
|
35
|
-
play_blackjack
|
36
|
-
when '2':
|
37
|
-
puts 'This game is not implemented yet.'
|
38
|
-
when '3':
|
39
|
-
puts 'This game is not implemented yet.'
|
40
|
-
when /a/i:
|
41
|
-
add_ai_player
|
42
|
-
when /p/i:
|
43
|
-
setup_player
|
44
|
-
when /d/i:
|
45
|
-
debug_console
|
46
|
-
when /q/i:
|
47
|
-
$player_quits = true
|
48
|
-
exit
|
49
|
-
else
|
50
|
-
puts 'Invalid choice, dumbass.'
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end # of menu
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
# Add an AI Player as an opponent.
|
58
|
-
def add_ai_player
|
59
|
-
@bots << setup_player(:bot => true)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Simple debugging console.
|
63
|
-
def debug_console
|
64
|
-
stop_debug = false
|
65
|
-
code = Array.new
|
66
|
-
|
67
|
-
puts # spacer
|
68
|
-
puts '== DEBUG CONSOLE =='
|
69
|
-
puts 'Commands:'
|
70
|
-
puts ' /run - Quit debugger and run the code.'
|
71
|
-
puts ' /show - Show the code currently in the buffer.'
|
72
|
-
puts ' /quit - Quit debugger without running the code.'
|
73
|
-
|
74
|
-
until stop_debug do
|
75
|
-
print "eval:#{code.size + 1}> "
|
76
|
-
line = STDIN.gets.chomp
|
77
|
-
|
78
|
-
case line
|
79
|
-
when '/run':
|
80
|
-
run_code(code)
|
81
|
-
stop_debug = true
|
82
|
-
when '/show':
|
83
|
-
show_code_buffer(code)
|
84
|
-
when '/quit':
|
85
|
-
stop_debug = true
|
86
|
-
else # not a command, must be some Ruby code.
|
87
|
-
code << line
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end # of debug_console
|
91
|
-
|
92
|
-
# Client header.
|
93
|
-
def display_header
|
94
|
-
puts # spacer
|
95
|
-
puts ''.center(WIDTH, '=')
|
96
|
-
puts " Gambler v#{Gambler::VERSION} ".center(WIDTH, '=')
|
97
|
-
puts ''.center(WIDTH, '=')
|
98
|
-
puts '----------------------------------------'.center(WIDTH)
|
99
|
-
puts '| Feeding yet another human addiction. |'.center(WIDTH)
|
100
|
-
puts '----------------------------------------'.center(WIDTH)
|
101
|
-
end # of display_header
|
102
|
-
|
103
|
-
# Pretty print the player's stats.
|
104
|
-
def display_player_stats
|
105
|
-
puts '- Players -'.center(WIDTH)
|
106
|
-
seperator = "\t"
|
107
|
-
stat_width = WIDTH - 5
|
108
|
-
stats = String.new
|
109
|
-
bot_stats = String.new
|
110
|
-
|
111
|
-
stats << "Player: #{@player.name}".ljust(WIDTH/2)
|
112
|
-
stats << seperator
|
113
|
-
stats << "Chips: #{@player.chips}"
|
114
|
-
puts stats.center(stat_width)
|
115
|
-
|
116
|
-
if @bots.empty?
|
117
|
-
puts 'No AI opponents.'.center(WIDTH)
|
118
|
-
else
|
119
|
-
@bots.each do |bot|
|
120
|
-
bot_stats = "AI: #{bot.name}".ljust(WIDTH/2)
|
121
|
-
bot_stats << seperator
|
122
|
-
bot_stats << "Chips: #{bot.chips}"
|
123
|
-
puts bot_stats.center(stat_width)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end # of display_player_stats
|
127
|
-
|
128
|
-
# Client game menu.
|
129
|
-
def display_game_menu
|
130
|
-
puts '-----------------------'.center(WIDTH)
|
131
|
-
puts '| 1) Blackjack |'.center(WIDTH)
|
132
|
-
puts '| 2) Stud Poker |'.center(WIDTH)
|
133
|
-
puts "| 3) Texas Hold 'em |".center(WIDTH)
|
134
|
-
puts '| A) Add AI Player |'.center(WIDTH)
|
135
|
-
puts '| D) Debug Console |'.center(WIDTH)
|
136
|
-
puts '| P) Setup Player |'.center(WIDTH)
|
137
|
-
puts '| Q) Quit |'.center(WIDTH)
|
138
|
-
puts '-----------------------'.center(WIDTH)
|
139
|
-
puts
|
140
|
-
print 'Game: '
|
141
|
-
end # of display_menu
|
142
|
-
|
143
|
-
# Play a quick 1vs1 game of Blackjack.
|
144
|
-
def play_blackjack
|
145
|
-
begin
|
146
|
-
# Create an array and add the player and bots.
|
147
|
-
players = Array.new
|
148
|
-
players << @player
|
149
|
-
players << @bots
|
150
|
-
players.flatten!
|
151
|
-
|
152
|
-
@game = Gambler::Game::Blackjack.new(:players => players)
|
153
|
-
rescue Gambler::Exceptions::InvalidPlayerSize
|
154
|
-
puts 'Need at least 2 players for blackjack.'
|
155
|
-
until @bots.size >= 1
|
156
|
-
@bots << setup_player(:bot => true)
|
157
|
-
end
|
158
|
-
retry
|
159
|
-
end # of begin ZOMG!!1
|
160
|
-
end # of play_blackjack
|
161
|
-
|
162
|
-
# Takes an array of +code+ lines and <tt>eval</tt>'s them.
|
163
|
-
def run_code(code)
|
164
|
-
puts # spacer
|
165
|
-
begin
|
166
|
-
puts " BEGIN DEBUG ".center(WIDTH, '=')
|
167
|
-
eval(code.join("\n")) # Need to join, since +code+ is an Array.
|
168
|
-
puts " END DEBUG ".center(WIDTH, '=')
|
169
|
-
rescue Exception => error
|
170
|
-
puts " DEBUG FAILED ".center(WIDTH, '=')
|
171
|
-
puts error
|
172
|
-
end
|
173
|
-
puts # spacer
|
174
|
-
end
|
175
|
-
|
176
|
-
# Setup a new Player instance.
|
177
|
-
def setup_player(options = {})
|
178
|
-
default_chips = 100
|
179
|
-
if options[:bot]
|
180
|
-
who = 'AI player'
|
181
|
-
default_name = 'Kenny'
|
182
|
-
else
|
183
|
-
who = 'your player'
|
184
|
-
default_name = 'Human'
|
185
|
-
end
|
186
|
-
|
187
|
-
puts "Setting up #{who}."
|
188
|
-
print "Name [#{default_name}]: "
|
189
|
-
name = STDIN.gets.chomp
|
190
|
-
name = default_name if name.empty?
|
191
|
-
|
192
|
-
print "Chips [#{default_chips}]: "
|
193
|
-
chips = STDIN.gets.chomp.to_i
|
194
|
-
chips = default_chips if chips.zero?
|
195
|
-
|
196
|
-
return Gambler::Player.new(name, :chips => chips)
|
197
|
-
end # of setup_player
|
198
|
-
|
199
|
-
# Takes an array of +code+ lines and prints them.
|
200
|
-
def show_code_buffer(code)
|
201
|
-
return (puts "Buffer empty.") if code.size.zero?
|
202
|
-
puts "== BUFFER ==\n"
|
203
|
-
code.each_with_index do |buf, line_num|
|
204
|
-
print "#{line_num + 1}: ".rjust(5)
|
205
|
-
puts buf
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
end # of Client
|
210
|
-
|
211
|
-
end # of Gambler
|
212
|
-
|
213
|
-
# Let's do this!
|
7
|
+
# See lib/gambler/client.rb
|
214
8
|
Gambler::Client.new.menu
|
data/gambler.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'gambler'
|
3
|
+
s.version = '0.0.3'
|
4
|
+
s.date = '2008-06-09'
|
5
|
+
|
6
|
+
s.authors = ['Dale Campbell']
|
7
|
+
s.email = ['dale@save-state.net']
|
8
|
+
s.homepage = 'http://gambler.rubyforge.org/'
|
9
|
+
|
10
|
+
s.summary = 'Ruby library to satisfy yet another human addiction.'
|
11
|
+
s.description = "Gambler is a Ruby library which can be included into other classes/modules. It provides an object oriented interface for common gambling games such as Blackjack, Poker, etc."
|
12
|
+
|
13
|
+
s.require_paths = ['lib']
|
14
|
+
s.files = ['History.txt', 'Manifest.txt', 'README', 'README.rdoc', 'README.txt', 'Rakefile', 'bin/gambler_client', 'gambler.gemspec', 'lib/gambler.rb', 'lib/gambler/card.rb', 'lib/gambler/deck.rb', 'lib/gambler/exceptions.rb', 'lib/gambler/game.rb', 'lib/gambler/game/basic_game.rb', 'lib/gambler/game/blackjack.rb', 'lib/gambler/player.rb', 'tasks/ditz.rake', 'tasks/docs.rake', 'tasks/git.rake', 'tasks/override_rake_task.rb', 'tasks/rcov.rake', 'tasks/site.rake', 'tasks/util.rb', 'test/game/test_basic_game.rb', 'test/game/test_blackjack.rb', 'test/helper.rb', 'test/suite.rb', 'test/test_card.rb', 'test/test_deck.rb', 'test/test_gambler.rb', 'test/test_player.rb', 'test/client/test_client.rb', 'test/client/test_client_helper.rb']
|
15
|
+
s.test_files = ['test/client/test_client.rb', 'test/client/test_client_helper.rb', 'test/game/test_basic_game.rb', 'test/game/test_blackjack.rb', 'test/test_card.rb', 'test/test_deck.rb', 'test/test_gambler.rb', 'test/test_player.rb']
|
16
|
+
|
17
|
+
s.has_rdoc = true
|
18
|
+
s.rdoc_options = ['--main', 'README.txt']
|
19
|
+
s.extra_rdoc_files = ['History.txt', 'Manifest.txt', 'README.txt']
|
20
|
+
|
21
|
+
s.add_dependency('hoe', '>= 1.5.3')
|
22
|
+
end
|
data/lib/gambler.rb
CHANGED
@@ -6,6 +6,7 @@ require 'rubygems'
|
|
6
6
|
|
7
7
|
# Gambler libraries.
|
8
8
|
require 'gambler/card'
|
9
|
+
require 'gambler/client'
|
9
10
|
require 'gambler/deck'
|
10
11
|
require 'gambler/exceptions'
|
11
12
|
require 'gambler/game'
|
@@ -20,5 +21,5 @@ module Gambler
|
|
20
21
|
|
21
22
|
self.debug = false
|
22
23
|
|
23
|
-
VERSION = '0.0.
|
24
|
+
VERSION = '0.0.3'
|
24
25
|
end
|
data/lib/gambler/deck.rb
CHANGED
data/lib/gambler/exceptions.rb
CHANGED
@@ -5,8 +5,12 @@ module Gambler
|
|
5
5
|
# Gambler
|
6
6
|
class MustOverrideMethod < Exception; end
|
7
7
|
|
8
|
+
# Blackjack
|
9
|
+
class PlayerBust < Exception; end
|
10
|
+
|
8
11
|
# Card
|
9
12
|
class InvalidCardType < Exception; end
|
13
|
+
class NoWinner < Exception; end
|
10
14
|
|
11
15
|
# Deck
|
12
16
|
class DeckEmpty < Exception; end
|
@@ -15,6 +19,7 @@ module Gambler
|
|
15
19
|
# Game
|
16
20
|
class InvalidPlayers < Exception; end
|
17
21
|
class InvalidPlayerSize < Exception; end
|
22
|
+
class NotEnoughChips < Exception; end
|
18
23
|
class NoPlayers < Exception; end
|
19
24
|
|
20
25
|
# Player
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Gambler
|
2
|
+
|
3
|
+
module Game
|
4
|
+
|
5
|
+
# The basic game class in which all others can inherit.
|
6
|
+
# Feel free to create your own game class which does not inherit
|
7
|
+
# from BasicGame, but uses Player, Deck, etc. directly.
|
8
|
+
#
|
9
|
+
# BasicGame gives some free functionality to it's children:
|
10
|
+
# * <tt>players</tt>: Instance reader for the game's Player(s).
|
11
|
+
# * <tt>ante</tt>: Instance accessor for the game's current ante.
|
12
|
+
# * <tt>deck</tt>: Brand new, fully shuffled Deck to play with.
|
13
|
+
# * <tt>pot</tt>: Instance accessor for the game's current pot.
|
14
|
+
#
|
15
|
+
# The +options+ hash only requires one element, +players+, which must
|
16
|
+
# be an array of Gambler::Player object(s).
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
# class Poker < Gambler::Game::BasicGame
|
20
|
+
# def initialize(options = {})
|
21
|
+
# # .. do custom shit (if needed) ..
|
22
|
+
# super(options) # Required to recieve free functionality.
|
23
|
+
# # .. more custom shit (if needed) ..
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# def poker_stuff
|
27
|
+
# !cheat
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# # Create some players.
|
32
|
+
# @dale = Gambler::Player.new('Dale')
|
33
|
+
# @kenny = Gambler::Player.new('Kenny')
|
34
|
+
#
|
35
|
+
# # This will be passed to Poker.new.
|
36
|
+
# options = {
|
37
|
+
# :players => [@dale, @kenny], # The only required option.
|
38
|
+
# :ante => 50,
|
39
|
+
# :pot => 1_000
|
40
|
+
# }
|
41
|
+
#
|
42
|
+
# @game = Poker.new(options)
|
43
|
+
# @game.poker_stuff
|
44
|
+
class BasicGame
|
45
|
+
INITIAL_ANTE = 10
|
46
|
+
INITIAL_POT = 0
|
47
|
+
|
48
|
+
attr_reader :players
|
49
|
+
attr_accessor :ante, :deck, :pot
|
50
|
+
|
51
|
+
def initialize(options = {})
|
52
|
+
raise Exceptions::NoPlayers unless options[:players].size > 0
|
53
|
+
options[:players].each do |player|
|
54
|
+
raise Exceptions::InvalidPlayers unless player.is_a? Player
|
55
|
+
end
|
56
|
+
@players = options[:players]
|
57
|
+
|
58
|
+
@deck = Deck.new
|
59
|
+
3.times { @deck.shuffle! }
|
60
|
+
|
61
|
+
@ante = options[:ante] || INITIAL_ANTE
|
62
|
+
@pot = options[:pot] || INITIAL_POT
|
63
|
+
end
|
64
|
+
end # of BasicGame
|
65
|
+
|
66
|
+
end # of Game
|
67
|
+
|
68
|
+
end # of Gambler
|
@@ -4,25 +4,125 @@ module Gambler
|
|
4
4
|
|
5
5
|
# The Game of Blackjack.
|
6
6
|
class Blackjack < Gambler::Game::BasicGame
|
7
|
+
BUST = 21 # The hand_value in which the Player busts.
|
7
8
|
INITIAL_CARDS = 2
|
8
9
|
|
10
|
+
# These are used instead of Card::FACE_VALUES to accommodate Blackjack.
|
11
|
+
FACE_VALUES = {
|
12
|
+
'A' => 11,
|
13
|
+
'K' => 10,
|
14
|
+
'Q' => 10,
|
15
|
+
'J' => 10,
|
16
|
+
'T' => 10,
|
17
|
+
'9' => 9,
|
18
|
+
'8' => 8,
|
19
|
+
'7' => 7,
|
20
|
+
'6' => 6,
|
21
|
+
'5' => 5,
|
22
|
+
'4' => 4,
|
23
|
+
'3' => 3,
|
24
|
+
'2' => 2,
|
25
|
+
'L' => 1 # Magic low Ace.
|
26
|
+
}
|
27
|
+
|
28
|
+
attr_reader :players_in_round
|
29
|
+
attr_reader :round_winner
|
30
|
+
|
9
31
|
def initialize(options = {})
|
10
32
|
raise Exceptions::InvalidPlayerSize unless options[:players].size >= 2
|
11
33
|
super(options)
|
12
34
|
@players.each { |player| player.empty_hand! }
|
35
|
+
@players_in_round = Array.new
|
36
|
+
@players_in_round.replace(@players)
|
37
|
+
@round_winner = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# Forces each Player to put ante in the pot.
|
41
|
+
def ante_up!
|
42
|
+
@players_in_round.each { |player| place_bet(player, @ante) }
|
43
|
+
end
|
44
|
+
|
45
|
+
# Calculates the integer value for a Blackjack +hand+.
|
46
|
+
# Aces are converted to their lower value if the total hand value
|
47
|
+
# will bust the Player (and there are aces in the +hand+, of course).
|
48
|
+
def hand_value(hand)
|
49
|
+
return 0 if hand.empty?
|
50
|
+
value = 0
|
51
|
+
|
52
|
+
# Add up the face values
|
53
|
+
hand.each do |card|
|
54
|
+
value += FACE_VALUES[card.face]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Handle any needed Ace changes.
|
58
|
+
while value > BUST
|
59
|
+
hand.each do |card|
|
60
|
+
if card.face == 'A'
|
61
|
+
# Subtract the difference between high and low ace (10).
|
62
|
+
value -= (FACE_VALUES['A'] - FACE_VALUES['L'])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
break # no aces to change, bail
|
66
|
+
end
|
67
|
+
|
68
|
+
return value
|
69
|
+
end # of hand_value
|
70
|
+
|
71
|
+
# Give +player+ a Card.
|
72
|
+
def hit(player)
|
73
|
+
@deck.deal_to player
|
74
|
+
if player_bust?(player)
|
75
|
+
@players_in_round.delete(player)
|
76
|
+
raise Exceptions::PlayerBust
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Allows +player+ to place a bet for +amount+ which will be added to
|
81
|
+
# the current hand's pot.
|
82
|
+
def place_bet(player, amount)
|
83
|
+
raise Exceptions::NotEnoughChips if player.chips < amount
|
84
|
+
@pot += amount
|
85
|
+
player.chips -= amount
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns true of the Player's hand has a value above BUST.
|
89
|
+
def player_bust?(player)
|
90
|
+
hand_value(player.hand) > BUST
|
91
|
+
end
|
92
|
+
|
93
|
+
# This should be called at the beginning of every round (not game),
|
94
|
+
# and sets up things like the ante and dealing initial hands.
|
95
|
+
def start_round!
|
96
|
+
@players.each { |player| player.empty_hand! }
|
97
|
+
@players_in_round.replace(@players)
|
98
|
+
@round_winner = nil
|
99
|
+
ante_up!
|
13
100
|
deal_initial_hands
|
14
101
|
end
|
15
102
|
|
103
|
+
# This should be called after all players bust or stay. Sets the
|
104
|
+
# <tt>@round_winner</tt> variable to the Player object who won and
|
105
|
+
# gives them the pot.
|
106
|
+
def finish_round!
|
107
|
+
raise Exceptions::NoWinner if @players_in_round.nil?
|
108
|
+
# The winner is the Player with the highest hand_value.
|
109
|
+
@round_winner = @players_in_round.sort_by do |player|
|
110
|
+
hand_value(player.hand)
|
111
|
+
end.reverse.first
|
112
|
+
@round_winner.chips += @pot
|
113
|
+
@pot = INITIAL_POT
|
114
|
+
end
|
115
|
+
|
16
116
|
private
|
17
117
|
|
18
118
|
# Deal out the initial cards to each Player.
|
19
119
|
def deal_initial_hands
|
20
120
|
INITIAL_CARDS.times do
|
21
|
-
@
|
121
|
+
@players_in_round.each do |player|
|
22
122
|
@deck.deal_to player
|
23
123
|
end
|
24
124
|
end
|
25
|
-
end
|
125
|
+
end # of deal_initial_hands
|
26
126
|
|
27
127
|
end # of Blackjack
|
28
128
|
|
data/lib/gambler/player.rb
CHANGED
@@ -37,12 +37,33 @@ module Gambler
|
|
37
37
|
%Q{#<Gambler::Player '#{@name}'>}
|
38
38
|
end
|
39
39
|
|
40
|
+
# Return true/false depending on if the Player has chips.
|
41
|
+
def is_broke?
|
42
|
+
@chips <= 0
|
43
|
+
end
|
44
|
+
|
40
45
|
# Pretty printing of a Player.
|
41
46
|
def to_s
|
42
47
|
"#{@name} ($#{@chips})"
|
43
48
|
end
|
44
49
|
|
45
50
|
# Allows a Player to view their +hand+ in various formats.
|
51
|
+
# Examples:
|
52
|
+
# @player = Player.new('Dale', :hand => [Card.new('Ad'), Card.new('Kd')])
|
53
|
+
#
|
54
|
+
# # :format => :array (the default)
|
55
|
+
# @player.view_hand
|
56
|
+
# => ['Ad', 'Kd']
|
57
|
+
# @player.view_hand(:pretty => true)
|
58
|
+
# => ['Ace of Diamonds', 'King of Diamonds']
|
59
|
+
#
|
60
|
+
# # :format => :string
|
61
|
+
# @player.view_hand(:format => :string)
|
62
|
+
# => 'Ad Kd'
|
63
|
+
# @player.view_hand(:format => :string, :pretty => true)
|
64
|
+
# => 'Ace of Diamonds, King of Diamonds'
|
65
|
+
# @player.view_hand(:format => :string, :pretty => true, :seperator => ' | ')
|
66
|
+
# => 'Ace of Diamonds | King of Diamonds'
|
46
67
|
def view_hand(options = {})
|
47
68
|
format = options[:format] || :array
|
48
69
|
pretty = options[:pretty] || false
|
data/tasks/docs.rake
CHANGED
data/tasks/site.rake
CHANGED
data/test/game/test_blackjack.rb
CHANGED
@@ -6,15 +6,17 @@ class TestBlackjack < Test::Unit::TestCase
|
|
6
6
|
|
7
7
|
def setup
|
8
8
|
@dale = Player.new('Dale')
|
9
|
-
@kenny = Player.new('
|
9
|
+
@kenny = Player.new('The Gambler')
|
10
10
|
@game = Blackjack.new(:players => [@dale, @kenny])
|
11
|
+
@game.start_round!
|
11
12
|
end
|
12
13
|
|
13
14
|
def test_new_blackjack_game
|
14
15
|
assert_kind_of(Blackjack, @game)
|
15
16
|
assert_equal(10, @game.ante)
|
16
|
-
assert_equal(
|
17
|
+
assert_equal(20, @game.pot)
|
17
18
|
assert_kind_of(Deck, @game.deck)
|
19
|
+
assert(@game.deck.shuffled, "#{@game.deck} not shuffled")
|
18
20
|
end
|
19
21
|
|
20
22
|
def test_invalid_player_size
|
@@ -23,4 +25,84 @@ class TestBlackjack < Test::Unit::TestCase
|
|
23
25
|
Blackjack.new(:players => [@dale])
|
24
26
|
end
|
25
27
|
end
|
28
|
+
|
29
|
+
def test_ante_up!
|
30
|
+
@game.ante_up!
|
31
|
+
assert_equal(40, @game.pot)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_hand_value
|
35
|
+
@player = Player.new('Newb', :hand => [ Card.new('2s'), Card.new('3s') ])
|
36
|
+
assert_equal(5, @game.hand_value(@player.hand))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_hand_value_with_aces
|
40
|
+
@player = Player.new('Newb', :hand => [
|
41
|
+
Card.new('As'), Card.new('2s'), Card.new('3s') ])
|
42
|
+
assert_equal(16, @game.hand_value(@player.hand))
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_hand_value_treating_ace_as_one
|
46
|
+
@player = Player.new('Newb', :hand => [
|
47
|
+
Card.new('As'), Card.new('2s'), Card.new('Ks') ])
|
48
|
+
assert_equal(13, @game.hand_value(@player.hand))
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_hit # shouldn't bust
|
52
|
+
@dale.hand = [ Card.new('2d'), Card.new('3d') ]
|
53
|
+
@game.hit(@dale)
|
54
|
+
assert_equal(3, @dale.hand.size)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_place_bet
|
58
|
+
@game.place_bet(@dale, 10)
|
59
|
+
assert_equal(30, @game.pot)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_player_bust?
|
63
|
+
@dale.hand = [ Card.new('Kd'), Card.new('Qd') ]
|
64
|
+
assert_raise(Exceptions::PlayerBust) do
|
65
|
+
@game.hit @dale
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_start_round!
|
70
|
+
@game = Blackjack.new(:players => [@dale, @kenny])
|
71
|
+
assert(@dale.hand.empty?, "#{@dale}'s hand is not empty")
|
72
|
+
assert(@kenny.hand.empty?, "#{@kenny}'s hand is not empty")
|
73
|
+
assert_equal(0, @game.pot)
|
74
|
+
@game.start_round!
|
75
|
+
assert_equal(2, @dale.hand.size)
|
76
|
+
assert_equal(2, @kenny.hand.size)
|
77
|
+
assert_equal(20, @game.pot)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_finish_round!
|
81
|
+
@winner = Player.new('Winner')
|
82
|
+
@middle = Player.new('Middle')
|
83
|
+
@loser = Player.new('Loser')
|
84
|
+
|
85
|
+
# Randomize the order.
|
86
|
+
players = [@winner, @middle, @loser].sort_by { rand }
|
87
|
+
@game = Blackjack.new(:players => players)
|
88
|
+
@game.start_round!
|
89
|
+
|
90
|
+
# Used in the asserts below.
|
91
|
+
winner_chips = @winner.chips
|
92
|
+
middle_chips = @middle.chips
|
93
|
+
loser_chips = @loser.chips
|
94
|
+
pot = @game.pot
|
95
|
+
|
96
|
+
# Craft a round with a known outcome.
|
97
|
+
@winner.hand = [Card.new('Kd'), Card.new('Ks')] # => 20
|
98
|
+
@middle.hand = [Card.new('5h'), Card.new('5c')] # => 10
|
99
|
+
@loser.hand = [Card.new('2d'), Card.new('2s')] # => 4
|
100
|
+
@game.finish_round!
|
101
|
+
|
102
|
+
assert_equal(@winner, @game.round_winner)
|
103
|
+
assert_equal((winner_chips + pot), @winner.chips)
|
104
|
+
assert_equal(middle_chips, @middle.chips)
|
105
|
+
assert_equal(loser_chips, @loser.chips)
|
106
|
+
assert_equal(0, @game.pot)
|
107
|
+
end
|
26
108
|
end
|
data/test/test_gambler.rb
CHANGED
data/test/test_player.rb
CHANGED
@@ -72,6 +72,13 @@ class TestPlayer < Test::Unit::TestCase
|
|
72
72
|
assert_equal(pretty_hand, @player.view_hand(:format => :string, :pretty => true))
|
73
73
|
end
|
74
74
|
|
75
|
+
def test_view_hand_as_pretty_string_with_seperator
|
76
|
+
@player = Player.new('Dale', :hand => [Card.new('Ad'), Card.new('Kd')])
|
77
|
+
pretty_hand = 'Ace of Diamonds | King of Diamonds'
|
78
|
+
assert_equal(pretty_hand,
|
79
|
+
@player.view_hand(:format => :string, :pretty => true, :seperator => ' | '))
|
80
|
+
end
|
81
|
+
|
75
82
|
def test_default_chip_stack
|
76
83
|
assert_equal(100, @player.chips)
|
77
84
|
end
|
@@ -93,4 +100,14 @@ class TestPlayer < Test::Unit::TestCase
|
|
93
100
|
@player.chips += pot # You win!
|
94
101
|
assert_equal(pot + chips, @player.chips)
|
95
102
|
end
|
103
|
+
|
104
|
+
def test_is_broke?
|
105
|
+
@player.chips = 0
|
106
|
+
assert(@player.is_broke?, "#{@player} isn't broke")
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_is_not_broke
|
110
|
+
assert_equal(100, @player.chips)
|
111
|
+
assert_equal(false, @player.is_broke?)
|
112
|
+
end
|
96
113
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Oshuma-gambler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Campbell
|
@@ -11,8 +11,16 @@ cert_chain: []
|
|
11
11
|
|
12
12
|
date: 2008-06-09 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.5.3
|
23
|
+
version:
|
16
24
|
description: Gambler is a Ruby library which can be included into other classes/modules. It provides an object oriented interface for common gambling games such as Blackjack, Poker, etc.
|
17
25
|
email:
|
18
26
|
- dale@save-state.net
|
@@ -32,6 +40,7 @@ files:
|
|
32
40
|
- README.txt
|
33
41
|
- Rakefile
|
34
42
|
- bin/gambler_client
|
43
|
+
- gambler.gemspec
|
35
44
|
- lib/gambler.rb
|
36
45
|
- lib/gambler/card.rb
|
37
46
|
- lib/gambler/deck.rb
|
@@ -55,6 +64,8 @@ files:
|
|
55
64
|
- test/test_deck.rb
|
56
65
|
- test/test_gambler.rb
|
57
66
|
- test/test_player.rb
|
67
|
+
- test/client/test_client.rb
|
68
|
+
- test/client/test_client_helper.rb
|
58
69
|
has_rdoc: true
|
59
70
|
homepage: http://gambler.rubyforge.org/
|
60
71
|
post_install_message:
|
@@ -83,6 +94,8 @@ signing_key:
|
|
83
94
|
specification_version: 2
|
84
95
|
summary: Ruby library to satisfy yet another human addiction.
|
85
96
|
test_files:
|
97
|
+
- test/client/test_client.rb
|
98
|
+
- test/client/test_client_helper.rb
|
86
99
|
- test/game/test_basic_game.rb
|
87
100
|
- test/game/test_blackjack.rb
|
88
101
|
- test/test_card.rb
|