Пример #1
0
 def test_uniqueList3(self):
    tab = Table("test1", ['one','two','three','four'], unique=True)
    res1 = Rpggen.finduse('test1')
    self.assertEqual(res1,'two')
    tab.clear()
    res2 = Rpggen.finduse('test1')
    self.assertEqual(res2,'two') 
Пример #2
0
 def test_createDict2(self):
    tab = Table("test1", {'roll': '1d4', '1-2':'two', '3-4': 'four'})
    res1 = Rpggen.finduse('test1')
    self.assertEqual(res1,'two')
    res2 = Rpggen.finduse('test1')
    self.assertEqual(res2,'two')
    values = tab.results()
    values.sort()
    self.assertEqual(values,['four','two'])
Пример #3
0
 def test_createDict3(self):
     tab = Table("test1", {'roll': '2d2', '2': 'two', '3-4': 'threefour'})
     res1 = tab.use()
     self.assertEqual(res1, 'threefour')
     res2 = tab.roll()
     self.assertEqual(res2, 'threefour')
     values = tab.results()
     values.sort()
     self.assertEqual(values, ['threefour', 'two'])
Пример #4
0
 def test_createDict(self):
     tab = Table("test1", {'1': 'one', '2': 'two'})
     res1 = tab.use()
     self.assertEqual(res1, 'two')
     res2 = tab.roll()
     self.assertEqual(res2, 'two')
     values = tab.results()
     values.sort()
     self.assertEqual(values, ['one', 'two'])
Пример #5
0
 def test_createNoName(self):
     tab = Table(['one', 'two', 'three', 'four'])
     res1 = tab.use()
     self.assertEqual(res1, 'two')
     res2 = tab.use()
     self.assertEqual(res2, 'two')
     values = tab.results()
     values.sort()
     self.assertEqual(values, ['four', 'one', 'three', 'two'])
Пример #6
0
 def test_createList(self):
    tab = Table("test1", ['one','two','three','four'])
    res1 = Rpggen.finduse('test1')
    self.assertEqual(res1,'two')
    res2 = Rpggen.finduse('test1')
    self.assertEqual(res2,'two')
    values = tab.results()
    values.sort()
    self.assertEqual(values,['four','one','three','two'])      
Пример #7
0
 def setUp(self):
     # Dice roller always returns this number, so we know what the results should be.
     Rpggen.testData = 2
     #logging.basicConfig(level=logging.DEBUG)
     self.allTables = []
     self.tab1 = Table("test1", ['one', 'two', 'three', 'four'])
     self.allTables.append(self.tab1)
     self.tab2 = Table("test2", {'1': 'one', '2': 'two'})
     self.allTables.append(self.tab2)
     self.tab3 = Table("test3", {
         'roll': '1d4',
         '1-2': 'two',
         '3-4': 'four'
     })
     self.allTables.append(self.tab3)
Пример #8
0
class TestTableActions(unittest.TestCase):
    def setUp(self):
        # Dice roller always returns this number, so we know what the results should be.
        Rpggen.testData = 2
        #logging.basicConfig(level=logging.DEBUG)
        self.allTables = []
        self.tab1 = Table("test1", ['one', 'two', 'three', 'four'])
        self.allTables.append(self.tab1)
        self.tab2 = Table("test2", {'1': 'one', '2': 'two'})
        self.allTables.append(self.tab2)
        self.tab3 = Table("test3", {
            'roll': '1d4',
            '1-2': 'two',
            '3-4': 'four'
        })
        self.allTables.append(self.tab3)

    def test_names(self):
        values = Table.names()
        self.assertEqual(values, 'test1, test2, test3')

    def test_results1(self):
        results = self.tab1.results()
        results.sort()
        self.assertEqual(results, ['four', 'one', 'three', 'two'])
Пример #9
0
 def test_uniqueFull(self):
    tab = Table("test8", ['one','two','three','four'], unique=True)
    res1 = Rpggen.finduse('test8')
    self.assertEqual(res1,'two')
    res2 = Rpggen.finduse('test8')
    self.assertEqual(res2,'one') 
    res3 = Rpggen.finduse('test8')
    self.assertEqual(res3,'three')    
    res4 = Rpggen.finduse('test8')
    self.assertEqual(res4,'four') 
