yY      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX .A probabilistic event with an outcome of type a . See the  function : to actually run the event and randomly pick an outcome. For an explanation of the Y' instance, see the DieRoll type in the Numeric.Probability.Game.Dice  module. The ZC instance compares the two distributions to see if they are equal. M This looks at all the outcomes and sees if their probabilities are equal on ; the left-hand side and the right-hand side. For example,  coinToss == fmap (>= 4) d6, but d12 / = d6 + d6. The [B instance will display a horizontal bar-chart of relative outcome M probability. Note: this really is a relative probability -- common factors N are cancelled, and is not a count of the different outcomes. If you wish to  show the raw numbers, use show . outcomes instead. The \C instance allows you to modify the outcome values without changing / their associated probabilities. For example,  fmap show d6 changes the outcomes $ into their String representations. The ]@ instance allows you to join together the results of two events * in a predetermined manner. For example, makeEvent [id, (* 2)] <*> d6 allows E you to roll a d6 that has a 50% chance of being doubled. Note that pure  67 is an event that is certain to produce the outcome 6. The ^A instance allows you to base the choice of the next event on the - result of the previous event. For example,  coinToss >>= x -> if x then d6  else d4C will roll a d4 50% of the time and a d6 the other 50%. Note that return  67 is an event that is certain to produce the outcome 6. _`aOGets a list of all the outcomes of the event and their associated probability. P You can be sure that the probabilities will all sum to 1, and that there will U only be one item in the list per outcome. It is possible that some of the outcomes * in the list will have zero probability. GMakes an event that has an equal chance of taking on the value of each K entry in the list. Note that duplicates in the list are permitted and do  have an effect: makeEvent [True, False]# has a 50% chance of giving a True  result, but *makeEvent [True, True, False, False, False] only has a 40% I chance of giving a True result. If you do not want this behaviour, use  makeEvent . nub to remove duplicates. 3The result of passing the empty list is undefined. CGiven a list of events and their associated probabilities, forms a G corresponding event. The probabilities must be non-negative. If the M probabilities do not sum to one, they are all scaled linearly so that their C sum is one. Duplicate items will have their probabilities added. PThe result of passing the empty list, a list containing negative probabilities, > or a list where all the probabilities are zero is undefined. MAn event with a 50% chance of giving True, and a 50% chance of giving False. VActually enacts the event and produces a single result according to the probabilities  in the EventM a parameter. If the EventM a: parameter returns a result equal to the first parameter, P it is changed to be the second parameter; otherwise it is left untouched. For  example replace 4 8 d45 has an equal chance of producing the outcomes 1, 2,  3 and 8, replace 10 0 d10 == z10, and replace 10 20 d6 == d6. RCompares the outcomes of the two events, and works out the probability associated M with the first outcome being greater than, equal to or less than the second I outcome. The probabilites for each are returned in an associative map. Added in version 1.1. QA type synonym for events with an integer outcome (i.e. all standard die rolls). The Y instance for  EventM Int* allows you to add the results of two die ' rolls, or subtract them (if it helps, (+) = liftA2 (+)). "Multiplication works as follows. d * e evaluates the first die roll, . then sums that many rolls of the second. So 2 * d6 rolls two d6 and adds 4 the outcomes. However, this definition means that d6 * 2 rolls one d6, / then effectively scales the result by 2. And d6 * d4 rolls one d6, then  rolls that number of d42, adding their results together. The simple rule K when one of the terms is a constant is: use the constant on the left-hand M side to get more dice, and use the constant on the right-hand side to scale  the result. 4A die with an equal chance of rolling 1, 2, 3 or 4. :A die with an equal chance of rolling 1, 2, 3, 4, 5 or 6. @A die with an equal chance of rolling 1, 2, 3, 4, 5, 6, 7 or 8. FA die with an equal chance of rolling 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9. GA die with an equal chance of rolling 1, 2, 3, 4, 5, 6, 7, 8, 9 or 10. 9A die with an equal chance of rolling 1 to 12 inclusive. 9A die with an equal chance of rolling 1 to 20 inclusive. :A die with an equal chance of rolling 1 to 100 inclusive. 9A die with an equal chance of rolling 0 to 99 inclusive. LMakes a die that has an equal chance of achieving the numbers 1 through the  number given. d 4; has an equal chance of producing the outcomes 1, 2, 3 and  4, d 1 is equivalent to return 1 (a certain result of 1), and  dR is undefined for any number below 1. For convenience, all the standard dice are  provided, e.g. d6 = d 6. HMakes a die that has an equal chance of achieving the numbers 0 through & the one less than the number given. z 4" has an equal chance of producing # the outcomes 0, 1, 2 and 3, while z 1 is equivalent to return 0 (a  certain result of 0), and z+ is undefined for any number below 1. For I convenience, several standard dice that can be interpreted with a lower  result of 0 are provided, e.g.  z10 = z 10. JRerolls the die when the specified outcome(s) occur. This has the effect O of removing the outcomes from the set of outcomes and rescaling all the other 3 probabilities linearly to sum to 1. For example:   d6 `rerollOn` [5,6] == d4 4 chancePred (== 12) ((2*d6) `rerollOn` [7]) == 1/30 >With the latter example, the standard chance of 12 on 2d6 is 1/ 36, which  is rescaled by 36/$30, the reciprocal of the chance of not hitting  a 7. A nice synonym for U: actually rolls the die and produces a single result according to the probabilities  in the EventM a parameter.     A collection/?deck of cards. The collection of cards has no implicit order, ; and each card is deemed to be equally likely to be drawn. So, for example,  makeCards ["a","a","a","b","c"] is a collection of cards  with a 3/5 chance of drawing an "a".  Note that in ! and all functions using it, the b instance is considered 8 to be authoritative. Imagine you have some type like:  F data MyCard = MyCard {cardType :: String, cardDescription :: String} 8 instance Ord MyCard where compare = comparing cardType BIf you then create a collection of cards, all those with the same cardType will , be considered the same, and differences in cardDescription will be collapsed. So,  for example you may find that:   cardsMap (makeCards [MyCard "Sword" "Long Sword", MyCard "Sword" "Legendary Sword of the Ancient King of Rak'Tharr", MyCard "Shield" "Buckler"]) P == fromList [(MyCard "Sword" "Long Sword", 2), (MyCard "Shield" Buckler", 1)] EThe two sword cards are indistinguishable from each other by the Ord I instance, so an arbitrary card for the two is kept in the collection to L represent them both -- the legendary sword is treated the same as the long K sword (so, equally, you might get two legendary swords in the deck and no  long sword). -If you want the difference to matter, use an b instance that recognises M the difference. If you want the difference to matter some of the time, and 0 not matter at other times, you may want to use  to either pick G out just the aspects you are interested in, or to use a default value E (e.g. empty description) for the aspects you are not interested in. The c& instance can be used to get an empty  object, and to add $ two collections of cards together. d0Gets a map from card to frequency for the given  item. eMakes a  item using a f( from card to frequency. Any card with + a frequency of 0 or less will be ignored. g+Gets a sorted list of cards. For example: c ["a","a","a","b","c","c"] == sortedCards (makeCardsMap (fromList [("c", 2), ("b", 1), ("a", 3)])) QRemoves the cards in the second parameter from the cards in the first parameter. M If the frequency of a card in the second parameter is greater than or equal M to the frequency of a card in the first parameter, all of them are removed. ) Negative frequencies are not possible.  Example: ~ makeCardsMap (fromList [("a", 3), ("b", 1), ("c", 2)]) `minusCards` (makeCards ["a","b","b","c"]) == makeCards ["a","a","c"] h'Applies a function to the cards. Like i for  , but we can't use  \ because of the b constraint. SIf this function maps two old cards to the same single new card, their frequencies G are added together, but otherwise the frequencies are left untouched. QThis function is particularly useful for narrowing the number of distinct cards;  see functions in the #Numeric.Probability.Game.Cards.Hand module.  Example:  mapCards (map toUpper) (makeCardsMap (fromList [("a", 2), ("A", 3), ("b", 2)])) == makeCardsMap (fromList [("A", 5), ("B", 2)]) MMakes a collection of cards from the given list. The order of the list does N not matter, but duplicates are important: if a card occurs multiple times in @ the list, it will appear multiple times in the collection. So  makeCards [a,b]  has one card named "a" and one named "b", but  makeCards [a,a,b,a]  has three cards named "a" and one named "b". KRemoves one of the given cards from the collection. This only reduces the Q frequency by one; it does not remove all of the given card from the collection. < If the card is not in the collection, this has no effect.  Example: L removeOneCard "a" (makeCards ["a","a","a","b"]) == makeCards ["a","a","b"] P removeOneCard "c" (makeCards ["a","a","a","b"]) == makeCards ["a","a","a","b"] ?Removes a given number of cards that match the given criteria. OAs the name suggests, the choice of cards removed is arbitrary. This function Q is mainly useful if you later want to check for the odds of finding a card that does Q match the given criteria, but first want to express that you know of many cards  that don't meet the criteria that aren't in the deck. EIf not enough cards meet the criteria in the collection, all that don't $ meet the criteria will be removed. KAdds the given card and frequency to the collection of cards. If the card : is already in the collection, the frequencies are added.  Example: O addCard ("c", 2) (makeCards ["a","a","b"]) == makeCards ["a","a","b","c","c"] K addCard ("b", 1) (makeCards ["a","a","b"]) == makeCards ["a","a","b","b"] j JDraws one card from the given collection of cards at random. Returns the P card, and the collection of cards after the card has been drawn (i.e. with one N of that card removed). If the collection is empty, the result is undefined. NNote that using this function repeatedly to draw a hand of cards can be quite @ computationally intensive; for more efficient methods, see the #Numeric.Probability.Game.Cards.Hand  module.  Example:  outcomes (drawOne (makeCards ["a","a","a","b"])) == [(("a", makeCards ["a","a","b"]), 3 % 4), (("b", makeCards ["a","a","a"]), 1 % 4)] !HDraws the given number of cards from the given deck of cards at random, L without replacement. Returns the collection of cards that were drawn (the I first part of the result pait), and the corresponding remaining deck of K cards. If the deck is empty or does not contain enough cards to draw the , specified number, the result is undefined. CNote that using this function to draw a hand of cards can be quite @ computationally intensive; for more efficient methods, see the #Numeric.Probability.Game.Cards.Hand  module.  Note that makeCards n cards == swap <$>& makeCards (cardCount cards - n) cards; Q this method will be much more efficient with a smaller number as parameter than  a larger number.  Example: B outcomes (drawNoReplace 2 (makeCards ["a","a","a","a", "b"])) == v [((makeCards ["a","a"], makeCards ["a","a", "b"]), 3 % 5), ((makeCards ["a","b"], makeCards ["a,"a","a"]), 2 % 5)] "LDraws the given number of cards from the given collection with replacement. O Returns the collection of cards that will be drawn (and thus you can be sure  that:  cardsCount <$> drawReplace n cards will be n , provided cards is not N empty). If the given collection of cards is empty, the result is undefined. CNote that using this function to draw a hand of cards can be quite @ computationally intensive; for more efficient methods, see the #Numeric.Probability.Game.Cards.Hand  module.  Example: ; outcomes (drawReplace 2 (makeCards ["a","a","a","b"])) == ` [(makeCards ["a","a"], 9 % 16), (makeCards ["a","b"], 3 % 8), (makeCards ["b","b"], 1 % 16)] #MCounts the number of cards (i.e. the sum of the frequencies of each distinct  card) in the collection. -cardCount cards == length (sortedCards count) >If you want the number of distinct cards in a collection, use size . cardsMap.  !"## "! !"#$LA playing card with a rank and suit. The ordering on them is arbitrary (by  rank then by suit). %&'(MThe standard four suits of playing cards. The ordering on them is arbitrary  (alphabetical, in fact). )*+,-A wrapper for 08 where the Ord, Enum and Bounded instances are adjusted 9 to list Ace as the lowest item rather than the highest. ./0JThe rank of playing cards. The ranking is specified ace-high, as this is N how many games operate. If you wish to have an ace-low ordering you can use  the - newtype. 123456789:;<=>,The standard full deck of 52 playing cards. ?,Checks if the two cards have the same suit. @,Checks if the two cards have the same rank. $%&'()*+,-./0123456789:;<=>?@$%&'(,+*)0=<;:987654321-./>?@$%&'%&'(,+*))*+,-././0 =<;:987654321123456789:;<=>?@A&A monad for describing drawing cards. NThe first parameter is the type of the card (this must match the deck you end N up drawing from), the second parameter is the monadic return type as normal. 7Each action in the monad is the drawing of a card, see C and similar functions. " There is the notion of failure: L& makes the current draw fail, as does  E5 if no cards satisfy the criteria, and attempting to C when ) there are no more cards will also fail. The k? instance allows you to choose between two sequences of draws.  If the LHS of '(<|>)'. fails, the right-hand side is used instead. l  is the same as L. mnopBLTries to perform the two draws interleaved with each other in any sequence, 6 favouring those where the left-hand side acts first. As an example:  T interleave (replicateM 2 (drawWhere (== "a"))) (replicateM 3 (drawWhere (== "b"))) will attempt to draw two "a" cards and three "b"% cards, in any order and return them O as a pair. If you want to draw identical groupings like this where the exact ' values of the cards can vary, look at J. C$Draws a single card and returns it. =If you are not interested in the value of the returned card, D is much J more efficient. If you want to constrain which card might be drawn, use E. DLDraws any card from the deck. In cases where you are not interested in what / the card is, this is much more efficient than C. EJDraws a single card that matches the given criteria (i.e. where the given & function returns True for the card).  For example:   drawWhere (/= "c") will draw any card that is not "c". Note that: 3 (draw >>= ensure f) == (drawWhere f >> return ()) FRDraws the given number of cards and then counts how many meet the given criteria.  The definition is:  9 drawCount f n = length . filter f <$> replicateM n draw Note that this is definitely NOT the same as replicateM n (drawWhere f).  The  drawWhereD code makes sure that it draws n cards that meet the given criteria O (and fails in other cases), whereas this function draws the given number then O checks how many meet the criteria. Therefore this function will only fail if 1 there are insufficient cards to draw that many. GKDraws cards until it draws a card that satisfies the given condition or it Q hits the optional limit of cards. If the limit is zero, the function will fail L every time, 1 will only draw a single card, 2 will draw up to 2 and so on. OAll the cards drawn will be returned in order, therefore you can be guaranteed S that the last card in the list (and only that card) satisfies the given function. H9Draws the given number of identical cards from the deck. 8This corresponds to drawing one card from the deck with C and then using E P to make sure the rest of the cards match. The card that was drawn is returned Q (since all of them are identical, only a single example is returned rather than  a list). IODraws the given number of identical (by the given aspect) cards from the deck. 8This corresponds to drawing one card from the deck with C and then using E M with the given mapping function to make sure the rest of the cards match on < the aspect specified. The card that was drawn is returned Q (since all of them are identical, only a single example is returned rather than 8 a list). The order of the returned list is arbitrary.  For example:   drawSameOn (map toLower) 5 Lwill draw 5 cards (where the card type is simply String) that have matching S names when compared case-insensitive. The return list you get might be something  like ["a","A","A","a","a"]. JZDraws cards in groups of identical cards (but in any order) according to the given sizes. ,This function is best explained by example:   drawGroups [2]( will draw two identical cards, much as  drawSame 2 does.  drawGroups [2,1]9 will draw two identical cards, and a third card that is 8 guaranteed not to be equal to the two identical cards.  drawGroups [2,2]; will draw two different lots of two identical cards (i.e. ' it cannot return 4 of the same card). JIt is perhaps helpful to think of this function in terms of poker hands.  drawGroups  [4,1]' looks for 4-of-a-kind in a hand of 5, drawGroups [3,2] looks for a  full house, drawGroups [2,2,1] looks for two-pair, while drawGroups [2,1,1,1]  looks for exactly one pair. NThe order of groups requested corresponds to the returns. Thus, for example, . this code should never fail a pattern match:  . do [[a1,a2], [b1,b2,b3]] <- drawGroups [2,3] NThe groups have no correspondence to the order in which the cards were drawn. O So although the groups above and returned together, those 5 cards could have ' been drawn in any order, for example: [b2, a1, b3, b2, a2]. This function is intended < for cases when you want particular identical groups but don't mind about the L order. That is surprisingly fiddly to write without this helper function. qKLike J;, but considers them equal if their given aspect is equal. L9Indicates that the current draw should not be continued. MMChecks that the given property holds, otherwise fails the current draw. Its  definition is simple: - ensure b = if b then return () else badHand rNKCalculates the chance of the given draw succeeding (i.e. not failing) with S the given deck. Note that the return value of the draw is ignored; this function 2 is only interested in whether the draw succeeds. PNote that if you are only interested in partial aspects of the cards (e.g. just ' the rank in a deck of playing cards), O is much more efficient. See  O for more details.  Examples:  chance deck (return ()) == 1 B chance (makeCards ["a", "a", "b"]) (drawWhere (== "a")) == 2 % 3 : chance (makeCards ["a", "a", "b"]) (drawSame 2) == 1 % 3 OKCalculates the chance of the given draw succeeding (i.e. not failing) with S the given deck. Note that the return value of the draw is ignored; this function 2 is only interested in whether the draw succeeds. NThe given function is used to transform the cards for drawing. This can make O the function much more efficient if the transform maps several cards onto the 9 same aspect. Consider if you wanted the probability of < drawing two aces from a deck of playing cards. If you use N , it will Y check all 52 distinct cards in the deck separately to see if they are aces when you are  drawing. However if you use  chanceOn rank!, it can collapse the 52 playing N cards into 13 distinct cards (one per rank) with frequency 4, and only check M each of the 13 cards separately. Since this saving is made across repeated  draws, using O rather than N can reduce queries from taking U many seconds into being instant. This also applies to all the other chance..On and 1 event..On variants of functions in this module.  Examples: % chanceOn id deck m == chance deck m \ chanceOn (map toLower) (makeCards ["a", "a", "A", "A", "b"]) (drawWhere (== "a")) == 4 % 5 P8Turns the successful outcomes of the given draw into an  type, which will return d the different values of the successful draw with their corresponding relative probabilities. Note P that only successful draws are included; a failed draw will have a probability @ of zero. To incorporate the possibility of a failed draw, use R  instead. As with other functions, Q! can be much more efficient; see O  for details.  For example:  O outcomes (eventDraw (makeCards ["a","b"]) (drawWhere (== "a"))) == [("a", 1)] D outcomes (eventDraw (makeCards ["a","a","a","b","b"]) (drawSame 2) # == [("a", 3 % 5), ("b", 2 % 5)] QLike P& but can be much more efficient. See O for an  explanation of why. R-Turns the outcomes of the given draw into an  type, which will return V the different values of the draw with their corresponding probabilities. Successful M draws are the Just values; Nothing indicates an unsuccessful draw, with its  corresponding probability. As with other functions, S! can be much more efficient; see O  for details.  For example:  j outcomes (eventDraw (makeCards ["a","b"]) (drawWhere (== "a"))) == [(Just "a", 1 % 2), (Nothing, 1 % 2)]  D outcomes (eventDraw (makeCards ["a","a","a","b","b"]) (drawSame 2) @ == [(Just "a", 3 % 10), (Just "b", 1 % 5), (Nothing, 1 % 2)] 8 eventDrawMaybe cards m == eventDraw cards (optional m) SLike R& but can be much more efficient. See O for an  explanation of why. TLike U& but can be much more efficient. See O for an  explanation of why. UKCalculates the probability of each result of the given draw with the given N deck. The probabilities will exclude the chance of a failed draw; therefore  the chance of a failed draw is 1 - sum (elems $ chanceMap ..). Alternatively Q you can incorporate the possibility of a failed draw with a Maybe wrapper using  chanceMap cards (optional m).  Examples:  P chanceMap (makeCards ["a","b"]) (drawWhere (== "a"))) == singleton "a" (1 % 2) D outcomes (eventDraw (makeCards ["a","a","a","b","b"]) (drawSame 2) - == fromList [("a", 3 % 10), ("b", 1 % 5)] sABCDEFGHIJKLMNOPQRSTUAMLBCDEGFHIJKNOUTPQRSABCDEFGHIJKLMNOPQRSTUVMGets the probability that the outcome will satisfy the given predicate. For  example: J chancePred (<= 2) d6 == 1/3 -- The chance of getting 2 or less on a d6 P chancePred even d6 == 1/2 -- The chance of rolling an event number on a d6 WOGets the probability that the given relation will hold between the two events.  For example: F chanceRel (==) d6 d6 == 1/6 -- The chance of rolling doubles on d6 J chanceRel (>) (2*d6) d12 -- The chance of beating a d12 with two d6 XKGets the probability that the given boolean-outcome event will give a True  outcome. For example:   chanceTrue coinToss == 1/2 # chanceTrue ((== 3) <$> d6) == 1/6 (For the latter example, V is more concise.) VWXVWXVWXt      !"#$%&'()*++,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a_bc_de_fg_hi_fjkl_bm_nopqrstu_fvw_hx_hyz{|}~game-probability-1.1Numeric.Probability.Game.EventNumeric.Probability.Game.DiceNumeric.Probability.Game.Cards%Numeric.Probability.Game.PlayingCards#Numeric.Probability.Game.Cards.HandNumeric.Probability.Game.QueryEventMoutcomes makeEvent makeEventProbcoinTossenactsubst compareEventDieRolld4d6d8z10d10d12d20d100z100dzrerollOnrollCardscardsMap makeCardsMap sortedCards minusCardsmapCards makeCards removeOneCardremoveArbitraryaddCarddrawOne drawNoReplace drawReplace cardCount PlayingCardranksuitSuitSpadesHeartsDiamondsClubs AceLowRankAceLowalRankRankAceKingQueenJackTenNineEightSevenSixFiveFourThreeTwodecksameSuitsameRankDrawM interleavedrawdrawAny drawWhere drawCount drawUntildrawSame drawSameOn drawGroups drawGroupsOnbadHandensurechancechanceOn eventDraw eventDrawOneventDrawMaybeeventDrawMaybeOn chanceMapOn chanceMap chancePred chanceRel chanceTruebaseGHC.NumNum GHC.ClassesEqGHC.ShowShowGHC.BaseFunctorControl.Applicative ApplicativeMonad normEventMshowBarsOrd Data.MonoidMonoidcacheCardsSizecontainers-0.3.0.0Data.MapMap makeCardsMap' maybeMinusfmapmakeList AlternativeemptyDrawAnyDoneDrawOneDrawFailpickchance' chanceMap'