Monday, February 12, 2024

Import your decklist

You can now use Deck-u-lator settings to import your decklist.  This can be a faster way to setup your calculation than entering cards one at a time.  Settings are accessible by clicking the gear icon at the top right of the screen.


Deck-u-lator recognizes any line that begins with a number and a space as a card in your deck.  Blank lines and lines that do not begin with a number and a space are ignored.  

WARNING: If there are multiple lines with the same card name, their counts are combined.  This means that if your decklist includes a sideboard, those cards and counts will be included.  If you do not want this, then delete the sideboard lines, or adjust the counts appropriately.


Saturday, February 10, 2024

Better support for longer calculations

With the latest upgrade, Deck-u-lator can calulate combinations including many more hands.  Mark had been trying to calculate larger combinations than could be finished within the Google App Engine limit of 60 seconds.  Now these longer calculations will show a progress bar with the amount of work that has been completed.


This required re-factoring the Deck-u-lator engine to return partial results and to continue a partial calculation.  The new engine is five times faster.

From the image above, you can also see that these changes are highlighted by switching to dark mode.

Saturday, January 20, 2024

New math formula for multiple hand combinations

The latest version of Deck-u-lator shows new math formulas for advanced calculations with two or three hands.  Previously multi-hand calculations simply confirmed how many alternate hand combinations you were calculating.  This is still the case for combinations with four or more hands.

To calculate your chances to draw alternate hands, Deck-u-lator performs the multivariate hypergeometric calculation for each hand and adds those probabilities together.  What about draws that contain all the cards needed for two different hands?  These get double counted by just summing probabilities for both hands.  So we calculate the probabilities for all combinations of two hands and subtract those.  This process continues, alternately adding probabilities for combinations of three hands, subtracting probabilities for combinations of four hands and so on.

The new formula gives a glimpse into this process.  Enjoy!

$$ \frac{ H_{0} + H_{1} - H_{0} \cap H_{1} }{ \binom{ 52 }{ 2 } } = 95.0\% $$

Monday, November 20, 2023

Deck-u-lator logo

 The logo for Deck-u-lator is the percent sign in a mana cost circle.  Deck-u-lator calculates the probability of drawing a card combination as a percentage.  Mana cost circles on cards in Magic: The Gathering show the casting cost for that spell.

The percent sign is rendered in the Planewalker font.  Neale Davidson of Pixel Sagas designed this calligraphic-style font face based on the card text from the first several editions of Wizards of the Coast's Magic: The Gathering collectable card game. 



Sunday, November 5, 2023

2023 Upgrade to Python3 and Flask

Deck-u-lator has been upgraded to the latest Python environment on Google App Engine.  Google is ending support for Python 2.7, so moving to Python 3 was necessary to continue operating on this platform.  Deck-u-lator now uses the Flask micro web application framework.

The functionality from the Advanced page is now added to the main page with a button that will toggle between basic and advanced.  

Behind the scenes, the Javascript code has been simplified now that most modern browsers support XMLHttpRequest and JSON.  You may see error messages if you are using an older browser.

Thank you to those of you who have shared questions and feature requests.  

Tuesday, July 5, 2022

Mulligans and Probability (redrawing hands)

Some card games (including MTG) include rules for a mulligan that permit the option to redraw your hand in hopes of getting better cards.  The more times you draw a hand, the more likely it is that you will eventually draw a hand that has your desired card combination.  Can we quantify this?

The probability of two independent events occurring is the product of the separate probability of the two events.  By replacing the initial draw and reshuffling before drawing again we make these two draws independent events.  

Probability when redrawing hands

Instead of looking at the probability to draw your combination in the first hand or the redraw, we will look at the probability to not draw your combination twice in a row.

  • Assume the probability to draw a hand with your desired card combination is P
  • That means that the probability of not drawing your combination is 1-P
  • The chance of not drawing your combination after one mulligan is (1-P) * (1-P) = (1-P)^2
  • The probability of drawing your combination with one mulligan is 1-( (1-P)^2 )
We can generalize this.  If you are willing to draw N times (initial draw plus N-1 mulligan redraws) then your probability to get your combination is 1-( (1-P)^N ).

If we are trying to draw a 2-card combination in a 60 card deck where we have 4 of each, our chance after drawing 7 cards is P=14.5%.  Being willing to mulligan twice (N=3) increases our chance to 37.5%

1-( (1-P)^N ) 

= 1-( (1-0.145)^3 )

= 1-( 0.855^3 )

= 1-( 0.625 )

= 0.375

Combination by turn 4 after two redraws

What are the chances to draw that same two card combination by turn 4 if we are willing to redraw twice? 

We use the same trick as before, but draw 7+4 cards after the last redraw.  With four extra cards, the chance to draw our 2-card combination after drawing 11 cards is 30.7%.  By being willing to mulligan twice and wait until turn 4, our chance to draw our combination increases to 49.3%

1-[ (1-0.145) * (1-0.145) * (1-0.307) ]

= 1-[ 0.855 * 0.855 * 0.693]

= 1-[ 0.507 ]

= 0.493


Friday, May 17, 2019

How to use the Deck-u-lator API

If you want to add a multivariate hypergeometric distribution calculator to your program, consider using the Deck-u-lator API.  This has been available since 2010 when it was introduced on this blog.

You can see an example of calling this using JavaScript over at Observable.