-
Notifications
You must be signed in to change notification settings - Fork 0
/
21.rb
119 lines (105 loc) · 2.54 KB
/
21.rb
1
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
module Blackjack
class Dealer
def initialize
@cards = [2,3,4,5,6,7,8,9,10,10,10,10,"A"]*4
end
def deal
@cards.shuffle!.pop
end
end
class Player
def initialize(cards, dealer)
@number_aces = cards.select { |card| card.is_a? String }.size
sum = 0
cards.each do |card|
if card.is_a? Integer
sum += card
end
end
@fixed_sum = sum
@dealer = dealer
end
def want_card?
sum = process_aces
sum < 13
end
def hit_me!
if want_card?
card = @dealer.deal
update_attributes_with card
return true
end
false
end
def show_cards
@fixed_sum + @dynamic_sum
end
class << self
def who_want_cards
players = []
ObjectSpace.each_object(self) do |player|
players << player if player.want_card?
end
players
end
end
private
def process_aces
@dynamic_sum = 11*@number_aces
number_aces = @number_aces
while @dynamic_sum + @fixed_sum > 21 && number_aces > 0
@dynamic_sum -= 10
number_aces -= 1
end
@dynamic_sum + @fixed_sum
end
def update_attributes_with card
if card.is_a? Integer
@fixed_sum += card
else
@number_aces += 1
end
process_aces
end
end
class Analytics
def initialize(number_plays, verbose=false)
@number_plays = number_plays
@avg_hand ||= 0
@losses = 0
play(verbose)
show_statistics
end
def show_statistics
@avg_hand /= (@number_plays - @losses)
puts "--- Strategy statistics ---"
puts "Average hand: #{@avg_hand}"
puts "Number losses: #{@losses} (#{@losses*100/@number_plays}%)"
end
private
def play(verbose)
@number_plays.times do |time|
dealer = Blackjack::Dealer.new
cards = [dealer.deal, dealer.deal]
player = Blackjack::Player.new(cards, dealer)
counter = 0
while player.want_card?
player.hit_me!
counter += 1
end
if player.show_cards > 21
@losses += 1
else
@avg_hand += player.show_cards
end
show_game_statistics(cards, counter, player.show_cards, time) if verbose
end
end
def show_game_statistics(cards, counter, final_sum, number_game)
puts "--- Game Statistics ##{number_game} ---"
puts "Number of hit-me: #{counter}"
puts "Initial hand: #{cards}"
puts "final_sum: #{final_sum}"
end
end
end