I'm trying to build a probability calculator for a trading card game (I'll abstract any examples so they're not dependent on knowing anything about the game itself) that can accept a variety of user input based on the cards in the deck and calculate the probability of drawing said cards in a certain number of draws.

For instance, lets say the deck contains the following cards:

10 F

4 T

4 A

4 P

4 R

34 X

...for a total of 60 cards.

I'd like my calculator to be able to handle user inputs of the following format:

[Exactly/At Least/At Most] [#] [Selected Card] or [Selected Card] or... in [#] draws

So the user might select:

[Exactly] [1] [F] in [7] draws

This is one of the cases that I know how to calculate. I could use the hypergeometric distribution formula for this:

HYPGEOMDIST (1, 7, 10, 60) = 0.4114556

Or I could just count:

C(10, 1) * C(50, 6) / C(60, 7) = 0.4114556

Another user input example might be:

[Exactly] [2] [F or T]

[Exactly] [1] [A or P]

[Exactly] [1] [R]

in [7] draws

This took some research to reaffirm, and I think I'm understanding how to solve it correctly. I find counting easier in this case:

C((F + T), 2) * C((A + P), 1) * C(R, 1) * C(34, 3) / C(60, 7)

C(14, 2) * C(8, 1) * C(4, 1) * C(34, 3) / C(60, 7) = 0.0451194

You might have noticed that I've only been using “Exactly” cases, even though my goal is to include “At Least” and “At Most” options. This is because incorporating them into these calculations is where I'm currently confused. For instance, consider the following user input:

[Exactly] [2] [F or T]

[At Least] [1] [A or P]

[At Most] [1] [R]

in [7] draws

Most of the examples I've been able to find don't deal with anything this specific. They're typically of the “at least two aces” or “at least one heart” variety. The few I have found that compound exactly/at least/at most in one calculation are solved through methods that are not very friendly to a computer programmer, requiring deductions specific to the exact problem at hand.

How could I go about solving that last case in a way that might translate more easily to a computer program (e.g. I can't care about using, or even prefer to use, large loops that no one would want to do by hand)?

Thanks