Advertisement
Guest User

Untitled

a guest
Jul 19th, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.17 KB | None | 0 0
  1. ''' NOTES ON WHAT TO DO NEXT
  2.  
  3. I PERSONALLY NEED TO UNDERSTAND ALL THE CODE!
  4.  
  5. Run standalone and return something like a tuple
  6. run standalone with a specified output method
  7. have an object to hold a bunch of information for you, etc.
  8.  
  9. d4-20 results in a minimum value of 1, maybe that's not the best by default unless specified
  10.  
  11. d4x20 doesn't multiply
  12. there's no division, which is probably just fine
  13.  
  14. I think I could crash this by doing a mult with like 1.2 or something like that
  15.  
  16. there's a reroll feature that I don't really understand currently. I should figure out how this works... and currently it just rr the low values, which is ok.
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24. '''
  25.  
  26. '''CURRENT FEATURES
  27. Syntax
  28. rolldesc,min1
  29.  
  30. Roll Descriptions
  31. d4x200 gives 200 results of 1d4
  32. 12d4 shows the sum of rolling 1d4 twelve times.
  33. d4^3 gives 3 separate results of rolling 1d4
  34. 4d6kh3 rolls 4d6 but keeps the results of only the highest 3 dice.
  35. 4d6kl3 lowest.
  36. d4+20 gives sum of 1d4 and 20
  37. d4-20 since the minimum result is currently 1 by default, this will return a 1.
  38. d4*100 result of d4 multiplied by 100
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46. '''
  47.  
  48.  
  49. '''FINAL FEATURES
  50.  
  51. I'd like to spruce this up with documentation so that it makes a nice HTML page on how to run it.
  52. I'd like a stand-alone mode that is used to just run a one-shot roll.
  53. Ideally I'd like my choice of how to output results (html, terminal, etc.)
  54.  
  55. I'd like to get rid of all the bugs but I don't know how I would find them, based on having random (and some hidden) output!
  56.  
  57. EV calculations, calculating percentage chances of success, etc.
  58.  
  59.  
  60.  
  61.  
  62.  
  63. '''
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70. # feature: sort the ^ results
  71. # feature: allow , to give multiple rolls per output
  72. # feature: tell the rolls that are being made
  73. # feature: verbose rolls for keeping highest dice
  74. # feature: allow non-sorting as well as sorting
  75.  
  76. # feature request: PUT A SORT RIGHT INTO THE ROLL DEScription
  77. # therefore functions that sort needs to get it from a self.sort thing.
  78. # actually maybe not because then I run into this issue of whether or not I
  79. # always need to have people specify sort vs no sort, etc. Not sure.
  80. # the self.mult is a partial model of how to solve this, though... consider that.
  81. # also I will need to update the documentation in order to make this work, maybe I should do something like N and S (sort, nosort)
  82. # consider doing something with the roll() in order to include a rolldescription there.
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89. import re, random
  90. random.seed()
  91.  
  92. DEBUG = False
  93. TESTS = False
  94.  
  95. #DEBUG = True
  96. TESTS = True
  97.  
  98. # --------------------------------------------------------------
  99.  
  100. def test_rolls():
  101. # print sum(Roller('3d6*10000').roll()) / float(10000)
  102. roller = Roller('d20*100')
  103. roller.rollout()
  104.  
  105. def test_patterns():
  106. p = re.compile(r'\d*d\d+[+-]?\d*', re.IGNORECASE)
  107. assert p.match('d20')
  108. assert p.match('1d20')
  109. assert p.match('d20+2')
  110. assert p.match('d20-1')
  111. assert p.match('1D20+1')
  112. assert p.match('d6')
  113. assert p.match('3d6')
  114. assert p.match('15d10-1')
  115. assert p.match('D20aa') # This passes, but len == len p.match('D20aa').group() fails, which is good.
  116. assert p.match('2D20')
  117.  
  118. #assert p.match('20D') #fails correctly
  119. #assert p.match('da20').group() #fails correctly
  120. #assert p.match('ad20') #fails correctly
  121. #assert p.match('^6') #fails correctly
  122.  
  123. p = re.compile(r'\^\d+')
  124.  
  125. def tests():
  126. test_patterns()
  127. test_rolls()
  128.  
  129. # --------------------------------------------------------------
  130.  
  131. class Roller:
  132. def __init__(self, rolldesc='1d20', MIN1=True):
  133. self.MIN1 = MIN1 #sets whether a dice roll can go below zero or not (2d4 is one roll, not two rolls)
  134. self.rolldesc = rolldesc
  135. self.results = []
  136. self.r = self.roll
  137. self.mult = False # I think currently this says how many groups to run of the same roll...
  138.  
  139.  
  140. def parse(self):
  141. pat_num_sides = re.compile(r'\d*D\d+')
  142. m = pat_num_sides.match(self.rdupper)
  143. assert m
  144. m = m.group().split('D')
  145. numdice = int(m[0]) if m[0] else 1
  146. dicesides = int(m[1])
  147. assert numdice > 0
  148. assert dicesides > 0
  149.  
  150. pat_mod = re.compile(r'[+-]\d+')
  151. m = pat_mod.search(self.rdupper)
  152. additive = int(m.group()) if m else 0
  153.  
  154. pat_multiplicative = re.compile(r'[*]\d+') #CURRENTLY I'M HAVING TROUBLE GETTING THE ASTERISK TO BE PROPERLY SEARCHED AS '*' INSTEAD OF WILDCARD
  155. m = pat_reps.search(self.rdupper)
  156. print m
  157. print m.group()
  158. multiplicative = int(m.group()[1:]) if m else 1
  159. assert multiplicative >= 1
  160. # print multiplicative
  161.  
  162. pat_reps = re.compile(r'[X]\d+')
  163. m = pat_reps.search(self.rdupper)
  164. reps = int(m.group()[1:]) if m else 1
  165. assert reps >= 1
  166.  
  167. pat_mult = re.compile(r'\^\d+')
  168. m = pat_mult.search(self.rdupper)
  169. mult = int(m.group()[1:]) if m else 1
  170. if mult < 2:
  171. self.mult = False
  172. else:
  173. self.mult = mult
  174.  
  175. pat_reroll = re.compile(r'RR\d+')
  176. m = pat_reroll.search(self.rdupper)
  177. reroll = int(m.group()[2:]) if m else 0
  178.  
  179. # not sure how to do this yet:
  180. '''
  181. pat_sort = re.compile(r's')
  182. if pat_sort.search(self.rdupper): self.sort = true
  183. '''
  184.  
  185. pat_keep = re.compile(r'K[HL]\d+')
  186. m = pat_keep.search(self.rdupper)
  187. if m:
  188. if m.group()[1] == 'H':
  189. keephigh = int(m.group()[2:])
  190. keeplow = 0
  191. else:
  192. keeplow = int(m.group()[2:])
  193. keephigh = 0
  194. else:
  195. keephigh = 0
  196. keeplow = 0
  197.  
  198. return numdice, dicesides, additive, reps, reroll, keephigh, keeplow, mult
  199.  
  200.  
  201. def newroll(self, rollstr):
  202. self.rolldesc = rollstr
  203.  
  204.  
  205. def clear_results(self):
  206. self.results = []
  207.  
  208.  
  209. def roll(self):
  210. '''Returns list of lists of results.'''
  211. self.rdupper = self.rolldesc.upper()
  212. self.clear_results()
  213. num, sides, mod, reps, reroll, keephigh, keeplow, mult = self.parse()
  214.  
  215. def rollgroup(MIN1=True):
  216. results = []
  217. for r in range(reps):
  218. result = 0
  219. rolls = []
  220.  
  221. for n in range(num):
  222. roll = random.randint(reroll+1,sides) + mod
  223. rolls.append(roll)
  224. if DEBUG: print roll
  225.  
  226. #FIX: SORTED??
  227. #rolls = sorted(rolls)
  228. if keephigh:
  229. result = sum(rolls[-keephigh:])
  230. elif keeplow:
  231. result = sum(rolls[:keeplow])
  232. else:
  233. result = sum(rolls)
  234.  
  235. if self.MIN1: result = max(result, 1)
  236. if DEBUG: print result
  237. results.append(result)
  238.  
  239. if DEBUG: print num, sides, mod, reps, reroll, keephigh, keeplow
  240. if DEBUG: print results
  241.  
  242. return results
  243.  
  244. if not self.mult:
  245. self.results = rollgroup(self.MIN1)
  246. return self.results
  247. else:
  248. mults = []
  249. for m in range(self.mult):
  250. mults.append(rollgroup(self.MIN1))
  251. self.results = mults
  252.  
  253. return self.results
  254.  
  255.  
  256. def printout(self, sort=False):
  257. if not self.mult:
  258. if sort:
  259. print list(reversed(sorted(self.results)))
  260. else:
  261. print self.results
  262. else:
  263. for r in self.results:
  264. if sort:
  265. print list(reversed(sorted(r)))
  266. else:
  267. print r
  268.  
  269.  
  270. def rollout(self, sort=False):
  271. self.roll()
  272. self.printout(sort)
  273.  
  274. # -------------------------------------------------
  275.  
  276. if __name__ == '__main__':
  277. if TESTS: tests()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement