Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- format compact
- rng('shuffle')
- % HEARTHSTONE PACK OPENING SIMULATOR
- % Opens packs until every plain card is collected
- % Set number of trials to run (increases accuracy and run time)
- n = 10000;
- % Pick the set to be run (1 = classic
- set = 1; % 2 = goblins vs gnomes
- % 3 = the grand tournament
- % 4 = whispers of the old gods
- % 5 = mean streets of gadgetzan)
- % Optional: input the current state of the collection
- % From the chosen set:
- % Number of commons where one is owned
- userC = 0;
- % Number of commons where two are owned
- userC2 = 0;
- % Number of rares where one is owned
- userR = 0;
- % Number of rares where two are owned
- userR2 = 0;
- % Number of epics where one is owned
- userE = 0;
- % Number of epics where two are owned
- userE2 = 0;
- % Number of legendaries owned
- userL = 1;
- % Current dust total
- userD = 0;
- % DON'T EDIT ANYTHING BELOW HERE
- % Store the size of each set
- % Rows are different sets, columns are different rarities
- setSize = [94 81 37 33;
- 40 37 26 20;
- 49 36 27 20;
- 50 36 27 21;
- 49 36 27 20];
- % Store the probability of each rarity occuring for each individual card
- % Rows are plain/golden, columns are common/rare/epic/legendary
- % Accurate to within ~1% based on HearthSim pack data
- rarity = [0.8809558 00.0185221 0.0770890 0.0045338 0.0146196 0.0006866 0.0033284 0.0002646];
- % Manipulate the array based on various pity timers
- legendaryDist = [0 rarity(7)/sum(rarity(7:8)) 1];
- epicDist = [0 rarity(5)/sum(rarity(5:8)) sum(rarity(5:6))/sum(rarity(5:8)) sum(rarity(5:7))/sum(rarity(5:8)) 1];
- rareDist = [0 rarity(3)/sum(rarity(3:8)) sum(rarity(3:4))/sum(rarity(3:8)) sum(rarity(3:5))/sum(rarity(3:8)) sum(rarity(3:6))/sum(rarity(3:8)) sum(rarity(3:7))/sum(rarity(3:8)) 1];
- commonDist = [0 rarity(1) sum(rarity(1:2)) sum(rarity(1:3)) sum(rarity(1:4)) sum(rarity(1:5)) sum(rarity(1:6)) sum(rarity(1:7)) 1];
- % Set an array to store how many packs each trial runs
- packsOpened = zeros(1,n);
- % Run the trial 'n' times
- for a = 1:n
- % Generate a collection
- %common = repmat(2,1,setSize(set,1));
- common = [zeros(1,userC2) ones(1,userC) repmat(2,1,(setSize(set,1)-(userC2+userC)))];
- rare = [zeros(1,userR2) ones(1,userR) repmat(2,1,(setSize(set,2)-(userR2+userR)))];
- epic = [zeros(1,userE2) ones(1,userE) repmat(2,1,(setSize(set,3)-(userE2+userE)))];
- legendary = [zeros(1,userL) ones(1,setSize(set,4)-userL)];
- % Set the dust count, pack count, and pity timers to zero
- dust = userD;
- pityEpic = 0;
- pityLegendary = 0;
- % Keep opening packs until either the collection is complete OR enough
- % dust is left over to craft the remaining
- while (sum(common)+sum(rare)+sum(epic)+sum(legendary) > 0) && (40*sum(common) + 100*sum(rare) + 400*sum(epic) + 1600*sum(legendary) > dust)
- % Open a pack
- packsOpened(a) = packsOpened(a) + 1;
- % Randomly give each card a 'rarity number', then translate it
- % 1 = Common, 2 = GCommon, 3 = Rare, 4 = GRare
- % 5 = Epic, 6 = GEpic, 7 = Legendary, 8 = GLegendary
- cardRand = rand(1,5);
- cardRarity = zeros(1,5);
- % The 'first' card has adjusted rarity, based on pity timer
- if pityLegendary >= 40
- for b = 1:2
- if cardRand(1) >= legendaryDist(b) && cardRand(1) <= legendaryDist(b+1)
- cardRarity(1) = b+6;
- end
- end
- elseif pityEpic >= 10
- for b = 1:4
- if cardRand(1) >= epicDist(b) && cardRand(1) <= epicDist(b+1)
- cardRarity(1) = b+4;
- end
- end
- else
- for b = 1:6
- if cardRand(1) >= rareDist(b) && cardRand(1) <= rareDist(b+1)
- cardRarity(1) = b+2;
- end
- end
- end
- % Generate the other four cards
- for c = 2:5
- for b = 1:8
- if cardRand(c) >= commonDist(b) && cardRand(c) <= commonDist(b+1)
- cardRarity(c) = b;
- end
- end
- end
- % Increase pity timers by one if none were opened
- if cardRarity(1) < 5 && cardRarity(2) < 5 && cardRarity(3) < 5 && cardRarity(4) < 5 && cardRarity(5) < 5
- pityEpic = pityEpic + 1;
- else
- pityEpic = 0;
- end
- if cardRarity(1) < 7 && cardRarity(2) < 7 && cardRarity(3) < 7 && cardRarity(4) < 7 && cardRarity(5) < 7
- pityLegendary = pityLegendary + 1;
- else
- pityLegendary = 0;
- end
- % For each card, dust the golden cards, add the plains to the
- % collection if needed, or dust them if already owned
- for c = 1:5
- if cardRarity(c) == 1
- draw = randi(setSize(set,1),1,1);
- if common(draw) > 0
- common(draw) = common(draw) - 1;
- else
- dust = dust + 5;
- end
- elseif cardRarity(c) == 2
- dust = dust + 50;
- elseif cardRarity(c) == 3
- draw = randi(setSize(set,2),1,1);
- if rare(draw) > 0
- rare(draw) = rare(draw) - 1;
- else
- dust = dust + 20;
- end
- elseif cardRarity(c) == 4
- dust = dust + 100;
- elseif cardRarity(c) == 5
- draw = randi(setSize(set,3),1,1);
- if epic(draw) > 0
- epic(draw) = epic(draw) - 1;
- else
- dust = dust + 100;
- end
- elseif cardRarity(c) == 6
- dust = dust + 400;
- elseif cardRarity(c) == 7
- draw = randi(setSize(set,4),1,1);
- if legendary(draw) > 0
- legendary(draw) = legendary(draw) - 1;
- else
- dust = dust + 400;
- end
- else
- dust = dust + 1600;
- end
- end
- end
- end
- maxPacks = max(packsOpened);
- avgPacks = ceil(mean(packsOpened));
- minPacks = min(packsOpened);
- stdPacks = std(packsOpened);
- intervallower = ceil(avgPacks - 1.96 * stdPacks / sqrt(n));
- intervalupper= ceil(avgPacks + 1.96 * stdPacks / sqrt(n));
- minPacks
- intervallower
- avgPacks
- intervalupper
- maxPacks
Advertisement
Add Comment
Please, Sign In to add comment