Wordman/WyldMagicMath

From Exalted - Unofficial Wiki
Revision as of 09:06, 3 April 2010 by Conversion script (talk) (link fix)
Jump to: navigation, search

This page contains more nerdy detail of the math used to select the point totals needed for various circles of sorcery in the /WyldMagic system.

The points needed for each circle were determined using the average number of points per card drawn. For the first draw of the deck, this is computed as follows:

|| Card || Number In Deck || Points Per Card || Points Possible in Whole Deck || || Ace || 4 || 1 || 4 || || Two || 4 || 2 || 8 || || Three || 4 || 3 || 12 || || Four || 4 || 4 || 16 || || Five || 4 || 5 || 20 || || Six || 4 || 6 || 24 || || Seven || 4 || 7 || 28 || || Eight || 4 || 8 || 32 || || Nine || 4 || 9 || 36 || || Ten || 4 || 10 || 40 || || Jack || 4 || 0 || 0 || || Queen || 4 || 0 || 0 || || King || 4 || 0 || 0 || || Joker || 2 || 0 || 0 || || Total || 54 || || 220 || |||||||| Average points per card: 4.074 ||

Even though the math changes as cards are removed from the deck, we'll stick with basic assumption that four points will be generated per card drawn. So based on this, figure out costs for each circle:

  • A minimally competent terrestrial sorcerer has Essence 3 and Occult 3.
  • Doing nothing but channeling, he can choose three cards per action.
  • Three cards would provide a bit more than 12 points.
  • Under canon exalted, a terrestrial spell needs two rounds to cast (one for channeling, one for casting).
  • Two rounds his of channeling would provide 24 points on average, from six cards.
  • To make the average terrestrial spell take two rounds to cast, the point value would need to be greater than 12 but less than 24.
  • Consider the following to figure out where in that range to set the limit:
    • On average, only a quarter of the cards will be diamonds. Very roughly, this would mean 6 diamond points.
    • Presumably, the average case would contain some lower average of, say, spade points, because spade face cards would more often be used to cancel spade points than diamond face cards would be used to cancel diamonds (which should basically never happen).
    • The maximum of one round of this sorcerer's channeling would be 30 points.
    • What percentage of three card hands generate more than 12 points?
    • What percentage of three cards generate more than 12 diamond points?
    • What percentage of three card hands generate more than 12 points when non-diamond face cards cancel the highest card they can?

Three Cards

http://rpg.divnull.com/exalted/images/wyldcard3.png

|| || Total || Face Negated || Diamonds || Total % || Face Negated % || Diamonds % || || 0 Points || 1,368 || 7,308 || 76,488 || 0.94% || 5.04% || 52.70% || || 1 Points || 1,896 || 3,408 || 5,604 || 1.31% || 2.35% || 3.86% || || 2 Points || 2,400 || 3,696 || 5,604 || 1.65% || 2.55% || 3.86% || || 3 Points || 3,264 || 4,290 || 5,868 || 2.25% || 2.96% || 4.04% || || 4 Points || 3,888 || 4,698 || 5,868 || 2.68% || 3.24% || 4.04% || || 5 Points || 4,872 || 5,412 || 6,132 || 3.36% || 3.73% || 4.23% || || 6 Points || 5,640 || 5,964 || 6,138 || 3.89% || 4.11% || 4.23% || || 7 Points || 6,744 || 6,798 || 6,402 || 4.65% || 4.68% || 4.41% || || 8 Points || 7,632 || 7,470 || 6,408 || 5.26% || 5.15% || 4.42% || || 9 Points || 8,880 || 8,448 || 6,678 || 6.12% || 5.82% || 4.60% || || 10 Points || 9,888 || 9,240 || 6,684 || 6.81% || 6.37% || 4.61% || || 11 Points || 9,360 || 7,470 || 1,350 || 6.45% || 5.15% || 0.93% || || 12 Points || 9,168 || 7,494 || 1,098 || 6.32% || 5.16% || 0.76% || || 13 Points || 9,168 || 7,656 || 1,104 || 6.32% || 5.28% || 0.76% || || 14 Points || 8,712 || 7,416 || 846 || 6.00% || 5.11% || 0.58% || || 15 Points || 8,472 || 7,338 || 852 || 5.84% || 5.06% || 0.59% || || 16 Points || 7,752 || 6,834 || 588 || 5.34% || 4.71% || 0.41% || || 17 Points || 7,248 || 6,492 || 588 || 4.99% || 4.47% || 0.41% || || 18 Points || 6,288 || 5,748 || 324 || 4.33% || 3.96% || 0.22% || || 19 Points || 5,520 || 5,142 || 318 || 3.80% || 3.54% || 0.22% || || 20 Points || 4,296 || 4,134 || 48 || 2.96% || 2.85% || 0.03% || || 21 Points || 3,288 || 3,288 || 42 || 2.27% || 2.27% || 0.03% || || 22 Points || 2,640 || 2,640 || 30 || 1.82% || 1.82% || 0.02% || || 23 Points || 2,112 || 2,112 || 24 || 1.46% || 1.46% || 0.02% || || 24 Points || 1,608 || 1,608 || 18 || 1.11% || 1.11% || 0.01% || || 25 Points || 1,200 || 1,200 || 12 || 0.83% || 0.83% || 0.01% || || 26 Points || 816 || 816 || 6 || 0.56% || 0.56% || 0.00% || || 27 Points || 552 || 552 || 6 || 0.38% || 0.38% || 0.00% || || 28 Points || 288 || 288 || 0 || 0.20% || 0.20% || 0.00% || || 29 Points || 144 || 144 || 0 || 0.10% || 0.10% || 0.00% || || 30 Points || 24 || 24 || 0 || 0.02% || 0.02% || 0.00% || || Mode || 10 || 10 || 0 || || || || || Median || 12 || 11 || 1 || || || || || Mean || 12.424343 || 11.462502 || 3.106086 || || || || || Permutations || 145,128 || || || || || ||

Four Cards

http://rpg.divnull.com/exalted/images/wyldcard4.png

