def test_add_row(self): '''Table: Test add_row()''' tbl = Table() tbl.add_row(1, 'Entry 1') # Should just work tbl.add_row((2, 3), 'Entry 2') # Should ust work tbl.add_row('A', 'Entry 3') with self.assertRaises(ValueError): tbl.add_row(dict(), 'Bogus entry') # ValueError
def test_table_in_table(self): '''Table: Test subtable''' tbl2 = Table() tbl2.add_row(1, 'Subentry 1') tbl2.dice = 1 tbl1 = Table() tbl1.add_row(1, 'Entry 1') tbl1.add_row(2, tbl2.roll) self.assertEquals(tbl1.lookup(2), 'Subentry 1')
def generate_chemistry(self, ranges, roll): ''' Inputs: - range in table - roll Returns: - chemistry - age modifier ''' if len(ranges) == 3: # Build table chemistry_table = Table() for i in range(0, len(ranges)): chemistry_table.add_row(ranges[i], self.chemistry_values[i]) # Generate return chemistry_table.lookup(roll)
def test_roll(self): '''Table: Test roll()''' tbl = Table() tbl.add_row((1, 6), 'Entry 1') tbl.dice = 1 self.assertEquals(tbl.roll(), 'Entry 1')
def test_lookup(self): '''Table: Test lookup()''' tbl = Table() tbl.add_row(1, 'Entry 1') self.assertEquals(tbl.lookup(1), 'Entry 1')
class System(object): '''Return a T5 basic system with the specified name and location hex''' naval_base_presence = Table() naval_base_presence.add_row('A', 6) naval_base_presence.add_row('B', 5) scout_base_presence = Table() scout_base_presence.add_row('A', 4) scout_base_presence.add_row('B', 5) scout_base_presence.add_row('C', 6) scout_base_presence.add_row('D', 7) mw_orbit_flux_table = Table() mw_orbit_flux_table.add_row(-6, -2) mw_orbit_flux_table.add_row((-5, -3), -1) mw_orbit_flux_table.add_row((-2, 2), 0) mw_orbit_flux_table.add_row((3, 5), 1) mw_orbit_flux_table.add_row(6, 2) def __init__(self, name='', location_hex='0000'): self.hex = location_hex self.name = name self.zone = '' self.stellar = Primary() self.mainworld = Planet() self.determine_mw_orbit() self.bases = self.determine_bases() self.pbg = Pbg(self.mainworld) self.allegiance = 'Na' self.determine_trade_codes() self.determine_x() self.nobility = self.determine_nobility() self.num_worlds = (self.pbg.belts + self.pbg.gasgiants + D6.roll(1) + 1) self.determine_travel_zone() def display(self): '''Display''' return '{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}'.format( self.hex, self.name, self.mainworld.uwp(), ' '.join(self.mainworld.trade_codes), str(self.importance_x), str(self.economic_x), str(self.cultural_x), self.nobility, self.bases, self.zone, str(self.pbg), self.num_worlds, self.allegiance, self.stellar.display()) def __str__(self): oformat = '{0:4} {1:20} {2:9} {3:18} {4:4} {5:7} {6:6} ' +\ '{7:7} {8:2} {9:1} {10:3} {11:2} {12:2} {13:14}' return oformat.format(self.hex, self.name, self.mainworld.uwp(), ' '.join(self.mainworld.trade_codes), str(self.importance_x), str(self.economic_x), str(self.cultural_x.display()), self.nobility, self.bases, self.zone, str(self.pbg), self.num_worlds, self.allegiance, self.stellar.display()) def determine_nobility(self): '''Determine noble representation''' nobility = 'B' # Every world gets a knight # Baronet if ('Pa' in self.mainworld.trade_codes or 'Pr' in self.mainworld.trade_codes): nobility += 'c' # Baron if ('Ag' in self.mainworld.trade_codes or 'Ri' in self.mainworld.trade_codes): nobility += 'C' if 'Pi' in self.mainworld.trade_codes: nobility += 'D' # Marquis if 'Ph' in self.mainworld.trade_codes: nobility += 'e' # Viscount # Count if ('In' in self.mainworld.trade_codes or 'Hi' in self.mainworld.trade_codes): nobility += 'E' if int(self.importance_x) >= 4: nobility += 'f' # Duke return nobility def determine_bases(self): '''Determine bases''' bases = '' # Naval base target = self.naval_base_presence.lookup(self.mainworld.starport) if target is not None: if D6.roll(2) <= target: bases += 'N' # Scout base target = self.scout_base_presence.lookup(self.mainworld.starport) if target is not None: if D6.roll(2) <= target: bases += 'S' return bases def determine_trade_codes(self): '''Determine climate trade codes''' tcs = TradeCodes(self.mainworld, self) self.mainworld.trade_codes = tcs.generate() def determine_mw_orbit(self): '''Determine mainworld orbit''' orbit = self.stellar.habitable_zone +\ self.mw_orbit_flux_table.lookup(FLUX.flux()) orbit = max(orbit, 0) self.mainworld.orbit = orbit def determine_travel_zone(self, starport_x_is_red=True): '''Determine travel zone - A or R''' self.zone = '' if int(self.mainworld.government) + \ int(self.mainworld.law_level) in [20, 21]: self.zone = 'A' self.mainworld.trade_codes.append('Da') elif int(self.mainworld.government) + \ int(self.mainworld.law_level) > 22: self.zone = 'R' if starport_x_is_red: if self.mainworld.starport == 'X': self.zone = 'R' self.mainworld.trade_codes.append('Fo') def as_json(self): '''Return JSON representation of system''' system_dict = { 'name': self.name, 'hex': self.hex, 'stellar': self.stellar.as_json(), 'mainworld': self.mainworld.as_json(), 'bases': self.bases, 'pbg': str(self.pbg), 'allegiance': self.allegiance, 'Ix': str(self.importance_x), 'Ex': str(self.economic_x), 'Cx': str(self.cultural_x), 'nobility': self.nobility, 'worlds': self.num_worlds, 'zone': self.zone } return json.dumps(system_dict) def json_import(self, jdata): '''Import from JSON''' system_dict = json.loads(jdata) self.name = system_dict['name'] self.hex = system_dict['hex'] self.bases = system_dict['bases'] self.allegiance = system_dict['allegiance'] self.nobility = system_dict['nobility'] self.num_worlds = int(system_dict['worlds']) self.zone = system_dict['zone'] self.stellar.json_import(system_dict['stellar']) self.mainworld.json_import(system_dict['mainworld']) self.pbg.json_import(system_dict['pbg']) self.importance_x.json_import(system_dict['Ix']) self.economic_x.json_import(system_dict['Ex']) self.cultural_x.json_import(system_dict['Cx']) def determine_x(self): '''Determine Ix Ex Cx values''' self.importance_x = ImportanceExtension(self.mainworld, self) self.economic_x = EconomicExtension(self.pbg, int(self.mainworld.population), int(self.mainworld.tech_level), self.mainworld.trade_codes, int(self.importance_x)) self.cultural_x = CulturalExtension(int(self.mainworld.population), int(self.importance_x), int(self.mainworld.tech_level))
class _MappingRegion(object): '''Sector/subsector base class''' system_presence_table = Table() system_presence_table.add_row('Extra galactic', 1) system_presence_table.add_row('Rift', 3) system_presence_table.add_row('Sparse', 17) system_presence_table.add_row('Scattered', 33) system_presence_table.add_row('Standard', 50) system_presence_table.add_row('Dense', 66) system_presence_table.add_row('Cluster', 83) system_presence_table.add_row('Core', 91) def __init__(self, name, density='Standard'): seed() self.name = name self.size_x = 0 self.size_y = 0 self.hexes = {} self.density = density def display(self): '''Display''' hexlist = sorted(self.hexes.keys()) for hex_id in hexlist: print(self.hexes[hex_id].display()) def as_list(self): '''Return contents as list''' out = [] hexlist = sorted(self.hexes.keys()) for hex_id in hexlist: out.append(self.hexes[hex_id].display()) return out @staticmethod def percentile(): '''1-100%''' return randint(1, 100) def process_hex(self, hex_id, ss_id=''): '''Add system on probability check''' name = 'Name-{}{}'.format(hex_id, ss_id) if self.percentile() <= \ self.system_presence_table.lookup(self.density): self.hexes[hex_id] = System(name, hex_id) def t5_tab(self): '''Output in T5 tab format''' out = [ '\t'.join([ 'Hex', 'Name', 'UWP', 'Remarks', '{Ix}', '(Ex)', '[Cx]', 'Nobility', 'Bases', 'Zone', 'PBG', 'W', 'Allegiance', 'Stars' ]) ] out.extend(self.as_list()) return out def find_nearby_hexes(self, o_hex_id, radius=1): '''Find hexes within radius of hex_id''' ''' B A C O F D E Add column of r+1 hexes starting at A, C Add column of r+2 hexes starting at A+1 ... etc ... Add column of 2r hexes starting at B (excluding O) Hex IDs on A->B (and B->C) depend on co-ordinates of O, size of r ''' nearby_hexes = [] o_col = int(o_hex_id[:2]) o_row = int(o_hex_id[2:]) side_length = radius + 1 a_col = o_col - radius c_col = o_col + radius if self._is_even(o_col): if self._is_even(radius): x_row = o_row - int(radius / 2) + 0.5 else: x_row = o_row - int(radius / 2) else: if self._is_even(radius): x_row = o_row - int(radius / 2) else: x_row = o_row - int(radius / 2) - 0.5 LOGGER.debug('O = %s radius = %s', o_hex_id, radius) LOGGER.debug('A = %s%s', a_col, x_row) col_length = side_length for col in range(0, radius): l_col = a_col + col r_col = c_col - col LOGGER.debug('l_col = %s r_col = %s x_row = %s', l_col, r_col, x_row) LOGGER.debug('col_length = %s', col_length) for idx in range(0, col_length): row = x_row + idx if l_col > 0 and int(row) > 0: l_hex_id = '{0:02d}{1:02d}'.format(l_col, int(row)) LOGGER.debug('Adding %s', l_hex_id) nearby_hexes.append(l_hex_id) if r_col > 0 and int(row) > 0: r_hex_id = '{0:02d}{1:02d}'.format(r_col, int(row)) LOGGER.debug('Adding %s', r_hex_id) nearby_hexes.append(r_hex_id) x_row -= 0.5 col_length += 1 for row in range(o_row - radius, o_row + radius + 1): if row > 0: hex_id = '{0:02d}{1:02d}'.format(o_col, row) if hex_id != o_hex_id: LOGGER.debug('Adding %s', hex_id) nearby_hexes.append(hex_id) return sorted(nearby_hexes) @staticmethod def _is_even(number): '''Return True for even number''' return float(number) / 2 == int(number / 2) def find_nearby_systems(self, hex_id, radius): '''Find worlds/systems in nearby hexes''' nearby_worlds = [] for hex_id in self.find_nearby_hexes(hex_id, radius): if self.is_system(hex_id): nearby_worlds.append(self.is_system(hex_id)) return nearby_worlds def is_system(self, hex_id): '''Return False if there is a system at hex_id, system otherwise''' if hex_id in self.hexes.keys(): return self.hexes[hex_id] else: return False def find_owning_system(self, hex_id): '''Return hex_id for most important system within 6 hexes''' nearby_systems = self.find_nearby_systems(hex_id, 6) most_important_system_ix = [] importance = -10 for system in nearby_systems: if int(system.importance_x) == importance: most_important_system_ix.append(system) elif int(system.importance_x) > importance: most_important_system_ix = [system] importance = int(system.importance_x) if len(most_important_system_ix) > 1: # Need to resolve tie - use Population population = -1 most_important_system_pop = [] for system in most_important_system_ix: if int(system.mainworld.population) == population: most_important_system_pop.append(system) elif int(system.mainworld.population) > population: most_important_system_pop = [system] population = int(system.mainworld.population) if len(most_important_system_pop) > 1: # Another tie - resolve wth TL tech_level = -1 most_important_system_tl = [] for system in most_important_system_pop: if int(system.mainworld.tech_level) == tech_level: most_important_system_tl.append(system) elif int(system.mainworld.tech_level) > tech_level: most_important_system_tl = [system] tech_level = int(system.mainworld.tech_level) if len(most_important_system_tl) > 1: # Tie - pick one at random return (most_important_system_tl[randint( 0, len(most_important_system_tl) - 1)].hex) else: return most_important_system_tl[0].hex else: return most_important_system_pop[0].hex else: return most_important_system_ix[0].hex def trade_code_owning_system(self): '''Trade codes extra pass - O:''' for hex_id in self.hexes.keys(): owned = False trade_codes = self.hexes[hex_id].mainworld.trade_codes for i, code in enumerate(trade_codes): if code.startswith('O:'): LOGGER.debug('Found owned system %s', str(hex_id)) owner = self.find_owning_system(hex_id) trade_codes[i] = 'O:{}'.format(owner) owned = True if owned: self.hexes[hex_id].mainworld.trade_codes = trade_codes
class Planet(object): '''Planet object''' starport_table = Table() starport_table.add_row((2, 4), 'A') starport_table.add_row((5, 6), 'B') starport_table.add_row((7, 8), 'C') starport_table.add_row((9), 'D') starport_table.add_row((10, 11), 'E') starport_table.add_row(12, 'X') starport_table.dice = 2 spaceport_table = Table() spaceport_table.add_row((0), 'Y') spaceport_table.add_row((1, 2), 'H') spaceport_table.add_row(3, 'G') spaceport_table.add_row((4, 6), 'F') mw_type_flux_table = Table() mw_type_flux_table.add_row((-5, -4), 'Far Satellite') mw_type_flux_table.add_row(-3, 'Close Satellite') mw_type_flux_table.add_row((-2, 5), 'Planet') parent_type_flux_table = Table() parent_type_flux_table.add_row((-5, 0), 'Gas Giant') parent_type_flux_table.add_row((1, 5), 'BigWorld') def __init__(self, system=None): self.starport = '?' self.size = uwp.Size() self.atmosphere = uwp.Atmosphere() self.hydrographics = uwp.Hydrographics() self.biosphere = uwp.Biosphere() self.population = uwp.Population() self.government = uwp.Government() self.law_level = uwp.LawLevel() self.tech_level = uwp.TechLevel() self.trade_codes = [] self.travel_code = '' self.bases = '' self.is_mainworld = True self.orbit = '' self.system = system self.mainworld_type = None self.parent_type = None self.orbit_around_parent = None self.determine_starport() self.determine_size() self.determine_atmosphere() self.determine_hydrographics() self.determine_population() self.determine_government() self.determine_law() self.determine_tech() # self.determine_trade_codes() self.determine_mainworld_type() def __str__(self): return self.uwp() def uwp(self): '''UPP''' return '{}{}{}{}{}{}{}-{}'.format( self.starport, str(self.size), str(self.atmosphere), str(self.hydrographics), str(self.population), str(self.government), str(self.law_level), str(self.tech_level), ) def display_trade_codes(self): '''Display method - UPP + other stuff''' return '{}'.format( ' '.join(self.trade_codes), ) def determine_starport(self): '''Set starport''' self.starport = self.starport_table.roll() def determine_size(self): '''Set size''' roll = D6.roll(2, -2) if roll >= 10: roll = D6.roll(1, 9) self.size = uwp.Size(roll) def determine_atmosphere(self): '''Set atmosphere''' roll = FLUX.flux() + int(self.size) if roll < 0 or int(self.size) == 0: roll = 0 if roll > 15: roll = 15 self.atmosphere = uwp.Atmosphere(roll) def determine_hydrographics(self): '''Set hydrographics''' mods = 0 if int(self.atmosphere) < 2 or int(self.atmosphere) > 9: mods -= 4 roll = FLUX.flux() + int(self.atmosphere) + mods if int(self.size) < 2: roll = 0 roll = max(0, roll) roll = min(10, roll) self.hydrographics = uwp.Hydrographics(roll) def determine_population(self): '''Set population''' roll = D6.roll(2, -2) if roll == 10: roll = D6.roll(2, 3) self.population = uwp.Population(roll) def determine_government(self): '''Set government''' roll = FLUX.flux() + int(self.population) roll = min(roll, 15) roll = max(roll, 0) self.government = uwp.Government(roll) def determine_law(self): '''Set law level''' roll = FLUX.flux() + int(self.government) roll = min(roll, 18) roll = max(roll, 0) self.law_level = uwp.LawLevel(roll) def determine_tech(self): '''Set tech level''' mod = 0 mod += self._mod_starport() mod += self._mod_physical() mod += self._mod_population() LOGGER.debug('determine_tech(): mod = %s', mod) roll = D6.roll(1, mod, floor=0) LOGGER.debug('TL result = %s', roll) self.tech_level = uwp.TechLevel(roll) def _mod_starport(self): '''TL mods for starport''' mod = 0 if self.starport == 'A': mod += 6 elif self.starport == 'B': mod += 4 elif self.starport == 'C': mod += 2 elif self.starport == 'X': mod -= 4 elif self.starport == 'F': mod += 1 LOGGER.debug('Starport = %s TL DM = %s', str(self.starport), mod) return mod def _mod_physical(self): '''TL mods for physical profile values''' mod = 0 # Size if str(self.size) in '01': mod += 2 elif str(self.size) in '234': mod += 1 # Atmosphere if str(self.atmosphere) in '0123ABCDEF': mod += 1 # Hydrographics if str(self.hydrographics) == '9': mod += 1 elif str(self.hydrographics) == 'A': mod += 2 LOGGER.debug('Physical TL DM = %s', mod) return mod def _mod_population(self): ''' TL mods for population-related profile values''' mod = 0 # Population if str(self.population) in '12345': mod += 1 elif str(self.population) == '9': mod += 2 elif str(self.population) in 'ABCDEF': mod += 4 # Government if str(self.government) in '05': mod += 1 elif str(self.government) == 'D': mod -= 2 LOGGER.debug('Population TL DM = %s', mod) return mod def determine_trade_codes(self): '''Set trade codes''' if self.system is not None: tcs = TradeCodes(self, self.system) else: tcs = TradeCodes(self) self.trade_codes = tcs.generate() def as_json(self): '''Return JSON representation''' planet = { 'uwp': self.uwp(), 'trade_codes': self.trade_codes, 'travel_code': self.travel_code, 'bases': self.bases, 'is_mainworld': self.is_mainworld, 'orbit': self.orbit, 'mainworld_type': self.mainworld_type, 'parent_type': self.parent_type, 'orbit_around_parent': self.orbit_around_parent } return json.dumps(planet) def json_import(self, jdata): '''Import from JSON''' planet = json.loads(jdata) self.trade_codes = planet['trade_codes'] self.travel_code = planet['travel_code'] self.bases = planet['bases'] self.is_mainworld = planet['is_mainworld'] self.orbit = planet['orbit'] self._load_uwp(planet['uwp']) self.mainworld_type = planet['mainworld_type'] self.parent_type = planet['parent_type'] self.orbit_around_parent = planet['orbit_around_parent'] def _load_uwp(self, uwp_data): '''Set planetary data from UWP''' try: self.starport = str(uwp_data[0]) self.size = uwp.Size(str(uwp_data[1])) self.atmosphere = uwp.Atmosphere(str(uwp_data[2])) self.hydrographics = uwp.Hydrographics(str(uwp_data[3])) self.population = uwp.Population(str(uwp_data[4])) self.government = uwp.Government(str(uwp_data[5])) self.law_level = uwp.LawLevel(str(uwp_data[6])) self.tech_level = uwp.TechLevel(str(uwp_data[8])) except (IndexError, ValueError): raise ValueError('Invalid UWP {}'.format(uwp_data)) def determine_mainworld_type(self): '''Determine if satellite (and type) or planet''' close_orbits = ['Ay', 'Bee', 'Cee', 'Dee', 'Ee', 'Eff', 'Gee', 'Aitch', 'Eye', 'Jay', 'Kay', 'Ell', 'Em'] far_orbits = ['En', 'Oh', 'Pee', 'Que', 'Arr', 'Ess', 'Tee', 'Yu', 'Vee', 'Dub', 'Ex', 'Wye', 'Zee'] LOGGER.debug('UWP = %s', self.uwp()) if int(self.size) == 0: # Asteroid belt => planet LOGGER.debug('Planet is belt => mainworld_type = Planet') self.mainworld_type = 'Planet' else: flux = FLUX.flux() LOGGER.debug('Flux roll is %s', flux) self.mainworld_type = self.mw_type_flux_table.lookup(flux) LOGGER.debug('Mainworld type is %s', self.mainworld_type) if self.mainworld_type == 'Planet': self.parent_world = None self.orbit_around_parent = None elif self.mainworld_type == 'Close Satellite': self.trade_codes.append('Lk') self.parent_type = self.parent_type_flux_table.lookup(FLUX.flux()) roll = FLUX.flux() if self.parent_type == 'Gas Giant': roll -= 2 roll = max(roll, -6) roll = min(roll, 6) self.orbit_around_parent = close_orbits[roll + 6] elif self.mainworld_type == 'Far Satellite': self.trade_codes.append('Sa') self.parent_type = self.parent_type_flux_table.lookup(FLUX.flux()) roll = FLUX.flux() if self.parent_type == 'Gas Giant': roll -= 2 roll = max(roll, -6) roll = min(roll, 6) self.orbit_around_parent = far_orbits[roll + 6]
class _Star(object): '''Star base class''' # Spectral type spectral_type_table = Table() spectral_type_table.add_row(-6, 'OB') spectral_type_table.add_row((-5, -4), 'A') spectral_type_table.add_row((-3, -2), 'F') spectral_type_table.add_row((-1, 0), 'G') spectral_type_table.add_row((1, 2), 'K') spectral_type_table.add_row((3, 5), 'M') spectral_type_table.add_row((6, 8), 'BD') size_o_table = Table() size_o_table.add_row((-6, -5), 'Ia') size_o_table.add_row(-4, 'Ib') size_o_table.add_row(-3, 'II') size_o_table.add_row((-2, 0), 'III') size_o_table.add_row((1, 3), 'V') size_o_table.add_row(4, 'IV') size_o_table.add_row(5, 'D') size_o_table.add_row((6, 8), 'IV') # Size size_b_table = Table() size_b_table.add_row((-6, -5), 'Ia') size_b_table.add_row(-4, 'Ib') size_b_table.add_row(-3, 'II') size_b_table.add_row((-2, 1), 'III') size_b_table.add_row((2, 3), 'V') size_b_table.add_row(4, 'IV') size_b_table.add_row(5, 'D') size_b_table.add_row((6, 8), 'IV') size_a_table = Table() size_a_table.add_row((-6, -5), 'Ia') size_a_table.add_row(-4, 'Ib') size_a_table.add_row(-3, 'II') size_a_table.add_row(-2, 'III') size_a_table.add_row(-1, 'IV') size_a_table.add_row((0, 4), 'V') size_a_table.add_row(5, 'D') size_a_table.add_row((6, 8), 'V') size_f_table = Table() size_f_table.add_row((-6, -5), 'II') size_f_table.add_row(-4, 'III') size_f_table.add_row(-3, 'IV') size_f_table.add_row((-2, 3), 'V') size_f_table.add_row(4, 'VI') size_f_table.add_row(5, 'D') size_f_table.add_row((6, 8), 'VI') size_g_table = Table() size_g_table.add_row((-6, -5), 'II') size_g_table.add_row(-4, 'III') size_g_table.add_row(-3, 'IV') size_g_table.add_row((-2, 3), 'V') size_g_table.add_row(4, 'VI') size_g_table.add_row(5, 'D') size_g_table.add_row((6, 8), 'VI') size_k_table = Table() size_k_table.add_row((-6, -5), 'II') size_k_table.add_row(-4, 'III') size_k_table.add_row(-3, 'IV') size_k_table.add_row((-2, 3), 'V') size_k_table.add_row(4, 'VI') size_k_table.add_row(5, 'D') size_k_table.add_row((6, 8), 'VI') size_m_table = Table() size_m_table.add_row((-6, -3), 'II') size_m_table.add_row(-2, 'III') size_m_table.add_row((-1, 3), 'V') size_m_table.add_row(4, 'VI') size_m_table.add_row(5, 'D') size_m_table.add_row((6, 8), 'VI') # Habitable zone hz_orbit_o_table = Table() hz_orbit_o_table.add_row('Ia', 15) hz_orbit_o_table.add_row('Ib', 15) hz_orbit_o_table.add_row('II', 14) hz_orbit_o_table.add_row('III', 13) hz_orbit_o_table.add_row('IV', 12) hz_orbit_o_table.add_row('V', 11) hz_orbit_o_table.add_row('D', 1) hz_orbit_b_table = Table() hz_orbit_b_table.add_row('Ia', 13) hz_orbit_b_table.add_row('Ib', 13) hz_orbit_b_table.add_row('II', 12) hz_orbit_b_table.add_row('III', 11) hz_orbit_b_table.add_row('IV', 10) hz_orbit_b_table.add_row('V', 9) hz_orbit_b_table.add_row('D', 0) hz_orbit_a_table = Table() hz_orbit_a_table.add_row('Ia', 12) hz_orbit_a_table.add_row('Ib', 11) hz_orbit_a_table.add_row('II', 9) hz_orbit_a_table.add_row('III', 7) hz_orbit_a_table.add_row('IV', 7) hz_orbit_a_table.add_row('V', 7) hz_orbit_a_table.add_row('D', 0) hz_orbit_f_table = Table() hz_orbit_f_table.add_row('Ia', 11) hz_orbit_f_table.add_row('Ib', 10) hz_orbit_f_table.add_row('II', 9) hz_orbit_f_table.add_row('III', 6) hz_orbit_f_table.add_row('IV', 6) hz_orbit_f_table.add_row('V', 5) hz_orbit_f_table.add_row('VI', 3) hz_orbit_f_table.add_row('D', 0) hz_orbit_g_table = Table() hz_orbit_g_table.add_row('Ia', 12) hz_orbit_g_table.add_row('Ib', 10) hz_orbit_g_table.add_row('II', 9) hz_orbit_g_table.add_row('III', 7) hz_orbit_g_table.add_row('IV', 5) hz_orbit_g_table.add_row('V', 3) hz_orbit_g_table.add_row('VI', 2) hz_orbit_g_table.add_row('D', 0) hz_orbit_k_table = Table() hz_orbit_k_table.add_row('Ia', 12) hz_orbit_k_table.add_row('Ib', 10) hz_orbit_k_table.add_row('II', 9) hz_orbit_k_table.add_row('III', 8) hz_orbit_k_table.add_row('IV', 5) hz_orbit_k_table.add_row('V', 2) hz_orbit_k_table.add_row('VI', 1) hz_orbit_k_table.add_row('D', 0) hz_orbit_m_table = Table() hz_orbit_m_table.add_row('Ia', 12) hz_orbit_m_table.add_row('Ib', 11) hz_orbit_m_table.add_row('II', 10) hz_orbit_m_table.add_row('III', 0) hz_orbit_m_table.add_row('V', 0) hz_orbit_m_table.add_row('VI', 0) hz_orbit_m_table.add_row('D', 0) def __init__(self): self.spectral_type = '' self.decimal = 0 self.size = '' self.companion = None self.primary_rolls = {} self.habitable_zone = '' def __str__(self): return self.code() def code(self): '''Return spec type, decimal, size for this star only''' if self.spectral_type == 'BD': return 'BD' elif self.size == 'D': return 'D' else: return '{}{} {}'.format( self.spectral_type, self.decimal, self.size) def display(self): '''Combine spectral type, decimal, size''' resp = [str(self)] if self.companion is not None: resp.append(str(self.companion)) return ' '.join(resp) def set_decimal(self): '''Set spectral decimal''' if self.spectral_type == 'F' and self.size == 'VI': self.decimal = D5.roll(1, -1) else: self.decimal = D10.roll(1, -1) def has_companion(self): '''Companion star?''' if FLUX.flux() >= 3: LOGGER.debug('Companion exists') self.companion = Secondary(self.primary_rolls) def json_import(self, jdata): '''Import from JSON''' LOGGER.setLevel(logging.ERROR) star_dict = json.loads(jdata) self.decimal = star_dict['decimal'] self.habitable_zone = star_dict['habitable_zone'] self.spectral_type = star_dict['spectral_type'] self.size = star_dict['size'] if star_dict['companion'] is not None: self.companion = Secondary({'Spectral type': 3, 'Size': 3}) self.companion.json_import(star_dict['companion']) else: self.companion = None def set_hz(self): '''Set habitable zone orbit''' if self.spectral_type == 'O': self.habitable_zone = self.hz_orbit_o_table.lookup(self.size) elif self.spectral_type == 'B': self.habitable_zone = self.hz_orbit_b_table.lookup(self.size) elif self.spectral_type == 'A': self.habitable_zone = self.hz_orbit_a_table.lookup(self.size) elif self.spectral_type == 'F': self.habitable_zone = self.hz_orbit_f_table.lookup(self.size) elif self.spectral_type == 'G': self.habitable_zone = self.hz_orbit_g_table.lookup(self.size) elif self.spectral_type == 'K': self.habitable_zone = self.hz_orbit_k_table.lookup(self.size) elif self.spectral_type == 'M': self.habitable_zone = self.hz_orbit_m_table.lookup(self.size)