Here's my solution, with a sample run. Comments, corrections, criticism welcome. /dh $ ./blackjack.rb Odds for each dealer outcome based on initial upcard (2 deck game) 17 18 19 20 21 BUST A 12.58% 12.82% 12.75% 12.85% 36.07% 12.93% 2 13.93% 13.33% 13.07% 12.39% 11.92% 35.36% 3 13.27% 13.06% 12.45% 12.18% 11.53% 37.50% 4 13.07% 12.02% 12.10% 11.63% 11.31% 39.88% 5 12.10% 12.28% 11.73% 10.90% 10.73% 42.25% 6 16.62% 10.62% 10.67% 10.12% 9.75% 42.21% 7 37.05% 13.82% 7.80% 7.88% 7.34% 26.11% 8 12.97% 36.12% 12.90% 6.89% 6.96% 24.16% 9 12.09% 11.20% 35.41% 12.11% 6.10% 23.09% 10 11.29% 11.22% 11.30% 33.56% 11.31% 21.32% J 11.29% 11.22% 11.30% 33.56% 11.31% 21.32% Q 11.29% 11.22% 11.30% 33.56% 11.31% 21.32% K 11.29% 11.22% 11.30% 33.56% 11.31% 21.32% $ cat blackjack.rb #!/usr/bin/env ruby CARDS = %w(A 2 3 4 5 6 7 8 9 10 J Q K) DECKS = ARGV.size == 1 ? ARGV[0].to_i : 2 SUITS = 4 def hand_value(hand) value = 0 # First calculate values ignoring aces hand.each do |c| if c=='A' next elsif 'JQK'.include? c value += 10 else value += c.to_i end end # Then add aces as 11 unless they would bust the hand hand.each do |c| if c=='A' if value>10 value += 1 else value += 11 end end end value end def new_shute cards = [] CARDS.each do |c| DECKS.times { SUITS.times { cards << c }} end cards end def odds_of(cards, v) count = 0 cards.each { |c| count += 1 if c==v } (1.0 * count) / cards.length end # calc the odds of reaching result from a given hand def calc_odds(hand, result) current = hand_value(hand) return 1.0 if current == result return 0.0 if current >= 17 # Remove hand cards from full shute cards = new_shute hand.each {|c| cards.delete_at(cards.index(c))} odds = 0.0 CARDS.each do |c| odds_of_card = odds_of(cards, c) if odds_of_card > 0.0 hand.push c odds_of_result = calc_odds(hand, result) odds += odds_of_card * odds_of_result hand.pop end end return odds end puts "Odds for each dealer outcome based on initial upcard (#{DECKS} deck game)" puts " 17 18 19 20 21 BUST" CARDS.each do |c| odds = {} bust = 100.0 (17..21).each do |r| odds[r] = calc_odds([c], r) * 100.0 bust -= odds[r] end printf "%2s %5.02f%% %5.02f%% %5.02f%% %5.02f%% %5.02f%% %5.02f%% \n", c, odds[17], odds[18], odds[19], odds[20], odds[21], bust end