|| || Total || Face Negated || Diamonds || Total % || Face Negated % || Diamonds % || || 0 Points || 8,424 || 172,584 || 3,019,224 || 0.12% || 2.39% || 41.82% || || 1 Points || 21,888 || 91,656 || 305,952 || 0.30% || 1.27% || 4.24% || || 2 Points || 33,264 || 106,488 || 305,952 || 0.46% || 1.48% || 4.24% || || 3 Points || 53,568 || 134,784 || 328,368 || 0.74% || 1.87% || 4.55% || || 4 Points || 71,688 || 152,256 || 328,368 || 0.99% || 2.11% || 4.55% || || 5 Points || 99,072 || 183,312 || 350,784 || 1.37% || 2.54% || 4.86% || || 6 Points || 126,096 || 205,368 || 351,840 || 1.75% || 2.84% || 4.87% || || 7 Points || 161,664 || 240,288 || 374,256 || 2.24% || 3.33% || 5.18% || || 8 Points || 197,352 || 266,904 || 375,312 || 2.73% || 3.70% || 5.20% || || 9 Points || 243,264 || 307,632 || 398,784 || 3.37% || 4.26% || 5.52% || || 10 Points || 288,816 || 340,008 || 399,864 || 4.00% || 4.71% || 5.54% || || 11 Points || 322,944 || 318,624 || 117,384 || 4.47% || 4.41% || 1.63% || || 12 Points || 350,088 || 321,576 || 97,104 || 4.85% || 4.45% || 1.35% || || 13 Points || 379,008 || 334,728 || 98,184 || 5.25% || 4.64% || 1.36% || || 14 Points || 396,048 || 334,488 || 76,872 || 5.49% || 4.63% || 1.06% || || 15 Points || 414,528 || 343,680 || 77,952 || 5.74% || 4.76% || 1.08% || || 16 Points || 418,728 || 337,512 || 55,608 || 5.80% || 4.68% || 0.77% || || 17 Points || 422,400 || 338,592 || 55,632 || 5.85% || 4.69% || 0.77% || || 18 Points || 411,696 || 324,216 || 33,288 || 5.70% || 4.49% || 0.46% || || 19 Points || 397,824 || 314,448 || 32,256 || 5.51% || 4.36% || 0.45% || || 20 Points || 367,752 || 287,616 || 8,832 || 5.09% || 3.98% || 0.12% || || 21 Points || 334,272 || 264,720 || 7,776 || 4.63% || 3.67% || 0.11% || || 22 Points || 301,152 || 244,992 || 5,712 || 4.17% || 3.39% || 0.08% || || 23 Points || 268,416 || 223,488 || 4,608 || 3.72% || 3.10% || 0.06% || || 24 Points || 234,072 || 199,728 || 3,552 || 3.24% || 2.77% || 0.05% || || 25 Points || 200,832 || 175,128 || 2,448 || 2.78% || 2.43% || 0.03% || || 26 Points || 167,040 || 149,328 || 1,368 || 2.31% || 2.07% || 0.02% || || 27 Points || 137,280 || 125,400 || 1,296 || 1.90% || 1.74% || 0.02% || || 28 Points || 107,448 || 100,968 || 216 || 1.49% || 1.40% || 0.00% || || 29 Points || 82,944 || 79,704 || 144 || 1.15% || 1.10% || 0.00% || || 30 Points || 61,152 || 60,504 || 120 || 0.85% || 0.84% || 0.00% || || 31 Points || 45,312 || 45,312 || 72 || 0.63% || 0.63% || 0.00% || || 32 Points || 33,240 || 33,240 || 48 || 0.46% || 0.46% || 0.00% || || 33 Points || 23,424 || 23,424 || 24 || 0.32% || 0.32% || 0.00% || || 34 Points || 15,936 || 15,936 || 24 || 0.22% || 0.22% || 0.00% || || 35 Points || 9,984 || 9,984 || 0 || 0.14% || 0.14% || 0% || || 36 Points || 5,880 || 5,880 || 0 || 0.08% || 0.08% || 0% || || 37 Points || 3,072 || 3,072 || 0 || 0.04% || 0.04% || 0% || || 38 Points || 1,248 || 1,248 || 0 || 0.02% || 0.02% || 0% || || 39 Points || 384 || 384 || 0 || 0.01% || 0.01% || 0% || || 40 Points || 24 || 24 || 0 || 0.00% || 0.00% || 0% || || Mode || 17 || 15 || 0 || || || || || Median || 17 || 15 || 2 || || || || || Mean || 16.691567 || 14.92254 || 4.172892 || || || || || Permutations || 7,219,224 || || || || || ||

Five Cards

http://rpg.divnull.com/exalted/images/wyldcard5.png

|| || Total || Face Negated || Diamonds || Total % || Face Negated % || Diamonds % || || 0 Points || 32,400 || 3,596,400 || 114,827,520 || 0.01% || 1.03% || 32.88% || || 1 Points || 168,480 || 2,721,600 || 15,096,120 || 0.05% || 0.78% || 4.32% || || 2 Points || 332,640 || 3,137,400 || 15,096,120 || 0.10% || 0.90% || 4.32% || || 3 Points || 644,160 || 4,019,160 || 16,625,880 || 0.18% || 1.15% || 4.76% || || 4 Points || 999,600 || 4,628,400 || 16,625,880 || 0.29% || 1.33% || 4.76% || || 5 Points || 1,525,920 || 5,690,400 || 18,155,640 || 0.44% || 1.63% || 5.20% || || 6 Points || 2,168,160 || 6,560,520 || 18,267,720 || 0.62% || 1.88% || 5.23% || || 7 Points || 2,989,440 || 7,819,200 || 19,797,480 || 0.86% || 2.24% || 5.67% || || 8 Points || 3,964,560 || 8,903,400 || 19,909,560 || 1.14% || 2.55% || 5.70% || || 9 Points || 5,187,840 || 10,436,640 || 21,551,400 || 1.49% || 2.99% || 6.17% || || 10 Points || 6,594,240 || 11,768,520 || 21,668,760 || 1.89% || 3.37% || 6.20% || || 11 Points || 8,110,080 || 11,966,760 || 8,214,480 || 2.32% || 3.43% || 2.35% || || 12 Points || 9,623,280 || 12,636,480 || 6,914,160 || 2.76% || 3.62% || 1.98% || || 13 Points || 11,213,280 || 13,521,240 || 7,031,520 || 3.21% || 3.87% || 2.01% || || 14 Points || 12,714,720 || 13,951,320 || 5,624,400 || 3.64% || 4.00% || 1.61% || || 15 Points || 14,233,920 || 14,628,120 || 5,741,880 || 4.08% || 4.19% || 1.64% || || 16 Points || 15,563,280 || 14,798,640 || 4,227,960 || 4.46% || 4.24% || 1.21% || || 17 Points || 16,780,320 || 15,157,080 || 4,233,360 || 4.81% || 4.34% || 1.21% || || 18 Points || 17,740,800 || 15,050,520 || 2,719,560 || 5.08% || 4.31% || 0.78% || || 19 Points || 18,448,320 || 15,023,640 || 2,613,000 || 5.28% || 4.30% || 0.75% || || 20 Points || 18,754,800 || 14,478,000 || 981,960 || 5.37% || 4.15% || 0.28% || || 21 Points || 18,704,640 || 13,995,840 || 870,120 || 5.36% || 4.01% || 0.25% || || 22 Points || 18,378,720 || 13,476,600 || 656,760 || 5.26% || 3.86% || 0.19% || || 23 Points || 17,782,080 || 12,926,400 || 534,480 || 5.09% || 3.70% || 0.15% || || 24 Points || 16,955,760 || 12,271,800 || 422,640 || 4.86% || 3.51% || 0.12% || || 25 Points || 15,907,200 || 11,541,840 || 300,240 || 4.56% || 3.31% || 0.09% || || 26 Points || 14,665,440 || 10,696,440 || 183,000 || 4.20% || 3.06% || 0.05% || || 27 Points || 13,315,680 || 9,849,960 || 167,280 || 3.81% || 2.82% || 0.05% || || 28 Points || 11,845,200 || 8,876,280 || 49,920 || 3.39% || 2.54% || 0.01% || || 29 Points || 10,351,200 || 7,930,920 || 33,960 || 2.96% || 2.27% || 0.01% || || 30 Points || 8,881,440 || 6,968,760 || 28,560 || 2.54% || 2.00% || 0.01% || || 31 Points || 7,505,280 || 6,062,400 || 17,760 || 2.15% || 1.74% || 0.01% || || 32 Points || 6,261,840 || 5,200,200 || 12,240 || 1.79% || 1.49% || 0.00% || || 33 Points || 5,115,360 || 4,362,600 || 6,600 || 1.46% || 1.25% || 0.00% || || 34 Points || 4,115,040 || 3,602,040 || 6,360 || 1.18% || 1.03% || 0.00% || || 35 Points || 3,216,480 || 2,890,320 || 840 || 0.92% || 0.83% || 0.00% || || 36 Points || 2,469,840 || 2,276,520 || 600 || 0.71% || 0.65% || 0.00% || || 37 Points || 1,844,640 || 1,742,040 || 360 || 0.53% || 0.50% || 0.00% || || 38 Points || 1,341,600 || 1,298,400 || 240 || 0.38% || 0.37% || 0.00% || || 39 Points || 953,280 || 939,240 || 120 || 0.27% || 0.27% || 0.00% || || 40 Points || 665,520 || 664,440 || 120 || 0.19% || 0.19% || 0.00% || || 41 Points || 452,640 || 452,640 || 0 || 0.13% || 0.13% || 0% || || 42 Points || 299,040 || 299,040 || 0 || 0.09% || 0.09% || 0% || || 43 Points || 186,240 || 186,240 || 0 || 0.05% || 0.05% || 0% || || 44 Points || 110,400 || 110,400 || 0 || 0.03% || 0.03% || 0% || || 45 Points || 58,080 || 58,080 || 0 || 0.02% || 0.02% || 0% || || 46 Points || 28,800 || 28,800 || 0 || 0.01% || 0.01% || 0% || || 47 Points || 11,040 || 11,040 || 0 || 0.00% || 0.00% || 0% || || 48 Points || 3,360 || 3,360 || 0 || 0.00% || 0.00% || 0% || || 49 Points || 480 || 480 || 0 || 0.00% || 0.00% || 0% || || 50 Points || 0 || 0 || 0 || 0% || 0% || 0% || || Mode || 20 || 17 || 0 || || || || || Median || 21 || 18 || 4 || || || || || Mean || 21.014598 || 18.30114 || 5.253649 || || || || || Permutations || 349,216,560 || || || || || ||

Maximum Points

Drawing some cards prohibits the use of others. This changes things as cards are dealt (so I'm not sure averages from above really mean anything). In any case, there is a maximum number of points you can get drawing x cards per round. Since each hand eats the cards of a given rank, the rate points per round as you draw a "maximum hand" each round decreases. For example, when drawing four cards, the first round the maximum is four 10s. The next round, there are no more 10s, so the max would be four 9s. Drawing all cards gives 220 points total.

|| |||||||||||||||||||||||||||| Round || || Cards Drawn Per Round || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12 || 13 || 14 || || 3 || 30 || 58 || 84 || 108 || 129 || 148 || 165 || 180 || 192 || 202 || 210 || 216 || 219 || 220 || || 4 || 40 || 76 || 108 || 136 || 160 || 180 || 196 || 208 || 216 ||||||||||220 || || 5 || 49 || 92 || 129 || 160 || 184 || 202 || 214 ||||||||||||||220 || || 6 || 58 || 108 || 148 || 180 || 202 || 216 ||||||||||||||||220 || || 7 || 67 || 122 || 165 || 196 || 216 ||||||||||||||||||220 || || 8 || 76 || 142 || 188 || 214 ||||||||||||||||||||220 || || 9 || 84 || 154 || 199 || 219 ||||||||||||||||||||220 || || 10 || 92 || 165 || 208 ||||||||||||||||||||||220 ||

Maximum Diamonds

|| |||||||| Round || || Cards Drawn Per Round || 1 || 2 || 3 || 4 || || 3 || 27 || 45 || 54 || 55 || || 4 || 34 || 52 ||||55 || || 5 || 40 ||||||55 || || 6 || 45 ||||||55 || || 7 || 49 ||||||55 || || 8 || 52 ||||||55 || || 9 || 54 ||||||55 || || 10 ||||||||55 ||

Code

This is Python code I used to build the data above. It is pretty completely unoptimized and, thus, pretty slow:

class Card:
   def __init__(self,rank,suit,points):
      self.rank = rank
      self.suit = suit
      self.points = points
      
   def getPoints(self):
      return self.points
   
   def getRank(self):
      return self.rank
   
   def getSuit(self):
      return self.suit

   def __repr__(self):
      result = "%s of %s" % (self.rank, self.suit)
      return result
   
   def __cmp__(self,other):
      result = cmp(self.points,other.points)
      if result == 0:
         result = cmp(self.suit,other.suit) 
      return result
      
class Hand:
   def __init__(self):
      self.cards = []
      
   def getSize(self):
      return len(self.cards)
   
   def pushCard(self,card):
      contains = card in self.cards
      if (not contains):
         self.cards.append(card)
      return not contains
      
   def popCard(self):
      self.cards.pop()
      
   def calculatePoints(self):
      hash = {
         "Diamonds":[],
         "Hearts":[],
         "Clubs":[],
         "Spades":[],
         "Face":[]
      }
      total = 0
      for card in self.cards:
         points = card.getPoints()
         total += points
         suit = card.getSuit()
         rank = card.getRank()
         if (points):
            hash[suit].append(card)
         elif rank is not "Joker":
            hash["Face"].append(card)
      
      diamondpoints = 0
      for card in hash["Diamonds"]:
         points = card.getPoints();
         diamondpoints += points
     
      facetotal = total
      for card in hash["Face"]:
         suit = card.getSuit()
         if (suit != "Diamonds"):
            list = hash[suit]
            list.sort()
            try:
               negatedCard = list.pop()
               facetotal -= negatedCard.getPoints()
            except:
               pass
            
      return (total,facetotal,diamondpoints)

   def __repr__(self):
      result = repr(self.cards)
      return result

      
class Deck:
   def __init__(self):
      cards = []
      suits = ["Diamonds","Hearts","Clubs","Spades"]
      for suit in suits:
         cards.append(Card("Ace",suit,1))
         cards.append(Card("Two",suit,2))
         cards.append(Card("Three",suit,3))
         cards.append(Card("Four",suit,4))
         cards.append(Card("Five",suit,5))
         cards.append(Card("Six",suit,6))
         cards.append(Card("Seven",suit,7))
         cards.append(Card("Eight",suit,8))
         cards.append(Card("Nine",suit,9))
         cards.append(Card("Ten",suit,10))
         cards.append(Card("Jack",suit,0))
         cards.append(Card("Queen",suit,0))
         cards.append(Card("King",suit,0))
      cards.append(Card("Joker","First",0))
      cards.append(Card("Joker","Second",0))
      self.cards = cards
   
   def checkCards(self,results,hand,totalCards):
      size = hand.getSize()
      if size < totalCards:
          for card in self.cards:
             added = hand.pushCard(card)
             if added:
                   self.checkCards(results,hand,totalCards)
                   hand.popCard()

      else:
        self.analyzeHand(results,hand)
   
   def summarizePermutations(self,totalCards):
      results = {"permutations":0,
         "totals":{"median":0,"mode":0,"runningHands":0,"runningPoints":0,"runningMax":0},
         "facenegation":{"median":0,"mode":0,"runningHands":0,"runningPoints":0,"runningMax":0},
         "diamondtotal":{"median":0,"mode":0,"runningHands":0,"runningPoints":0,"runningMax":0}
      }
      pointRange = range(0,(10*totalCards)+1)
      for index in pointRange:
         results["totals"][index] = 0
         results["facenegation"][index] = 0
         results["diamondtotal"][index] = 0
         
      hand = Hand()
      self.checkCards(results,hand,totalCards)
      
      permutations = results["permutations"]
      middle = permutations / 2
      permfloat = 1.0 * permutations
      for index in pointRange:
         totals = self.compute[[PointSet]](results["totals"],index,middle)
         faceneg = self.compute[[PointSet]](results["facenegation"],index,middle)
         diamonds = self.compute[[PointSet]](results["diamondtotal"],index,middle)
         tpercent = (totals * 100.0) / permutations
         fpercent = (faceneg * 100.0) / permutations
         dpercent = (diamonds * 100.0) / permutations
         print "%d\t%d\t%d\t%d\t%f%%\t%f%%\t%f%%" % (index,totals,faceneg,diamonds,tpercent,fpercent,dpercent)
      print "%s\t%d\t%d\t%d" % ("Mode",results["totals"]["mode"],results["facenegation"]["mode"],results["diamondtotal"]["mode"])
      print "%s\t%d\t%d\t%d" % ("Median",results["totals"]["median"],results["facenegation"]["median"],results["diamondtotal"]["median"])
      print "%s\t%f\t%f\t%f" % ("Mean",results["totals"]["runningPoints"]/permfloat,results["facenegation"]["runningPoints"]/permfloat,results["diamondtotal"]["runningPoints"]/permfloat)
      print "Permutations\t%d" % (permutations)
      print
      
   def compute[[PointSet]](self,hash,index,middle):
      hands = hash[index]
      hash["runningHands"] += hands
      hash["runningPoints"] += hands * index
      if (hash["runningMax"] < hands):
         hash["runningMax"] = hands
         hash["mode"] = index
      if (hash["median"] == 0 and hash["runningHands"] > middle):
         hash["median"] = index
      return hands
      
   def analyzeHand(self,results,hand):
      (points, facepoints, diamondpoints) = hand.calculatePoints()
      results["totals"][points] += 1
      results["facenegation"][facepoints] += 1
      results["diamondtotal"][diamondpoints] += 1
      results["permutations"] += 1
   
deck = Deck()
deck.summarizePermutations(1)
deck.summarizePermutations(2)
deck.summarizePermutations(3)
deck.summarizePermutations(4)
deck.summarizePermutations(5)