Advertisement
Guest User

Python table thing

a guest
Nov 29th, 2014
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.85 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import random
  4. import re
  5. import sys
  6.  
  7. diceRegex = "^(\d+)d(\d+)(?:([-x+*/])(\d+))?"
  8. tableGroups = {}
  9.  
  10. class TableGroup(object):
  11.     def __init__(self, name):
  12.         self.name = name
  13.         filename = "{0}.txt".format(name)
  14.         self.tables = parseFile(filename)["tables"]
  15.         for table in self.tables:
  16.             self.tables[table].setTableGroup(self)
  17.         tableGroups[self.name] = self
  18.  
  19.     def getTable(self, name):
  20.         return self.tables[name.lower()]
  21.  
  22.     def rollOnTable(self, name):
  23.         if name.lower() in self.tables:
  24.             raw = str(self.getTable(name).getRandom())
  25.             return re.sub(" +", " ", raw)
  26.         else:
  27.             return "[No table named '{0}' in {1}]".format(name, self.name)
  28.  
  29. class Table(object):
  30.     def __init__(self, raw):
  31.         self.name = ""
  32.         self.entries = []
  33.         self.appendText = ""
  34.         for line in raw.split("\n"):
  35.             if line == "":
  36.                 continue
  37.             if line.startswith("#"):
  38.                 self.name = line[1:].strip()
  39.             elif line.startswith("!"):
  40.                 self.setDirective(line[1:].strip())
  41.             else:
  42.                 matches = re.match("^(\d+ )?(.*)", line)
  43.                 weight = matches.group(1)
  44.                 if weight == None:
  45.                     weight = 1;
  46.                 weight = int(weight)
  47.                 tokens = tokenize(matches.group(2))
  48.                 for i in range(0, weight):
  49.                     self.entries.append(Entry(tokens))
  50.  
  51.     def getRandom(self):
  52.         result = str(random.choice(self.entries))
  53.         # if self.appendText != "":
  54.             # result += " " + self.appendText
  55.         print "Getting random from {0}: {1}".format(self.name, result)
  56.         return result
  57.  
  58.     def setDirective(self, directive):
  59.         if directive.lower().startswith("append "):
  60.             self.appendText = directive[6:].strip()
  61.  
  62.     def setTableGroup(self, tableGroup):
  63.         self.tableGroup = tableGroup
  64.         for entry in self.entries:
  65.             entry.setTableGroup(self.tableGroup)
  66.  
  67. class Entry(object):
  68.     def __init__(self, tokens):
  69.         self.tokens = tokens
  70.  
  71.     def setTableGroup(self, tableGroup):
  72.         self.tableGroup = tableGroup
  73.         for token in self.tokens:
  74.             token.setTableGroup(self.tableGroup)
  75.  
  76.     def __str__(self):
  77.         parts = []
  78.         for token in self.tokens:
  79.             parts.append(str(token))
  80.         return "".join(parts)
  81.  
  82.     def __repr__(self):
  83.         return str(self)
  84.  
  85. class Token(object):
  86.     def __init__(self, value):
  87.         self.value = value
  88.  
  89.     def setTableGroup(self, tableGroup):
  90.         self.tableGroup = tableGroup
  91.  
  92.     def __str__(self):
  93.         dice = re.match(diceRegex, self.value)
  94.  
  95.         if dice != None:
  96.             text = parseDice(dice)
  97.         elif self.value.startswith("["):
  98.             text = parseExpression(self.value[1:-1], self.tableGroup)
  99.         else:
  100.             text = self.value
  101.  
  102.         return text
  103.  
  104.     def __repr__(self):
  105.         return str(self)
  106.  
  107. def parseFile(filename):
  108.     tables = {}
  109.  
  110.     try:
  111.         file = open(filename, "r")
  112.         text = file.read()
  113.     except IOError as ex:
  114.         print "Error opening {0}: {1}".format(filename, ex.strerror)
  115.         return {
  116.             "filename": filename,
  117.             "tables": tables,
  118.         }
  119.  
  120.     for rawtable in re.findall("^#[^#]*", text, re.M):
  121.         table = Table(rawtable)
  122.         tables[table.name.lower()] = table
  123.  
  124.     return {
  125.         "filename": filename,
  126.         "tables": tables,
  127.     }
  128.  
  129. def parseDice(dice):
  130.     number = int(dice.group(1))
  131.     size   = int(dice.group(2))
  132.     op     = dice.group(3)
  133.     mod    = int(dice.group(4) or 0)
  134.     total = 0
  135.     for i in range(0, number):
  136.         total = total + random.randint(1, size)
  137.  
  138.     if op == "+":
  139.         total += mod
  140.     elif op == "-":
  141.         total -= mod
  142.     elif op == "*":
  143.         total *= mod
  144.     elif op == "x":
  145.         total *= mod
  146.     elif op == "/":
  147.         total /= mod
  148.  
  149.     return str(total)
  150.  
  151. def parseExpression(expr, defaultTableGroup):
  152.     if expr.lower()[0:4].lower() == "list":
  153.         listMatch = re.match("^List (\d+(?:d\d+(?:[-x+*/]\d+)?)?)\s*((?:[-_.\w]+)?\s*->\s*.*)", expr, re.I)
  154.         if listMatch != None:
  155.             return parseList(listMatch, defaultTableGroup);
  156.         else:
  157.             return "[Unable to parse list: {0}]".format(expr)
  158.  
  159.     lookupMatch = re.match("([-_.\w]+)?\s*->\s*(.*)", expr)
  160.    
  161.     if lookupMatch != None:
  162.         source = lookupMatch.group(1)
  163.         table = lookupMatch.group(2)
  164.         if source == None:
  165.             return defaultTableGroup.rollOnTable(table)
  166.  
  167.         if source not in tableGroups:
  168.             TableGroup(source)
  169.  
  170.         return tableGroups[source].rollOnTable(table)
  171.  
  172.     return "[Unsure how to interpret: {0}]".format(expr)
  173.  
  174. def parseList(listMatch, defaultTableGroup):
  175.     results = {}
  176.     resultsText = []
  177.     amount = listMatch.group(1).strip()
  178.     table = listMatch.group(2).strip()
  179.  
  180.     diceMatch = re.match(diceRegex, amount)
  181.     if diceMatch != None:
  182.         amount = parseDice(diceMatch)
  183.  
  184.     amount = int(amount)
  185.  
  186.     for i in range(0, amount):
  187.         result = parseExpression(table, defaultTableGroup)
  188.         if result not in results:
  189.             results[result] = 0
  190.  
  191.         results[result] += 1
  192.  
  193.     for result in results:
  194.         qty = results[result]
  195.         if (qty > 1):
  196.             resultsText.append("{0}x {1}".format(str(qty), result))
  197.         else:
  198.             resultsText.append(result)
  199.  
  200.     return ", ".join(resultsText)
  201.  
  202. def tokenize(str):
  203.     tokens = []
  204.     for subtoken in re.findall("\[[^]]*]|[^[]+", str):
  205.         subtoken = subtoken
  206.         if subtoken[0] == "[":
  207.             tokens.append(Token(subtoken))
  208.         else:
  209.             dieSplit = re.split("(\d+d\d+(?:[-x+*/]\d+)?)", subtoken)
  210.             for token in dieSplit:
  211.                 token = token
  212.                 if (token != ""):
  213.                     tokens.append(Token(token))
  214.     return tokens
  215.  
  216. if __name__ == '__main__':
  217.     # TableGroup("treasure")
  218.     # for table in treasure.tables:
  219.     #   print table
  220.     # print tableGroups["treasure"].rollOnTable("CR 0 Hoard")
  221.     # print treasure.getTable("10 gp Gemstone").getRandom()
  222.     # print tokenize("1d6 [x 3d6 x] lal 5d3+4 knmdf kmfsd ")
  223.     # print tokenize("6d6*100 cp, 3d6*100 sp, 2d6*10 gp, and [-> CR 0 Treasure Hoard Items]")
  224.     pass
  225.  
  226. TableGroup("treasure")
  227. print tableGroups["treasure"].rollOnTable("CR 17 Hoard")
  228.  
  229. # if len(sys.argv) == 3:
  230. #   group = sys.argv[1]
  231. #   table = sys.argv[2]
  232. #   TableGroup(group)
  233. #   print tableGroups
  234. #   print tableGroups[group].rollOnTable(table)
  235. # else:
  236. #   print "Usage: ./Table.py tablegroup 'Table name'"
  237.  
  238. print 'Number of arguments:', len(sys.argv), 'arguments.'
  239. print 'Argument List:', str(sys.argv)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement