Created
July 9, 2010 18:04
-
-
Save bakineggs/469793 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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