JSFiddle - React, Tailwind, and code Playground
by cyphern
HTML
<div class="explanation">This is a monte carlo simulation of whether milling cards affects your chance to draw good cards. Two versions are simulated: in one, you draw a fixed number of cards, and see how many good cards were drawn. In the other, some number of cards are milled, and then the fixed number of cards are drawn and again the good cards are counted. The results are then compared.
<br/><br/>
I threw this together in like 15 minutes, so don't expect it to be robust. If you enter gibberish, that's on your head.</div>
<br/>
<div># of Total Cards</div><input id="numTotalCards" value="60"></input>
<div># of Good Cards</div><input id="numGoodCards" value="4"></input>
<div># of cards drawn over the course of the game</div><input id="numCardsDrawn" value="20"></input>
<div># of cards milled</div><input id="numCardsMilled" value="30"></input>
<div># of iterations to simulate</div><input id="iterations" value="10000"></input>
<br/>
<button onclick="execute()">Go!</button>
<div id="output1"></div>
<div id="output2"></div>
JavaScript
var createDeck = function (cardCount, goodCardCount) {
var deck = [];
var i;
for (i = 0; i < goodCardCount; i++) {
deck.push("g");
}
for (i = 0; i < (cardCount - goodCardCount); i++) {
deck.push("b");
}
return deck;
}
var fisherYatesShuffle = function (deck) {
var length = deck.length;
for (var i = length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
swap(deck, i, j);
}
return deck;
}
var swap = function (array, indexA, indexB) {
var temp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = temp;
}
var countGoodCards = function (deck, startIndex, endIndex) {
var count = 0;
for (var i = startIndex; i <= endIndex; i++) {
if (deck[i] == "g") {
count++;
}
}
return count;
}
var createReport = function (resultArray, maxGoodCards, iterations) {
var newResults = [];
var i;
for (i = 0; i <= maxGoodCards; i++) {
newResults[i] = 0;
}
for (i = 0; i < resultArray.length; i++) {
newResults[resultArray[i]]++;
}
var msg = "";
for (i = 0; i < newResults.length; i++) {
msg += i + " good cards: " + newResults[i] + " times ( " + ((newResults[i] / iterations) * 100) + "%)<br/>";
}
return msg;
}
execute = function () {
var totalCards = parseInt($("#numTotalCards").val());
var goodCards = parseInt($("#numGoodCards").val());
var cardsToDraw = parseInt($("#numCardsDrawn").val());
var cardsToMill = parseInt($("#numCardsMilled").val());
var iterations = parseInt($("#iterations").val());
var resultsWithoutMill = [];
var resultsWithMill = [];
var deck;
// Simulate without mill
var i;
for (i=0; i < iterations; i++) {
deck = createDeck(totalCards, goodCards);
deck = fisherYatesShuffle(deck);
resultsWithoutMill.push(countGoodCards(deck, 0, cardsToDraw - 1));
...