Пример #10
0
 def test_uniqueFull2(self):
    tab = Table("test8", ['one','two','three','four'], unique=True)
    res1 = Rpggen.finduse('test8')
    self.assertEqual(res1,'two')
    res2 = Rpggen.finduse('test8')
    self.assertEqual(res2,'one') 
    res3 = Rpggen.finduse('test8')
    self.assertEqual(res3,'three')    
    res4 = Rpggen.finduse('test8')
    self.assertEqual(res4,'four') 
    # Expect/want the exception here
    self.assertRaises(ValueError,tab.use)
Пример #11
0
 def test_uniqueFull(self):
     tab = Table("test8", ['one', 'two', 'three', 'four'], unique=True)
     res1 = tab.use()
     self.assertEqual(res1, 'two')
     res2 = tab.use()
     self.assertEqual(res2, 'one')
     res3 = tab.use()
     self.assertEqual(res3, 'three')
     res4 = tab.use()
     self.assertEqual(res4, 'four')
Пример #12
0
 def __init__(self):
     super().__init__({
         'name': 'Corporate Repo',
         'qualifications': 'Int 5+',
         'survival': 'Int 4+',
         'commission': 'Soc 7+',
         'advancement': 'Int 6+',
         'reenlistment': '5+'
     })
     self.addData('Ranks', [
         'Crew', 'Specialist', 'Agent', 'Lead', 'Manager', 'Director',
         'Executive'
     ])
     self.addData('Skills',
                  ['Streetwise', None, 'GunCombat', None, None, None, None])
     self.addTable(
         Table('MaterialBenefits', [
             'Weapon', 'Explorer\' Society', 'Weapon', 'Mid Passage',
             'High Passage', 'High Passage or Starship'
         ]))
     self.addTable(
         Table('CashBenefits', [
             'cr2000', 'cr10000', 'cr10000', 'cr10000', 'cr20000',
             'cr40000', 'cr100000'
         ]))
     self.addTable(
         Table('PersonalDevelopment', [
             '+1 Str', '+1 Dex', '+1 End', 'MeleeCombat', 'Vehicle',
             'Athletics'
         ]))
     self.addTable(
         Table('ServiceDevelopment', [
             'Streetwise', 'Engineering', 'Bribery', 'Liaison', 'Recon',
             'Mechanics'
         ]))
     self.addTable(
         Table('SpecialistDevelopment', [
             'Zero-G', 'Comms', 'Admin', 'Tactics', 'Leadership',
             'Jack-o-Trades'
         ]))
     self.addTable(
         Table('AdvancedDevelopment', [
             'Computer', 'Gravitics', 'Piloting', 'Navigation', 'Advocate',
             'Electronics'
         ]))
