TOTAL_CARDS = { :common => 100, :rare => 70, :epic => 50, :legendary => 30 } RARITY_CHANCE = { :legendary => 0.005, :epic => 0.025, :rare => 0.1, :common => 1 } DISENCHANTED_ARCANE_DUST = { :common => 2, :rare => 10, :epic => 100, :legendary => 400 } CRAFT_ARCANE_DUST = { :legendary => 1600, :epic => 400, :rare => 100, :common => 10 } CARDS_PER_PACK = 5 class Card attr_accessor :rarity, :number def initialize(rarity, number) @rarity = rarity @number = number end end class PackGenerator def initialize @collection = { :common => [], :rare => [], :epic => [], :legendary => [] } @arcane_dust = 0 @packs_open = 0 @disenchanted = 0 end def check_packs_needed while !is_collection_complete? add_collection(random_pack) @packs_open += 1 #puts info end return @packs_open end def add_collection(pack) pack.each do |card| unless @collection[card.rarity].any? { |c| c.number == card.number } @collection[card.rarity] << card else disenchant_card(card) end end end def disenchant_card(card) @arcane_dust += DISENCHANTED_ARCANE_DUST[card.rarity] @disenchanted += 1 CRAFT_ARCANE_DUST.each do |rarity, craft_cost| if @collection[rarity].size != TOTAL_CARDS[rarity] craft_card(rarity) if craft_cost <= @arcane_dust break end end end def craft_card(rarity) (1..TOTAL_CARDS[rarity]).each do |i| unless @collection[rarity].any? { |card| card.number == i } @arcane_dust -= CRAFT_ARCANE_DUST[rarity] @collection[rarity] << Card.new(rarity, i) return end end end def random_pack pack = [] (1..5).each do |i| pack << random_rarity_card(i == 5 && !pack.any? { |card| card.rarity != :common }) end return pack end def random_rarity_card(force_atleast_rare) r = rand # get rarity while r < RARITY_CHANCE[:rare] r = rand end if force_atleast_rare card = nil RARITY_CHANCE.each do |rarity, chance| if r < chance card = Card.new(rarity, random_card_from_rarity(TOTAL_CARDS[rarity])) break end end return card end def random_card_from_rarity(max) return (rand * (max - 1) + 1).round end def is_collection_complete? @collection.each do |rarity, list| return false if list.size != TOTAL_CARDS[rarity] end return true end def info msg = "" msg << "packs: #{@packs_open}, " msg << "common: #{@collection[:common].size}, " msg << "rare: #{@collection[:rare].size}, " msg << "epic: #{@collection[:epic].size}, " msg << "leg: #{@collection[:legendary].size}, " msg << "dis: #{@disenchanted}, " msg << "dust: #{@arcane_dust}" msg << "." return msg end end results = [] (0..49).each do |i| p = PackGenerator.new results << p.check_packs_needed puts "Packs needed: #{results[i]}." end puts "Average: #{results.inject{|sum,x| sum + x} / results.size}" puts "Max: #{results.max}" puts "Min: #{results.min}" #Packs needed: 1167. #Packs needed: 1310. #Packs needed: 1598. #Packs needed: 1471. #Packs needed: 1178. #Packs needed: 1288. #Packs needed: 1434. #Packs needed: 1254. #Packs needed: 1141. #Packs needed: 1246. #Packs needed: 1394. #Packs needed: 1417. #Packs needed: 1200. #Packs needed: 1399. #Packs needed: 1224. #Packs needed: 1250. #Packs needed: 1489. #Packs needed: 1277. #Packs needed: 1512. #Packs needed: 1182. #Packs needed: 1383. #Packs needed: 1185. #Packs needed: 1386. #Packs needed: 1280. #Packs needed: 1288. #Packs needed: 1386. #Packs needed: 1484. #Packs needed: 1238. #Packs needed: 1378. #Packs needed: 1338. #Packs needed: 1332. #Packs needed: 1480. #Packs needed: 1404. #Packs needed: 1522. #Packs needed: 1446. #Packs needed: 1411. #Packs needed: 1412. #Packs needed: 1332. #Packs needed: 1289. #Packs needed: 1122. #Packs needed: 1228. #Packs needed: 1245. #Packs needed: 1407. #Packs needed: 1370. #Packs needed: 1342. #Packs needed: 1411. #Packs needed: 1211. #Packs needed: 1224. #Packs needed: 1305. #Packs needed: 1257. #Average: 1330 #Max: 1598 #Min: 1122