const fs = require('fs');

// Coronet Combo
const deckArray = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 
                   11, 12, 12, 13, 13, 14, 14, 15, 15, 16];

// Full duplicates
//const deckArray = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 
//                   11, 11, 12, 12, 13, 13, 14, 14, 15, 15];

// Full singles
//const deckArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
//                  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];

var decklist;
var hand = [];
const targetIDs = [1, 2]; // [1] if looking for 1 card §##§ [1, 2] if looking for 2 cards
const mulliganSwaps = 3; // Going first: 3 §##§ Going second: 4
let totalTrials = [10, 20, 30, 50, 75, 100, 200, 400, 800, 1500, 3000, 6000, 10000, 
                    25000, 50000, 75000, 100000, 200000, 500000, 1000000];

//let totalTrials = [1];

const SimpleDraw = () => {
    const randomIndex = Math.floor(Math.random() * decklist.length);
    const drawnCard = decklist[randomIndex];
  
    // Remove the card from the deck
    decklist.splice(randomIndex, 1);
    
    // And add the card to the hand
    hand.push(drawnCard);

    return drawnCard;
}

const MulliganSwap = () => {
    const randomIndex = Math.floor(Math.random() * decklist.length);
    const drawnCard = decklist[randomIndex];
  
    // Remove all occurrences of the drawn card
    decklist = decklist.filter(card => card !== drawnCard);
    
    // Update the hand
    hand[0] = drawnCard;

    return drawnCard;
}

const CheckPick = (cardID) => {
    if (targetIDs.includes(cardID)) {
        //console.log(`\x1b[32mTarget card found: ${cardID}\x1b[0m`);
        return true;
    }
}

const DrawOneGame = (arr) => {
    decklist = [...arr]; // Create a shallow copy

    //console.log("\x1b[1mNew game start\x1b[0m");
    //console.log(`Original deck:  ${deckArray}`);
    //console.log(`Starting deck:  ${decklist}`);

    for (let i = 0; i < 3; i++) {
        const pickedCard = SimpleDraw();
        //console.log(`Mulligan Card #${i+1}: ${pickedCard}`);
        //console.log(`Remaining deck: ${decklist}`);
        if (CheckPick(pickedCard)) {
            return true;
        }
      }
    
    for (let j = 0; j < mulliganSwaps; j++) {
        const pickedCard2 = MulliganSwap();
        //console.log(`Mulligan Swap #${j+1}: ${pickedCard2}`);
        //console.log(`Remaining deck: ${decklist}`);
        if (CheckPick(pickedCard2)) {
            return true;
        }
    }
    
    // Before drawing the 4th card, reset the card list without the restrictions of the mulligan
    //console.log(`Decklist before mulligan:  ${decklist}`);
    //console.log(`Hand after mulligan:  ${hand}`);
    decklist = arr.filter(card => card !== hand);
    //console.log(`Decklist after mulligan:  ${decklist}`);

    const firstDraw = SimpleDraw();

    // Reset hand array for next iteration
    hand = [];

    //console.log(`First Draw: ${firstDraw}`);
    //console.log(`Remaining deck: ${decklist}`);
    if (CheckPick(firstDraw)) {
        return true;
    }

    //console.log("\x1b[31mTarget card not found\x1b[0m");
    return false;
}

// START HERE
console.log(`Original array  ${deckArray}`);
console.log("Array size:", deckArray.length);

// Clear the .csv results file and write the header
var dataCSV = "";
const pathCSV = './mulligan_results.csv';
const eventLabels = "Iteration,Total_Trials,Card_Found,Percentage\n";

fs.writeFile(pathCSV, eventLabels, (error) => {
  if (error) throw error;
});

// Main loop
totalTrials.forEach(value => {

    for (let k = 0; k < 30; k++) { // k < 30

        let foundCard = 0;

        for (let l = 0; l < value; l++) {

            if (DrawOneGame(deckArray)) {
                foundCard++;
            }
        }

        const percent = (foundCard / value * 100).toFixed(2);

        dataCSV += `${k+1},${value},${foundCard},${percent}\n`;

        console.log("Target card found:", foundCard, "times");
        console.log("Total Trials:", value);
        console.log("Chance of finding target card(s):", percent, "%");
    }
})

console.log(`Original array  ${deckArray}`);
console.log("Array size:", deckArray.length);

// Save data to file
fs.appendFile(pathCSV, dataCSV, (error) => {
  if (error) throw error;
});


 
by

NodeJS Online Compiler

Write, Run & Share NodeJS code online using OneCompiler's NodeJS online compiler for free. It's one of the robust, feature-rich online compilers for NodeJS language,running on the latest LTS version NodeJS 16.14.2. Getting started with the OneCompiler's NodeJS editor is easy and fast. The editor shows sample boilerplate code when you choose language as NodeJS and start coding. You can provide the dependencies in package.json.

About NodeJS

Node.js is a free and open-source server environment. Node.js is very popular in recent times and a large number of companies like Microsoft, Paypal, Uber, Yahoo, General Electric and many others are using Node.js.

Key features

  • Built on Google chrome's javascript engine V8 and is pretty fast.
  • Node.js was developed by Ryan Dahl in 2009.
  • Server-side platform for building fast and scalable applications.
  • Node.js is Asynchronous, event-driven and works on single-thread model thus eliminating the dis-advantages of multi-thread model.
  • Supports various platforms like Windows, Linux, MacOS etc.
  • Provides rich library of java script modules which simplifies the development efforts.
  • Released under MIT license.

Express Framework

Express is one of the most popular web application framework in the NodeJS echosystem.

  • Pretty fast
  • Minimalist
  • Unopinionated
  • Very flexible

Syntax help

Examples

Using Moment

let moment = require('moment');

console.log(moment().format('MMMM Do YYYY, h:mm:ss a'));

Using Lodash

const _ = require("lodash");

let colors = ['blue', 'green', 'yellow', 'red'];

let firstElement = _.first(colors);
let lastElement = _.last(colors);

console.log(`First element: ${firstElement}`);
console.log(`Last element: ${lastElement}`);

Libraries supported

Following are the libraries supported by OneCompiler's NodeJS compiler.

  • lodash
  • moment
  • underscore
  • uuid
  • ejs
  • md5
  • url