Пример #13
0
class Career():
    '''This class represents one Traveller career.
      It mostly contains functions aimed at a character's pregression through that career.

      More specific rules (such as CepheusEngine or MegaTraveller) will have their own career
      classes which will usually inherit from this one.

      Also, each specific career (Scout, Army, Pirate, etc.) will inherit from this class.
   '''

    whichAdvantage = Table("WhichAdvantage", [
        'MaterialBenefits', 'CashBenefits', 'PersonalDevelopment',
        'ServiceDevelopment'
    ])

    def __init__(self, config):
        try:
            self.name = config['name']
            self.config = config
            self.log = []
        except:
            raise ValueError('Config did not have the items required.')

    def addData(self, name, data):
        self.config[name] = data

    # TODO remove this? use addData+Table
    def addTable(self, name, tab=None):
        '''Add this table to the career creation system.
         If two areguments are passed in, use the first as the name.
         Otherwise, use the table's id as the name.
      '''
        if tab is None:
            tab = name
            name = tab.id
        self.config[name] = tab

    def changeName(self, name):
        self.name = name
        self.config['name'] = name

    def doBasicTraining(self, character):
        # TODO put in seperate function
        character.history.append('In basic training')
        which = self.whichAdvantage.use()
        adv = Rpggen.finduse(which)
        character.changeStr(adv)

    def doMusteringOut(self, character):
        # CE31
        # Calculate pension
        if character.rank > 4:
            character.money['pension'] = 2000 * character.rank
            character.history.append('Got a pension of %d' %
                                     character.money['pension'])

        # Calculate number of benefits
        benefitCount = character.terms
        if character.rank >= 4:
            benefitCount = character.rank - 2
        # Divide between cash and material
        cashBenefits = 0
        materialBenefits = 0
        if benefitCount < 3:
            cashBenefits = benefitCount
        elif 3 <= benefitCount:
            cashBenefits = 2
            materialBenefits = benefitCount - 2

        character.history.append(
            'Ended up with %d cash and %d material benefits' %
            (cashBenefits, materialBenefits))
        for num in range(cashBenefits):
            benefit = Rpggen.finduse('CashBenefits')
            character.money['bank'] += Traveller.str2cr(benefit)
            character.history.append(benefit)
        for num in range(materialBenefits):
            benefit = Rpggen.finduse('MaterialBenefits')
            if benefit.startswith('+'):
                character.changeStr(benefit)
            else:
                character.possessions.append(benefit)
            character.history.append(benefit)

    def doOneTerm(self, character, debug=False):
        '''Adds one term to a character.
         Returns None if the career continues, or a string if the career
         ends, the string stating why the career ends.
      '''
        if debug:
            print('entering doOneTerm')
        character.history.append('Starting a new term.')
        if character.terms == 7:
            result = 'Aged out of career.'
            character.history.append(result)
            return result
        if not character.checkStr(self.config['survival']):
            result = 'Did not survive.'
            character.history.append(result)
            return result
        character.terms += 1
        character.age += 4

        # TODO use funciton here
        which = self.whichAdvantage.use()
        adv = Rpggen.finduse(which)
        character.changeStr(adv)

        print('rank %d' % character.rank)
        if character.rank == 0:
            print('foo')
            if character.checkStr(self.config['commission']):
                character.history.append('Was commissioned')
                character.rank = 1
                newSkill = self.config['Skills'][character.rank - 1]
                if newSkill is not None:
                    character.changeStr(newSkill)
        else:
            if character.checkStr(self.config['advancement']):
                character.history.append('Advanced in rank.')
                character.rank += 1
                newSkill = self.config['Skills'][character.rank - 1]
                if newSkill is not None:
                    character.changeStr(newSkill)

        if self.roll('reenlistment'):
            return 'Could not reenlist.'

        return None

    def roll(self, name):
        '''Roll on the named item for this career.
         Only works on rolls specific to a career (reenlistment, survival, etc.)
         Returnes True if succeeds and False if it fails.
         Raises an exception if the argument is not known to this career.
      '''
        try:
            target = self.config[name]
        except:
            KeyError('The Career %s did not have a config item called %s' %
                     (self.name, name))
        return Traveller.roll(target=target)

    def use(self, name):
        '''Roll on the named item for this career.
         Returnes True if succeeds and False if it fails.
         Raises an exception if the argument is not known to this career.
      '''
        try:
            tab = self.config[name]
        except:
            KeyError('The Career %s did not have a config item called %s' %
                     (self.name, name))
        return tab.use()

    def printTestHelper(self, name):
        try:
            data = self.config[name]
            print('Has %s: %s' % (name, str(data)))
        except KeyError:
            print('Does not have %s.' % name)

    def printTest(self):
        self.printTestHelper('name')
        self.printTestHelper('qualifications')
        self.printTestHelper('survival')
        self.printTestHelper('commission')
        self.printTestHelper('advancement')
        self.printTestHelper('reenlistment')
        self.printTestHelper('Ranks')
        self.printTestHelper('Skills')
        self.printTestHelper('MaterialBenefits')
        self.printTestHelper('CashBenefits')
        self.printTestHelper('PersonalDevelopment')
        self.printTestHelper('ServiceDevelopment')
        self.printTestHelper('SpecialistDevelopment')
        self.printTestHelper('AdvancedDevelopment')
Пример #14
0
 def test_uniqueList2(self):
    tab = Table("test1", ['one','two','three','four'], unique=False)
    res1 = Rpggen.finduse('test1')
    self.assertEqual(res1,'two')
    res2 = Rpggen.finduse('test1')
    self.assertEqual(res2,'two') 
Пример #15
0
 def test_table(self):
     tab = Table('test3', {'1': 'one', '2': 'two'})
     temp = Template('t1', '''IQ: {{use('test3')}}''')
     result = temp.use()
     self.assertEqual(result, 'IQ: two')
Пример #16
0
 def test_uniqueList2(self):
     tab = Table("test1", ['one', 'two', 'three', 'four'], unique=False)
     res1 = tab.use()
     self.assertEqual(res1, 'two')
     res2 = tab.use()
     self.assertEqual(res2, 'two')
Пример #17
0
class YoungThug(Character):
   # Updated when improvements are made to the generation algorithm.
   version = '0.2'

   # Tables are class variables, not object variables, so that when we print out the YoungThug
   # class as a json string, we do NOT include these tables.

   meleeSkills = Table("MeleeSkills", ['Melee Combat (Blugeoning)', 'Melee Combat (Piercing)',
		                                   'Melee Combat (Slashing)'], unique=True)
   weaponSkills = Table("WeaponsSkills",
                        ['Gun Combat (EnergyRifle)','Gun Combat (EnergyPistol)',
		                   'Gun Combat (Shotgun)', 'GunCombat (SlugRifle)',
		                   'Gun Combat (SlugPistol)'],
                        unique=True)

   otherSkills = Table("OtherSkills", 
                       ['Bribery', 'Courousing', 'Gambling', 'Leadership', 'Mechanics',
                        'Medicine', 'Recon', 'Streetwise', 'Tactics'],
		                 unique=True)
   # This is a very generic table, which should be overwritten by a better one in the
   # setting table
   possessionsTable = Table('PossessionsTable',
                            ['{{use("PossessionsTableRare")}}', 'Anti-Laser Aerosol',
                             'Body Armor', 'Key', 'Legal Drugs',
                             'Drug Paraphenella', 
                             'Illegal Drugs', 'Gambling Materials', 'Gear Bag',   
                             'Forgerly or Lockpicking Equipment', 'Jumk Food',
                             'Gloves', 'Flask', 'Photo', 'Recording Equipment', 'Shades',
                             'Sanitizer', 'Survellience Gear',
                             'Torn Up Photo', 'Mints',                        
                             'Lip Balm or Handcream'])
   possessionsTableRare = Table('PossessionsTableRare',
                                ['Broken Jewlery', 'Bandage(s) or BandAid(s)', 
                                 'Plastic Tie'],
                                unique=True)

   looksTable = Table('Looks',

    
                 { 'roll': '1d12',
                   '1': 'Cosmetic Surgery', '2': 'Cyborg Enhasement (Obvious)', 
                   '3': 'Body Piercing', '4': 'Jewlery', '5': 'Tatoos', 
                   '6': 'Unusual Clothing', 
                   '7': 'Unusual Hair',
                   '8-12': 'Nothing Unusual'})

   personalityTable = Rpggen.loadLt("PersonalityTraits.lt") 

   def __init__(self):
      super().__init__()
      Rpggen.clear()
      try:
         Rpggen.load("Setting.rpggen")
      except:
         print('Warning: could not find data file Setting.rpggen.') 
         print(sys.exc_info()[1])    
     

   def generate(self, debug=False):
      '''Create a young thug.
      '''
      Rpggen.clear()
      self.name = GetFromWeb.get('names')
      self.name = string.capwords(self.name)
      if debug:
         print(self.name)
      self.lastCareer = "No Career"    
      self.str = Rpggen.roll('2d5+2')
      self.dex = Rpggen.roll('2d5+2')
      self.end = Rpggen.roll('2d5+2')
      self.int = Rpggen.roll('2d5')
      self.edu = Rpggen.roll('2d2')
      self.soc = Rpggen.roll('2d3')

      if YoungThug.personalityTable is not None:
         self.personality = YoungThug.personalityTable.rollRepeatedly(3, unique=True)

      level = Select.choose(['teen','start', 'young'])
      if level == 'teen':
         self.age = Rpggen.roll('1d3+15')
         self.terms = 0  
         numSkills = 2   # TODO right number?     
      elif level == 'start':
         self.age = Rpggen.roll('1d3+17')
         self.terms = 0     
         numSkills = 3   #  
      elif level == 'young':
         self.lastCareer = "Rogue"   
         self.age = Rpggen.roll('1d3+21')
         self.terms = 1
         numSkills = 5 # TODO right number?  Basic Training plus above.
      else:
         raise ValueError('level is an unknown value: %s' % level)

    # Three issues here: what skills, and what level (also equipment based on skills)
    # So we cycle through skills like this: 
    #   Brawling, Weapon, Something Else
    #   Until we are done with the skills the character has.
    # Most skills will be 0 or 1 at this point, but a few will be 2.
    # teens get 1 skill at 1, rest at 0    (20% change a 0 becomes a 2)
    # start get 3 skills at 1, rest at 0   (20% change a 1 to a 2)
    # young get 7 skills at 1, rest at 0   (20% change a 1 to a 2)

    # lucky means the character get more skills
      lucky = Rpggen.roll('1d3')-2
      numSkills += lucky
      if numSkills < 2:
          numSkills = 2
      if numSkills > 6:
          numSkills = 6          

      for idx in range(1, numSkills+1):
         if idx < 7:
            if (idx % 3) == 1:
               skill = Attribute(self.meleeSkills.use(),0)
               self.skills.append(skill)
            elif (idx % 3) == 2:
               skill = Attribute(self.weaponSkills.use(),0)
               self.skills.append(skill) 
            elif (idx % 3) == 0:
               skill = Attribute(self.otherSkills.use(),0)
               self.skills.append(skill)
            else:
               print('bad %d %d' % (idx, (idx % 3)))
         else:
             skill = Attribute(self.otherSkills.use(),0)
             self.skills.append(skill) 

      if level == 'teen':
         attr = Select.choose(self.skills,1)
         self.addToSkill(attr.name, attr.specific, 1)
      elif level == 'start':
         attrs = Select.choose(self.skills,2)
         for attr in attrs:
            self.addToSkill(attr.name, attr.specific, 1)  
      elif level == 'young':
         attrs = Select.choose(self.skills,2)
         for attr in attrs:
            self.addToSkill(attr.name, attr.specific, 1) 
      else:
         raise ValueError('level is an unknown value: %s' % level)                 	

      # Loop through each skills, and give any equipment that makes sense.
      for attr in self.skills:
         if attr.specific is not None:  
            self.equipmentTableOrDefault(attr.specific)

      # Figure out how much money he has 
      # TODO: refine algorithm
      # TODO: add bling
      pocket = int(Rpggen.roll('2d20')) * 10
      bank = int(Rpggen.roll('2d5')) * 100
      self.money = { 'pocket': pocket, 'bank': bank, 'pension': 0}

      # What is the thug carrying?
      if self.possessionsTable is not None:
         if self.money['bank'] > 300:
            num = Rpggen.roll('3d2')
         else:
            num = Rpggen.roll('2d2')
         self.possessions = Rpggen.find('PossessionsTable').rollRepeatedly(num)

      self.looks = self.looksTable.roll()

      # Add some events

   def equipmentTableOrDefault(self, weapon, default=None):
      '''Note that this function assumes a table with name 'WeaponsX' for each skill with a
         specialization of X.  If oneis not found, then default is used, and if default is not
         set, then the specialization is used as a possetion.  (Which actually works better than
         you would expect.)
      '''
      if default is None:
         default = weapon
      tableName = 'Weapons'+weapon
      try: 
         equipment = Rpggen.finduse(tableName)
         if equipment is None or equipment == '':
            logging.warning('Using equipment table %s returned None or "".' % tableName)
         else:
            self.equipment.append(equipment)
      except:
         logging.warning('Table %s not found, but should have been in Settings.rpggen.' %
                        tableName)
         logging.warning(sys.exc_info()[1])    
         self.equipment.append(default+' Weapon')         

   def text(self):
      return self.strSmall()

   def html(self):
       doc, tag, text = Doc().tagtext()
       text('Name: %s --- %s --- %d years old' % (self.name, self.strUpp(),self.age))
       doc.asis('<br>')
       text('%s (%d term%s)              Cr%d' % (self.strCareer(), self.terms, ("s" if (self.terms!=1) else ""), self.availableMoney()))
       doc.asis('<p>')
       text(self.strSkills())
       if self.personality is not None:
          doc.stag('br') 
          text('Personality: %s' % ', '.join(self.personality))       
       doc.asis('<br>') 
       text('Equipment: %s' % ', '.join(self.equipment))
       doc.asis('<br>')
       text('Possessions: %s' % ', '.join(self.possessions))
       doc.asis('<br>')       
       text('Money: %d in pocket, %d in bank, %d in pension' %
                  (self.money['pocket'], self.money['bank'], self.money['pension']))
       doc.asis('<br>')
       text('Looks: %s' % self.looks)
       doc.asis('<br>')       
       #with tag('ol'):
       #   for history in self.history:
       #      with tag('li'):
       #         text(history)
       return doc.getvalue() 

   def htmlText(self):
      '''Returns a Young Thug in text format, but wrapped in the PRE tag, so it is actually
         HTML.
      '''
      return '<pre>'+self.strSmall()+'</pre>'  

   @classmethod
   def htmlPage(self, count=8):
      characters = []
      for ii in range(count):
         characters.append(YoungThug())
         characters[ii].generate()

      doc, tag, text = Doc().tagtext()
      with tag("html"):
         with tag("head"):
           pass
         with tag("body"):
            with tag("table", width = '100%', border=2, cellpadding=10, style='table-layout: fixed;'):
               for ii in range(int(count/2)):
                  with tag("tr", border=2):
                    for jj in range(2):
                      with tag('td', width = '50%', height = '25%', padding='15', border=2, style='word-wrap:break-word;'):
                        ch = characters[((ii*2)+(jj-1))-1]
                        tmp = ch.html()
                        doc.asis(tmp)
            doc.asis('<br>')
            with tag('small'):
               with tag('center'):
                  text('Traveller is a registered trademark of Far Future Enterprises.')
                  doc.stag('br')
                  text('Generated by Joshua Levy "Young Thugs" web server in 2017 version %s' % self.version)
      return doc.getvalue()
Пример #18
0
# Rule 1(b): All objects have a method called "use", which uses that object,
# but many of the object also have a method called "roll" which does the same
# thing.  Because sometimes it just feels better to say "use" and other times it
# feels better to say "roll".

print('Rolling 1d10+3 again: %s' % dice.use())

# Rpggen also supports Tables.
# You can create tables in three different ways, and I'll go through each one
# in turn, and the discuss which type of table you should use in which
# situation.

# This first example creates a table out of a list.  Each item in the list has the
# same chance of being selected.

tab1 = Table('PlanetaryOcean',
             ['On Surface', 'Under A Thin Crust', 'Deep Underground'])

# this second example creates a table out of a python dictionary.  The first element
# is the roll, the second is the result for each "line" in the table.

tab2 = Table('Race', {'1-3': 'Human', '4-5': "Elf", '6': 'Dwarf'})

# and you can use these tables in the obvious ways:
print('Using the PlanetaryOcean table: %s' % tab1.use())
print('Using the Race table: %s' % tab2.roll())

# Rule 2: many functions support a "debug=True" option.  If you pass that
# option in, it will print out debugging information designed to help you
# figure out what is going on, and why it is happening.

# You can also do several other interesting things with tables:
Пример #19
0
 def test_names(self):
     values = Table.names()
     self.assertEqual(values, 'test1, test2, test3')
Пример #20
0
 def __init__(self):
     super().__init__()
     if Character.skillTab is None:
         Character.skillTab = Table('skills', Character.skills)