In this answer, I consider the question that I believe the asker is most interested in: given optimal mulligan decisions, what is the probability of drawing at least one Bazaar in time to play one on your first turn? This answer accounts for all reasonable mulligan decisions, including scrying, and for the chance of drawing one in your first draw step on the play. This is in accord with the asker's own answer, but not necessarily with the explicit algorithm that was later added to the question.
(This answer does not address questions like whether you should exile important cards other than Bazaar using Serum Powder. It also assumes that the opponent does not interfere with your first draw.)
When you draw a hand, there are four parameters to consider:
- The number of cards in your library (excluding those exiled by Serum Powder).
- The number of Serum Powders left in your library.
- The number of cards you're drawing.
- Whether you're on the draw (and have a chance of drawing on your first turn).
When you draw a hand, if you hit a Bazaar, you're done. Otherwise, you have up to three choices:
- Keep the hand and hope to draw Bazaar on your first turn. If your current hand size is less than seven, you get to look at two cards; otherwise, you only see one.
- Mulligan and try again with a smaller hand size (unless you're already at zero).
- Exile your hand and try again with the same hand size (only if you've drawn at least one Serum Powder).
Rather than work this out analytically, I wrote a Python script to brute-force it (with a little memoization):
#!/usr/bin/python3
from functools import lru_cache
from scipy.stats import hypergeom
INITIAL_LIBRARY_SIZE = 60
INITIAL_HAND_SIZE = 7
COPIES_OF_BAZAAR = 4
COPIES_OF_SERUM = 4
@lru_cache(None)
def prob(library_size, serums_in_library, hand_size, on_the_draw=False):
# Probability of drawing at least one Bazaar
prob_bazaar = 1 - hypergeom.pmf(0, library_size, COPIES_OF_BAZAAR, hand_size)
if hand_size > 0:
# Probability of success on a mulligan
prob_if_mulligan = prob(library_size, serums_in_library, hand_size-1, on_the_draw)
else:
prob_if_mulligan = 0
if on_the_draw:
# Probability of drawing Bazaar on the first draw step given that we haven't drawn a Bazaar yet.
# Accounts for seeing an extra card as a result of the Vancouver mulligan.
prob_if_keep = 1 - hypergeom.pmf(0, library_size-hand_size, COPIES_OF_BAZAAR, 2 if hand_size < INITIAL_HAND_SIZE else 1)
else:
prob_if_keep = 0
# Split into cases depending on the number of Serum Powders drawn.
prob_if_no_bazaar = sum(
# Probability of drawing exactly `serums_drawn` copies of Serum Powder.
hypergeom.pmf(serums_drawn, library_size-COPIES_OF_BAZAAR, serums_in_library, hand_size)
# Choose the strategy with the best chance of success
* max(
# Mulligan, recycling drawn cards.
prob_if_mulligan,
# Use Serum Powder. Exile all cards in hand, which may include more than one Serum Powder.
# If we draw no Serum Powders, ignore this strategy.
prob(library_size-hand_size, serums_in_library-serums_drawn, hand_size, on_the_draw) if serums_drawn else 0,
# Keep the hand and hope to draw on the first turn.
prob_if_keep
)
# For each possible number of Serum Powders drawn
for serums_drawn in range(0, 1 + min(serums_in_library, hand_size))
)
return prob_bazaar + (1 - prob_bazaar) * prob_if_no_bazaar
print(
prob(INITIAL_LIBRARY_SIZE, COPIES_OF_SERUM, INITIAL_HAND_SIZE, False),
prob(INITIAL_LIBRARY_SIZE, COPIES_OF_SERUM, INITIAL_HAND_SIZE, True),
)
The results I got were:
- 94.17% if you're on the play.
- 95.03% if you're on the draw.
These numbers are significantly lower than t.rathjen's. I double-checked the first figure by running a few million simulations, and it seems correct. I suspect that t.rathjen's simulations may have a small bug. If I've made a mistake in the script, I hope that someone will point it out. I haven't tried it out yet with high-precision arithmetic.
I played around with the script to see if you should ever do a regular mulligan if you draw Serum Powder, and the answer seems to be no. Even if you draw all of your Serum Powders at once, it's better to exile all of them for a single free mulligan than keep going with a smaller hand size but Serum Powders in the deck. That is, the algorithm described in the question does seem to be optimal: you should always use Serum Powder when possible and always mulligan down to one card (but not zero) or until you find a Bazaar.