Probability of Specific Cards

handsWithAs = {$A*s};
handsWithAs.Count() / AllHands.Count();
Output: 0.25
{$A*s} creates a set of hands that contain the A♠ and any number of additional spades. Dividing the number of hands in {A*s} by the total number of possible hands gives the chance that any given hand is contained within {A*s}. This means that 25% of all hands contain A♠.

Probability of Suit Length

handsMinFiveSpades = {xxxxx*s};
handsMinFiveSpades.Count() / AllHands.Count();
Output: 0.17634
{xxxxx*s} creates a set of hands that contain at least 5 spades This shows that ~17.6% of all hands contain at least five spades.

Probability with Known Hands

myhand = [93c QT8d KQT9h AQ43s];
westHands = AllHands.RemoveCards(myhand);
westHands.Intersect({$K*s}).Count() / westHands.Count();
Output: 0.33333
Another player cannot have hands that contains cards that you own. Given that you don't have the K♠, another player has a 33% chance of having it

Probability Given Bid

StandardBid0.Intersect({$A*s}).Count() / StandardBid0.Count() Output: 0
StandardBid3.Intersect({$A*s}).Count() / StandardBid3.Count() Output: 0.26685
StandardBid6.Intersect({$A*s}).Count() / StandardBid6.Count() Output: 0.58608
The StandardBids are HandSets that contain all the hands that will result in a given bid. This is of course an estimate. See the documentation for the assumptions made to produce these bids. The above examples shows the probability a player has the A♠ for various bids.

Probability of Multiple Hands

myhand = {63c AK8532d 862h 74s};
min2Diamonds = {xx*d};
DealSet(myhand, min2Diamonds, min2Diamonds, AllHands).Count() / DealSet(myhand, AllHands, AllHands, AllHands).Count();
Output: 0.54244
If you want to calculate probabilities that are dependent on the hands of multiple players use a DealSet. A DealSet contains four HandSets representing the hands of each player in a deal. The above example shows the probability (~54%) that both of your opponents have at least two diamaonds and that you will be able to safely play A♦ and K♦ without your opponents being able to trump.

CardSet

To create a CardSet fill in the cards in between square brackets '[' and ']'. Suits and ranks can be entered in any order.
[AKQ98c 93d K4h AQJ3s] Output: AKQ98c 93d K4h AQJ3s
[Ac Kc Qc 9c 8c 9d 3d AQJ3s 4Kh] Output: AKQ98c 93d K4h AQJ3s

CardSet.Complement(): CardSet

Returns the set of all cards not contained in this CardSet
[AKQ98c 93d K4h AQJ3s].Complement() Output: JT765432c AKQJT876542d AQJT9876532h KT9876542s

CardSet.Count(): Int

Returns the number of cards in this CardSet
[AJTs].Count() Output: 3

CardSet.Edit()

Opens the hand editor with the cards in this cardset placed in South's hand.
[AKQ43c J7d 3h AJT32s].Edit()

CardSet.Intersect(other: CardSet): CardSet

Returns the set intersection of this and other CardSet. In other words it returns all cards that exist in both sets.
[AKQ98c 93d K4h AQJ3s].Intersect([Ac Ad Ah As]) Output: Ac As

CardSet.Subtract(other: CardSet): CardSet

Returns the set subtraction of this and other CardSet. In other words it returns all cards that exist in this set that don't exist in the other set.
[AKQ98c 93d K4h AQJ3s].Subtract([Ac Ad Ah As]) Output: KQ98c 93d K4h QJ3s

CardSet.Union(other: CardSet): CardSet

Returns the set union of this and other CardSet. In other words it returns all cards that exist in either set.
[AKQ98c 93d K4h AQJ3s].Union([Ac Ad Ah As]) Output: AKQ98c A93d AK4h AQJ3s

Deal(hand1: CardSet, hand2: CardSet, hand3: CardSet, hand4: CardSet): Deal

Creates a deal from four hands. This function will produce an error if hands do not encompass all 52 cards or if any hand does not contain 13 cards
Deal([KQ8c AJ98d AJ97h Q7s], [765c KQ2d 8653h JT8s], [T432c T54d T4h A954s], [AJ9c 763d KQ2h K632s]) Output:
KQ8c AJ98d AJ97h Q7s
765c KQ2d 8653h JT8s
T432c T54d T4h A954s
AJ9c 763d KQ2h K632s

