def __init__(self, game, generate=False): """ Not only is this the constructor for the `Galaxy` class, this also will generate a random `Galaxy` if and only if the correct and precise keyword arguments are passed in (hint: to generate a `Galaxy`, set `generate` to `True`). Args: game (Game): The `Game` which this `Galaxy` will be used for. Keyword Args: generate (boolean): Set to `True` if this `Galaxy` is to be generated at random. Note: It is the responsibility of the caller of this constructor to save this galaxy to disk. """ # Assign attributes. self.game = game # Escape gase. if not generate: return # Declare global variables. global GALAXY_START_JSON global GALAXY_DEFAULT_RANGE global GALAXY_LENGTH global GALAXY_WIDTH global GALAXY_HEIGHT global STARS_PER_CUBIC_LY # Open the JSON import os current_directory = os.path.dirname(__file__) json_f = open(current_directory+GALAXY_START_JSON) json_contents = json_f.read() data = json.loads(json_contents) json_f.close() # Append default systems. for system in data: # Parse the system dict and assign the system object a unique ID. self._system_unique_counter += 1 system_obj = system_lib.system_from_dict(system, game) system_obj.unique = self._system_unique_counter system_obj.galaxy = self # Assign the planets of this system unique identifiers system_planets = system_obj.flat_planets() for planet in system_planets: self._planet_unique_counter += 1 planet.unique = self._planet_unique_counter self.systems.append(system_obj) # The dimensions of the galaxy. adj_dim = lambda x: (x - 1) / 2 abs_sum = lambda x, y, z: abs(x) + abs(y) + abs(z) width = irange(-adj_dim(GALAXY_WIDTH), adj_dim(GALAXY_WIDTH)) length = irange(-adj_dim(GALAXY_LENGTH), adj_dim(GALAXY_LENGTH)) height = irange(-adj_dim(GALAXY_HEIGHT), adj_dim(GALAXY_HEIGHT)) positions = [(x, y, z) for x in width for y in length for z in height] gdr = GALAXY_DEFAULT_RANGE in_default_range = lambda x, y, z: (abs_sum(x, y, z) <= gdr) in_discover_range = lambda x, y, z: (abs_sum(x, y, z) <= gdr + 4) # Loop through the galatic grid. For the positions outside the range of # default systems, randomly create new ones. generated = 0 for (x, y, z) in positions: if in_default_range(x, y, z): continue elif coinflip(STARS_PER_CUBIC_LY): generated += 1 self._system_unique_counter += 1 new_sys = self._create_system(x, y, z) new_sys.unique = self._system_unique_counter if in_discover_range(x, y, z): new_sys.discovered_by = set(game.players) # Assign the new planets unique identifiers. new_sys_planets = new_sys.flat_planets() for planet in new_sys_planets: self._planet_unique_counter += 1 planet.unique = self._planet_unique_counter self.systems.append(new_sys) # Save to disk print "Generated {0} systems".format(str(generated))
def generate_system(name, scheme): """ Args: name (str): What we want to name this `System`. scheme (int): A system naming scheme code defined at the top of this module. Use `SYSTEM_SCHEME_SYLLABLES` to generate new names for planets. Use `SYSTEM_SCHEME_STAR` to name planets after `name` (for example, "Ceti Alpha V" and "Ceti Alpha VI"). Returns: A `System` generated at random. Notes: The `position` attribute of the returned `System` will not be set. """ # Declare global variables. global SYSTEM_MAX_PLANETS global SYSTEM_MIN_PLANETS # How many planets does this system have? num_planets = random.randint(SYSTEM_MIN_PLANETS, SYSTEM_MAX_PLANETS) # Generate a random spectral class. star_spectral_class = _random_spectral_class() # Now calculate the maximum and minimum distances planets can be between. min_orbit_dist = 0.1 max_orbit_dist = 30.0 # TODO # Calculate the orbiting distances between the planets. orbit_distances = [] for a in xrange(0, num_planets): distance = rand_float_range(min_orbit_dist, max_orbit_dist) orbit_distances.append(distance) orbit_distances.sort() # This is the probability of a planet being rocky as a function of its # orbital distance from its star. chance_rocky = lambda d: 0.5 # TODO # This is the probability of a planet being habitable GIVEN that it is # rocky as a function of its orbital distance. chance_habitable = lambda d: 0.25 # TODO # Begin creating the planets planets = [] a = 1 # used for iteration for distance in orbit_distances: planet_type = None # Case: Rocky or habitable planet if coinflip(chance_rocky(distance)): planet_type = planet_lib.RockyPlanet if coinflip(chance_habitable(distance)): planet_type = planet_lib.HabitablePlanet else: planet_type = planet_lib.GasPlanet planet = planet_type(orbit_distance=distance) # TODO setup planet planet.name = _planet_name(name, scheme, a) planets.append(planet) a += 1 # Setup the system that we will return system = System(name, star_spectral_class=star_spectral_class) return system