Пример #1
0
    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))
Пример #2
0
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