Deal.Edit()

Opens the hand editor with the cards distributed according to this deal
myHand = [AKQ43c J7d 3h AJT32s];
westHands = StandardBid3;
DealSet(myHand, westHands).RandomDeal().Edit();

DealSet(hand1: HandSet, hand2: HandSet, hand3: HandSet, hand4: HandSet): DealSet

Creates a deal from four hands. If fewer than four hands are given then the DealSet uses AllHands for the missing hands. A CardSet may be used in place of a HandSet to represent a hand if the CardSet contains exactly 13 cards.
myhand = [63c AK8532d 862h 74s];
min2Diamonds = {xx*d};
DealSet(myhand, min2Diamonds, min2Diamonds).Count() / DealSet(myhand).Count();
Output: 0.54244
The above example shows the probability (~54%) that both of your opponents have at least two diamaonds and there you will be able to safely play A♦ and K♦ without your opponents being able to trump.

DealSet.Complement(): HandSet

Returns the set of all deals that are not contained in this DealSet
hand1 = { Axx*s !Ad xx*!AKQh };
hand2 = { K*d (JTxx|JTxxx)c };
hand3 = { (Axx*|Kxx*)d !Qs };
dealSet = DealSet(hand1, hand2, hand3, AllHands);
dealSetComplement = dealSet.Complement();
AllDeals.Count() - (dealSet.Count() + dealSetComplement.Count());
Output: 0
As expected, a set of deals and its complement contain all possible deals between them.

DealSet.Contains(deal: Deal): Boolean

Returns true if deal is contained in this DealSet
dealSet = DealSet(StandardBid3);
dealSet.Contains(dealSet.RandomDeal());
Output: True

DealSet.Count(): Int

Returns the number of deals in this DealSet
AllDeals.Count() Output: 53644737765488792839237440000
The total number of ways 52 cards can be distributed among all four players is this large number.

DealSet.Intersect(other: DealSet): DealSet

Returns the set intersection of this and other DealSet. In other words it returns all deals that exist in both sets.
settingDeals = DealSet({Jxxxc AQ*h}, {xxxx*c xx*h})
.Union(DealSet({Jxxxc AJ*h}, {xxxx*c xx*!Qh}))
.Union(DealSet({AQ*h Kx*s}, {xx*h}))
.Union(DealSet({AJ*h Kx*s}, {xx*!Qh}))
.Union(DealSet({Jxxxc A*h Kx*s}, {xxxx*c x*h}))
.Union(DealSet({xxc A*h Kxx*s}, {xxx*c x*h}))
.Union(DealSet({xxxc A*h Kxx*s}, {xxxx*c x*h}))
.Union(DealSet({xc AQ*h x*s}, {xx*c xx*h}))
.Union(DealSet({xc AJ*h x*s}, {xx*c xx*!Qh}))
.Union(DealSet({xxc AQ*h x*s}, {xxx*c xx*h}))
.Union(DealSet({xxc AJ*h x*s}, {xxx*c xx*!Qh}))
.Union(DealSet({xxxc AQ*h x*s}, {xxxx*c xx*h}))
.Union(DealSet({xxxc AJ*h x*s}, {xxxx*c xx*!Qh}));

myhand = [89QKAc 4Kh 38TJQAs]; possibleDeals = DealSet(StandardBid2, StandardBid3, myhand);
settingDeals = possibleDeals.Intersect(settingDeals);
settingDeals.Count() / possibleDeals.Count();
Output: 0.06058
In the above example we create a DealSet that contains all the deals where we might get set if the hands of two other players are just right. Then set intersection is used to constrain the deals to the ones that match the bidding we have seen and our hand.

DealSet.RandomDeal(): Deal

Returns a random deal contained in this set.
DealSet({AQ*c}, {Kx*c}, {Qxxd}, AllHands).RandomDeal() Output:
AQ962c A942d 643h 4s
K3c KT6d AQT72h AJ6s
J8754c Q75d 8h 8732s
Tc J83d KJ95h KQT95s

DealSet.Subtract(other: DealSet): DealSet

