def log_monsters_summary(): print "Space Monsters Placement Summary" for monster, counter in monsters_summary: if counter > 0: print "Placed space monster", monster, counter, "times" print inverse_monster_chance = fo.monster_frequency(fo.get_galaxy_setup_data().monsterFrequency) monster_chance = 1.0 / (1e-5 + inverse_monster_chance) # the following loop depends on name mapping done in monsters.py print "Tracked Monster and Nest Summary (base monster freq: %4.1f%%)" % (100 * monster_chance) print "%-18s | %8s | %8s | %8s | %12s | %s" %\ ("Monster", "chance", "# tried", "# placed", "# valid sys locs", "# valid nest planet locs") for monster in tracked_monsters_summary: print "%-18s | %5.2f | %4d | %4d | %4d | %4d" % (monster, tracked_monsters_chance[monster], tracked_monsters_tries[monster], tracked_monsters_summary[monster], tracked_monsters_location_summary[monster], tracked_nest_location_summary[monster])
def log_species_summary(): num_empires = sum(empire_species.values()) num_species = len(fo.get_playable_species()) exp_count = num_empires // num_species print "Empire Starting Species Summary for %d Empires and %d playable species" % (num_empires, num_species) print "Approximately %d to %d empires expected per species" % (max(0, exp_count - 1), exp_count + 1) print "%-16s : # -- %%" % ("species") for species, count in empire_species.items(): if count: print "%-16s : %3d -- %5.1f%%" % (species, count, 100.0 * count / num_empires) print inverse_native_chance = fo.native_frequency(fo.get_galaxy_setup_data().nativeFrequency) native_chance = 1.0 / (1e-5 + inverse_native_chance) print "Natives Placement Summary (native frequency: %.1f%%)" % (inverse_native_chance and (100 * native_chance)) # as the value in the universe table is higher for a lower frequency, we have to invert it # exception: a value of 0 means no natives, in this case return immediately if inverse_native_chance <= 0: return native_potential_planet_total = sum(potential_native_planet_summary.values()) for species in species_summary: if species_summary[species] > 0: settleable_planets = 0 expectation_tally = 0.0 for p_type in natives.planet_types_for_natives[species]: settleable_planets += potential_native_planet_summary[p_type] expectation_tally += native_chance * 100.0 * potential_native_planet_summary[p_type] / len(natives.natives_for_planet_type[p_type]) expectation = expectation_tally / settleable_planets print "Settled natives %18s on %3d planets -- %5.1f%% of total and %5.1f%% vs %5.1f%% (actual vs expected) of %s planets" % \ (species, species_summary[species], 100.0 * species_summary[species] / native_potential_planet_total, 100.0 * species_summary[species] / settleable_planets, expectation, [str(p_t) for p_t in natives.planet_types_for_natives[species]]) print native_settled_planet_total = sum(settled_native_planet_summary.values()) print "Planet Type Summary for Native Planets (native frequency: %.1f%%)" % (inverse_native_chance and (100 * native_chance)) print "%19s : %-s" % ("Potential (% of tot)", "Settled (% of potential)") print "%-13s %5d : %5d" % ("Totals", native_potential_planet_total, native_settled_planet_total) for planet_type, planet_count in potential_native_planet_summary.items(): settled_planet_count = settled_native_planet_summary.get(planet_type, 0) potential_percent = 100.0 * planet_count / native_potential_planet_total settled_percent = 100.0 * settled_planet_count / (1E-10 + planet_count) print "%-12s %5.1f%% : %5.1f%%" % (planet_type.name, potential_percent, settled_percent)
def create_universe(): """ Main universe generation function invoked from C++ code. """ print "Python Universe Generator" # fetch universe and player setup data gsd = fo.get_galaxy_setup_data() psd_list = fo.get_player_setup_data() total_players = len(psd_list) # initialize RNG seed_rng(gsd.seed) seed_pool = [random.random() for _ in range(100)] # make sure there are enough systems for the given number of players print "Universe creation requested with %d systems for %d players" % (gsd.size, total_players) size = max(gsd.size, (total_players * 3)) if size > gsd.size: # gsd.size = size print "Too few systems for the requested number of players, number of systems adjusted accordingly" print "Creating universe with %d systems for %d players" % (size, total_players) # calculate star system positions seed_rng(seed_pool.pop()) system_positions = calc_star_system_positions(gsd.shape, size) size = len(system_positions) print gsd.shape, "Star system positions calculated, final number of systems:", size # generate and populate systems seed_rng(seed_pool.pop()) systems = generate_systems(system_positions, gsd) print len(systems), "systems generated and populated" # generate Starlanes seed_rng(seed_pool.pop()) fo.generate_starlanes(gsd.starlaneFrequency) print "Starlanes generated" print "Compile list of home systems..." seed_rng(seed_pool.pop()) home_systems = compile_home_system_list(total_players, systems) if not home_systems: err_msg = "Python create_universe: couldn't get any home systems, ABORTING!" report_error(err_msg) raise Exception(err_msg) print "Home systems:", home_systems # set up empires for each player seed_rng(seed_pool.pop()) for psd_entry, home_system in zip(psd_list, home_systems): empire = psd_entry.key() psd = psd_entry.data() if not setup_empire(empire, psd.empire_name, home_system, psd.starting_species, psd.player_name): report_error("Python create_universe: couldn't set up empire for player %s" % psd.player_name) # assign names to all star systems and their planets # this needs to be done after all systems have been generated and empire home systems have been set, as # only after all that is finished star types as well as planet sizes and types are fixed, and the naming # process depends on that print "Assign star system names" seed_rng(seed_pool.pop()) name_star_systems(systems) print "Set planet names" for system in systems: name_planets(system) print "Generating Natives" seed_rng(seed_pool.pop()) generate_natives(gsd.nativeFrequency, systems, home_systems) print "Generating Space Monsters" seed_rng(seed_pool.pop()) generate_monsters(gsd.monsterFrequency, systems) print "Distributing Starting Specials" seed_rng(seed_pool.pop()) distribute_specials(gsd.specialsFrequency, fo.get_all_objects()) # finally, write some statistics to the log file print "############################################################" print "## Universe generation statistics ##" print "############################################################" statistics.log_planet_count_dist(systems) print "############################################################" statistics.log_planet_type_summary(systems) print "############################################################" statistics.log_species_summary() print "############################################################" statistics.log_monsters_summary() print "############################################################" statistics.log_specials_summary() print "############################################################" if error_list: print "Python Universe Generator completed with errors" return False else: print "Python Universe Generator completed successfully" return True