Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Hearthstone packs needed to complete collection

By: a guest on Apr 2nd, 2013  |  syntax: Ruby  |  size: 4.24 KB  |  hits: 47  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. TOTAL_CARDS = { :common => 100, :rare => 70, :epic => 50, :legendary => 30 }
  2. RARITY_CHANCE = { :legendary => 0.005, :epic => 0.025, :rare => 0.1, :common => 1 }
  3. DISENCHANTED_ARCANE_DUST = { :common => 2, :rare => 10, :epic => 100, :legendary => 400 }
  4. CRAFT_ARCANE_DUST = { :legendary => 1600, :epic => 400, :rare => 100, :common => 10 }
  5. CARDS_PER_PACK = 5
  6.  
  7. class Card
  8.   attr_accessor :rarity, :number
  9.   def initialize(rarity, number)
  10.     @rarity = rarity
  11.     @number = number
  12.   end
  13. end
  14.  
  15. class PackGenerator
  16.  
  17.   def initialize
  18.     @collection = { :common => [], :rare => [], :epic => [], :legendary => [] }
  19.     @arcane_dust = 0
  20.     @packs_open = 0
  21.     @disenchanted = 0
  22.   end
  23.  
  24.   def check_packs_needed
  25.     while !is_collection_complete?
  26.       add_collection(random_pack)
  27.       @packs_open += 1
  28.       #puts info
  29.     end
  30.    
  31.     return @packs_open
  32.   end
  33.  
  34.   def add_collection(pack)
  35.     pack.each do |card|
  36.       unless @collection[card.rarity].any? { |c| c.number == card.number }
  37.         @collection[card.rarity] << card
  38.       else
  39.         disenchant_card(card)
  40.       end
  41.     end
  42.   end
  43.  
  44.   def disenchant_card(card)
  45.     @arcane_dust += DISENCHANTED_ARCANE_DUST[card.rarity]
  46.     @disenchanted += 1
  47.  
  48.     CRAFT_ARCANE_DUST.each do |rarity, craft_cost|
  49.       if @collection[rarity].size != TOTAL_CARDS[rarity]
  50.         craft_card(rarity) if craft_cost <= @arcane_dust
  51.         break
  52.       end
  53.     end
  54.   end
  55.  
  56.   def craft_card(rarity)
  57.     (1..TOTAL_CARDS[rarity]).each do |i|
  58.       unless @collection[rarity].any? { |card| card.number == i }
  59.         @arcane_dust -= CRAFT_ARCANE_DUST[rarity]
  60.         @collection[rarity] << Card.new(rarity, i)
  61.         return
  62.       end
  63.     end
  64.   end
  65.  
  66.   def random_pack
  67.     pack = []
  68.     (1..5).each do |i|
  69.       pack << random_rarity_card(i == 5 && !pack.any? { |card| card.rarity != :common })
  70.     end
  71.     return pack
  72.   end
  73.  
  74.   def random_rarity_card(force_atleast_rare)
  75.     r = rand # get rarity
  76.     while r < RARITY_CHANCE[:rare]
  77.       r = rand
  78.     end if force_atleast_rare
  79.  
  80.     card = nil
  81.     RARITY_CHANCE.each do |rarity, chance|
  82.       if r < chance
  83.         card = Card.new(rarity, random_card_from_rarity(TOTAL_CARDS[rarity]))
  84.         break
  85.       end
  86.     end
  87.  
  88.     return card
  89.   end
  90.  
  91.   def random_card_from_rarity(max)
  92.     return (rand * (max - 1) + 1).round
  93.   end
  94.  
  95.   def is_collection_complete?
  96.     @collection.each do |rarity, list|
  97.       return false if list.size != TOTAL_CARDS[rarity]
  98.     end
  99.     return true
  100.   end
  101.  
  102.   def info
  103.     msg = ""
  104.     msg << "packs: #{@packs_open}, "
  105.     msg << "common: #{@collection[:common].size}, "
  106.     msg << "rare: #{@collection[:rare].size}, "
  107.     msg << "epic: #{@collection[:epic].size}, "
  108.     msg << "leg: #{@collection[:legendary].size}, "
  109.     msg << "dis: #{@disenchanted}, "
  110.     msg << "dust: #{@arcane_dust}"
  111.     msg << "."
  112.     return msg
  113.   end
  114. end
  115.  
  116. results = []
  117. (0..49).each do |i|
  118.   p = PackGenerator.new
  119.   results << p.check_packs_needed
  120.   puts "Packs needed: #{results[i]}."
  121. end
  122. puts "Average: #{results.inject{|sum,x| sum + x} / results.size}"
  123. puts "Max: #{results.max}"
  124. puts "Min: #{results.min}"
  125.  
  126. #Packs needed: 1167.
  127. #Packs needed: 1310.
  128. #Packs needed: 1598.
  129. #Packs needed: 1471.
  130. #Packs needed: 1178.
  131. #Packs needed: 1288.
  132. #Packs needed: 1434.
  133. #Packs needed: 1254.
  134. #Packs needed: 1141.
  135. #Packs needed: 1246.
  136. #Packs needed: 1394.
  137. #Packs needed: 1417.
  138. #Packs needed: 1200.
  139. #Packs needed: 1399.
  140. #Packs needed: 1224.
  141. #Packs needed: 1250.
  142. #Packs needed: 1489.
  143. #Packs needed: 1277.
  144. #Packs needed: 1512.
  145. #Packs needed: 1182.
  146. #Packs needed: 1383.
  147. #Packs needed: 1185.
  148. #Packs needed: 1386.
  149. #Packs needed: 1280.
  150. #Packs needed: 1288.
  151. #Packs needed: 1386.
  152. #Packs needed: 1484.
  153. #Packs needed: 1238.
  154. #Packs needed: 1378.
  155. #Packs needed: 1338.
  156. #Packs needed: 1332.
  157. #Packs needed: 1480.
  158. #Packs needed: 1404.
  159. #Packs needed: 1522.
  160. #Packs needed: 1446.
  161. #Packs needed: 1411.
  162. #Packs needed: 1412.
  163. #Packs needed: 1332.
  164. #Packs needed: 1289.
  165. #Packs needed: 1122.
  166. #Packs needed: 1228.
  167. #Packs needed: 1245.
  168. #Packs needed: 1407.
  169. #Packs needed: 1370.
  170. #Packs needed: 1342.
  171. #Packs needed: 1411.
  172. #Packs needed: 1211.
  173. #Packs needed: 1224.
  174. #Packs needed: 1305.
  175. #Packs needed: 1257.
  176. #Average: 1330
  177. #Max: 1598
  178. #Min: 1122