Returns the set subtraction of this and other DealSet. In other words it returns all deals that exist in this set that don't exist in the other set.
deal1 = DealSet({(AQ*|AKx)s}, {JTxxc}, AllHands, AllHands);
deal2 = DealSet({AQ3xs AQ*d}, AllHands, {KJx!T98h}, AllHands);
deal1.Subtract(deal2).Count() - (deal1.Count() - deal1.Intersect(deal2).Count());
Output: 0
This is a demonstration of the set difference formula

DealSet.Union(other: DealSet): DealSet

Returns the set union of this and other DealSet. In other words it returns all deals that exist in either set.
handSet = {xxxxx*s xxxxx*c}
.Union({xxxxx*s xxxxx*d})
.Union({xxxxx*s xxxxx*h});
handSet.Count() / AllHands.Count();
Output: Output: 0.02808
handSet contains all the hands with at least 5 spades and at least 5 cards of a side suit.

AllCards: CardSet

The set containing all 52 cards in a deck.
AllCards.Count() Output: 52

AllDeals: DealSet

The set containing possible ways a deck a cards can be distributed among four players.
AllDeals.Count() Output: 53644737765488792839237440000

AllHands: HandSet

The set containing all possible 13 card starting hands.
AllHands.Count() Output: 635013559600

EmptyCardSet: CardSet

The set containing zero cards.
EmptyCardSet.Count() Output: 0

EmptyDealSet: DealSet

The set containing zero deals.
EmptyDealSet.Count() Output: 0

EmptyHandSet: HandSet

The set containing zero hands.
EmptyHandSet.Count() Output: 0

nCr(n: Int, r: Int): Int

Returns the numer of ways you can choose r elements from a set of n elements.
AllHands.Count() - nCr(52, 13) Output: 0

Pow(base: Real, exponent: Real): Real

Calcualtes base ^ exponent
Pow(2, 10) Output: 1024

StandardBid0: HandSet, StandardBid1: HandSet, ..., StandardBid12: HandSet, StandardBid13: HandSet

These HandSets are useful for approximating how a player's bid changes the distribution of hands a player can have when playing Spades. Every possible hand is contained in exactly one of these HandSets. The StandardBids assigns bids to hands using the following rules:
  • +1 trick for each Ace of any suit.
  • +1 trick for each King of any suit with at least two cards.
  • +1 trick for the Qs if the spade suit has at least three cards.
  • +1 trick for each additional spade after the first three spade cards.
  • +1 trick for having exactly three spades(but not Qxxs) and having a singleton or void side suit
  • -1 trick for having zero spades or only one spade unless it is the As
  • If the resulting bid is zero, bump it up to one if there is a singleton Ace or King
This is not a perfect way of guessing a player's hand based on their bid but it is generally better than assuming a player's holdings are completely random.
myhand = [93c QT8d KQT9h AQ43s];
westHands = AllHands.RemoveCards(myhand);
westHands.Intersect({$K*s}).Count() / westHands.Count();
Output: 0.33333
myhand = [93c QT8d KQT9h AQ43s];
westHands = StandardBid5.RemoveCards(myhand);
westHands.Intersect({$K*s}).Count() / westHands.Count();
Output: 0.81358
In the above example we are trying to find out what is the chance our right hand opponent holds the Ks. The answer would be 33% if we don't take into account his bid of 5(!). If we assume that rho must have one of the hands in the StandardBid5 HandSet rho actually has ~81% chance of holding the Ks which is certainly more accurate for any reasonable opponent.

HandSet

To create a CardSet fill in the cards in between brackets '{' and '}'. Suits and ranks can be entered in any order.
hands = {*c *d *h *s};
hands.Count() / AllHands.Count();
Output: 1
The above example creates a HandSet that contains all hands with an arbitrary number of clubs, diamonds, hearts, and spades. This set therefore contains 100% of all possible hands
hands = {*c *d *h A*s };
hands.Count() / AllHands.Count();
Output: 0.25
In this example hands contains all hands with the As and any number of spades less the Ace as well as any number of clubs, diamnods, and hearts. In other words all hands that contain the As which consists of 25% of all possible hands.
hands = {A*s};
hands.Count() / AllHands.Count();
Output: 0.25
There is no need to explicitly define suits with no constraints. This is identical to the previous example.
hands = {Axx*s};
hands.Count() / AllHands.Count();
Output: 0.21217
This how you define a suit with the As and and least two additional lower spades.
hands = {Axxs};
hands.Count() / AllHands.Count();
Output: 0.06608
This how you define a suit with the As and and exactly two additional lower spades.
hands = {Kxxs};
hands.Count() / AllHands.Count();
Output: 0.05506
All additional cards of a suit will be lower than the lowest explicitly named rank. So in the above example, no hands with the As belong to the defined HandSet.
hands = {Kxx!QJs};
hands.Count() / AllHands.Count();
Output: 0.03604
You can forbid additional cards from a suit. In the above example, hands contains all hands with Ks and two additonal spades that are not the As, Qs or Js.
NoSpades = {0s};
NoSpades.Count() / AllHands.Count();
Output: 0.01279
In the above example, the HandSet contains all the possible hands that are void in the spade suit.
MaxTwoSpades = {(0|x|xx)s};
MaxTwoSpades.Count() / AllHands.Count();
Output: 0.29873
In the above example, the HandSet contains all the possible hands that have 0, 1, or 2 spades. In other words ~30% of the time a player will be dealt fewer than 3 spades.
MaxTwoSpades = {0..xxs};
MaxTwoSpades.Count() / AllHands.Count();
Output: 0.29873
Alternatively you may define a range of suit lengths.
atLeastOneAce = {A*c | A*d | A*h | A*s};
atLeastOneAce.Count() / AllHands.Count();
Output: 0.69618
You can define multiple subsets when creating a HandSet. In the above example, atLeastOneAce contains all the possible hands that have Ac, Ad, Ah, or As. This shows that ~70% of the time a player will be dealt at least one Ace.
handsContainingKs = {$K*s};
handsContainingKs.Count() / AllHands.Count();
Output: 0.25
Normally defining a suit with K* would indicate that it does not contain the Ace. If you start a subset with '$' then the calculator will include all ranks that are not explicitly removed.

HandSet.Complement(): HandSet

Returns the set of all Hands that are not contained in this HandSet
atLeastOneAceOrKing = {!AKc !AKd !AKh !AKs}.Complement();
atLeastOneAceOrKing.Count() / AllHands.Count();
Output: 0.91825
The hands that contain at least one Ace or King are the hands do not lack all Aces and Kings.

HandSet.Contains(Hand: Hand): Boolean

Returns true if Hand is contained in this HandSet
superHands = {Axxxx*s Axxxx*c | Axxxx*s Axxxx*d | Axxxx*s Axxxx*h};
myhand = [AQ432c 32d Qh A9543s]; superHands.Contains(myhand);
Output: True

HandSet.Count(): Int

Returns the number of Hands in this HandSet
AllHands.Count() Output: 635013559600
The total number of ways a player can be dealt 13 cards

HandSet.Intersect(other: HandSet): HandSet

Returns the set intersection of this and other HandSet. In other words it returns all Hands that exist in both sets.
{xxxxc}.Intersect({AQx*c}) Output: AQxxc

HandSet.RandomHand(): CardSet

Returns a random Hand contained in this set.
StandardBid3.RandomHand() Output: KJT62c A93d 84h A52s
You can use RandomHand to get a feel for what types of hands are in the standard bids.

HandSet.RemoveCards(cards: CardSet): HandSet

Returns the set with all the hands that contain cards removed. This is often useful for removing the cards in your hand from the HandSet representing other players.
myhand = [93c QT8d KQT9h AQ43s];
westHands = AllHands.RemoveCards(myhand);
westHands.Intersect({$K*s}).Count() / westHands.Count();
Output: 0.33333
Each other player has a 1/3 chance of a particular card if we don't have it ourselves.

HandSet.Subtract(other: HandSet): HandSet

Returns the set subtraction of this and other HandSet. In other words it returns all Hands that exist in this set that don't exist in the other set.
{AQ*c}.Subtract({(xxx|xxxx)c}) Output:
AQc
AQxxx*c

HandSet.Union(other: HandSet): HandSet

Returns the set union of this and other HandSet. In other words it returns all Hands that exist in either set.
subset1 = {AJx*h};
subset2 = {xxxxs};
subset1.Union(subset2).Count() - (subset1.Count() + subset2.Count() - subset1.Intersect(subset2).Count());
Output: 0
This is a demonstration of the set union formula