Skip to content

Instantly share code, notes, and snippets.

@bakineggs
Created July 9, 2010 18:04
Show Gist options
  • Select an option

  • Save bakineggs/469793 to your computer and use it in GitHub Desktop.

Select an option

Save bakineggs/469793 to your computer and use it in GitHub Desktop.
# some blackjack tables in Vegas were standing on soft 17, so it made me wonder what were the probable outcomes of hitting soft 17. if you want to see the possible outcomes of a different starting scenario, change the initial contents of "processing"
class Deck
def initialize counts = nil, total = nil
unless counts.nil?
@counts = counts
@total = total
return
end
@counts = {}
2.upto(9).each {|value| @counts[value] = 4}
@counts[10] = 16 # 4 each of T, J, Q, K
@counts[11] = 4
@total = 52 # instead of constantly summing the counts
end
# returns hash of values mapped to probabilities
def next_card
probabilities = @counts.map {|value, count| [value, count * 1.0 / @total]}
Hash[probabilities].reject {|value, count| count == 0}
end
def pull value
raise 'trying to pull a card not in the deck' if @counts[value] == 0
counts = @counts.dup
counts[value] -= 1
Deck.new(counts, @total - 1)
end
end
class Hand
attr_accessor :probability, :deck, :softness
def initialize probability, value, deck, softness
while value > 21 && softness >= 1
value -= 10
softness -= 1
end
self.probability = probability
self.value = value
self.deck = deck
self.softness = softness
end
def done?
value == :bust || value > 17 || (value == 17 && softness == 0)
end
def value
return :bust if @value > 21
@value
end
private
attr_writer :value
end
outcomes = {}
17.upto(21).each {|value| outcomes[value] = 0}
outcomes[:bust] = 0
processing = [Hand.new 1, 17, Deck.new.pull(11).pull(6), 1]
count = 0
until processing.empty?
count += 1
hand = processing.pop
if hand.done?
outcomes[hand.value] += hand.probability
next
end
hand.deck.next_card.each do |value, probability|
softness = hand.softness
softness += 1 if value == 11
processing.push Hand.new(hand.probability * probability, hand.value + value, hand.deck.pull(value), softness)
end
end
outcomes.each do |value, probability|
puts "#{value}: #{probability}"
end
puts "analyzed #{count} hands"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment