Skip to content

Commit

Permalink
Move universe data tables into Python.
Browse files Browse the repository at this point in the history
There's no point in loading the information from a text file and sending
it from C++ to Python, when it can just be in the Python files to begin
with.

I didn't port over the planet type adjustments since

* They weren't used;
* Most of them were all 0s
* I don't see any point in having a type adjustment; it just arbitrarily
  favours some species with certain habitabilities.

Of course, if someone wants to add them back it will just be a matter of
adjusting the Python code now.

I've only tested compilation on MSVC2013, so someone checking if the
changes to the other build processes worked would be appreciated.
  • Loading branch information
wheals authored and Vezzra committed Sep 23, 2015
1 parent 108f75c commit 125203f
Show file tree
Hide file tree
Showing 34 changed files with 193 additions and 428 deletions.
2 changes: 0 additions & 2 deletions CMakeLists.txt
Expand Up @@ -171,7 +171,6 @@ set (freeorioncommon_HEADER
universe/ValueRefFwd.h
util/AppInterface.h
util/blocking_combiner.h
util/DataTable.h
util/Directories.h
util/EnumText.h
util/i18n.h
Expand Down Expand Up @@ -231,7 +230,6 @@ set (freeorioncommon_SOURCE
universe/UniverseObject.cpp
universe/ValueRef.cpp
util/AppInterface.cpp
util/DataTable.cpp
util/Directories.cpp
util/EnumText.cpp
util/i18n.cpp
Expand Down
6 changes: 0 additions & 6 deletions Xcode/FreeOrion.xcodeproj/project.pbxproj
Expand Up @@ -165,7 +165,6 @@
471032600CEF6D0D00A7DF2B /* ServerFSM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 471030470CEF569200A7DF2B /* ServerFSM.cpp */; };
471033860CEF721B00A7DF2B /* PythonAI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47102FA00CEF562700A7DF2B /* PythonAI.cpp */; };
4710338A0CEF723900A7DF2B /* AIInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47102F9E0CEF562700A7DF2B /* AIInterface.cpp */; };
47103BF00CF04E5900A7DF2B /* DataTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 471D5D1C0A98A3F900DA9C21 /* DataTable.cpp */; };
47103BF20CF04E5900A7DF2B /* MultiplayerCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 471D5D270A98A3F900DA9C21 /* MultiplayerCommon.cpp */; };
47103BF30CF04E5900A7DF2B /* OptionsDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 471D5D290A98A3F900DA9C21 /* OptionsDB.cpp */; };
47103BF40CF04E5900A7DF2B /* Order.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 471D5D2C0A98A3F900DA9C21 /* Order.cpp */; };
Expand Down Expand Up @@ -793,8 +792,6 @@
471D5D190A98A3F900DA9C21 /* AppInterface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppInterface.h; sourceTree = "<group>"; };
471D5D1A0A98A3F900DA9C21 /* binreloc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = binreloc.c; sourceTree = "<group>"; };
471D5D1B0A98A3F900DA9C21 /* binreloc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = binreloc.h; sourceTree = "<group>"; };
471D5D1C0A98A3F900DA9C21 /* DataTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DataTable.cpp; sourceTree = "<group>"; };
471D5D1D0A98A3F900DA9C21 /* DataTable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DataTable.h; sourceTree = "<group>"; };
471D5D1E0A98A3F900DA9C21 /* Directories.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Directories.cpp; sourceTree = "<group>"; };
471D5D1F0A98A3F900DA9C21 /* Directories.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Directories.h; sourceTree = "<group>"; };
471D5D210A98A3F900DA9C21 /* Doxyfile */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Doxyfile; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1774,8 +1771,6 @@
471D5D1A0A98A3F900DA9C21 /* binreloc.c */,
471D5D1B0A98A3F900DA9C21 /* binreloc.h */,
471D5CF60A98A3F900DA9C21 /* blocking_combiner.h */,
471D5D1C0A98A3F900DA9C21 /* DataTable.cpp */,
471D5D1D0A98A3F900DA9C21 /* DataTable.h */,
471D5D1E0A98A3F900DA9C21 /* Directories.cpp */,
471D5D1F0A98A3F900DA9C21 /* Directories.h */,
471D5D200A98A3F900DA9C21 /* doc */,
Expand Down Expand Up @@ -2357,7 +2352,6 @@
34C449601182716E0071E09A /* SerializeMultiplayerCommon.cpp in Sources */,
34C449611182716E0071E09A /* SerializeOrderSet.cpp in Sources */,
34C449631182716E0071E09A /* SerializeUniverse.cpp in Sources */,
47103BF00CF04E5900A7DF2B /* DataTable.cpp in Sources */,
47103BF20CF04E5900A7DF2B /* MultiplayerCommon.cpp in Sources */,
47103BF30CF04E5900A7DF2B /* OptionsDB.cpp in Sources */,
47103BF40CF04E5900A7DF2B /* Order.cpp in Sources */,
Expand Down
3 changes: 2 additions & 1 deletion default/python/universe_generation/galaxy.py
Expand Up @@ -4,6 +4,7 @@

import freeorion as fo
import util
import universe_tables


# tuple of galaxy shapes to randomly choose from when shape is "random"
Expand Down Expand Up @@ -353,7 +354,7 @@ def irregular_galaxy_calc_positions(positions, size, width):
Calculate positions for the irregular galaxy shape.
"""
adjacency_grid = AdjacencyGrid(width)
max_delta = max(min(float(fo.max_starlane_length()), width / 10.0), adjacency_grid.min_dist * 2.0)
max_delta = max(min(float(universe_tables.MAX_STARLANE_LENGTH), width / 10.0), adjacency_grid.min_dist * 2.0)
print "Irregular galaxy shape: max delta distance =", max_delta
origin_x, origin_y = width / 2.0, width / 2.0
prev_x, prev_y = origin_x, origin_y
Expand Down
9 changes: 4 additions & 5 deletions default/python/universe_generation/monsters.py
Expand Up @@ -2,6 +2,7 @@
import freeorion as fo
import util
import statistics
import universe_tables


def generate_monsters(monster_freq, systems):
Expand All @@ -12,12 +13,10 @@ def generate_monsters(monster_freq, systems):
# first, calculate the basic chance for monster generation in a system
# based on the monster frequency that has been passed
# get the corresponding value for the specified monster frequency from the universe tables
inverse_monster_chance = fo.monster_frequency(monster_freq)
# 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 monsters, in this case return immediately
if inverse_monster_chance <= 0:
basic_chance = universe_tables.MONSTER_FREQUENCY[monster_freq]
# a value of 0 means no monsters, in this case return immediately
if basic_chance <= 0:
return
basic_chance = 1.0 / float(inverse_monster_chance)
print "Default monster spawn chance:", basic_chance
expectation_tally = 0.0
actual_tally = 0
Expand Down
9 changes: 4 additions & 5 deletions default/python/universe_generation/natives.py
Expand Up @@ -4,6 +4,7 @@

import planets
import statistics
import universe_tables

natives_for_planet_type = {}
planet_types_for_natives = {}
Expand All @@ -28,12 +29,10 @@ def generate_natives(native_freq, systems, empire_home_systems):

# first, calculate the chance for natives on a planet based on the native frequency that has been passed
# get the corresponding value for the specified natives frequency from the universe tables
inverse_native_chance = fo.native_frequency(native_freq)
# 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:
native_chance = universe_tables.NATIVE_FREQUENCY[native_freq]
# a value of 0 means no natives, in this case return immediately
if native_chance <= 0:
return
native_chance = 1.0 / float(inverse_native_chance)

# compile a list of planets where natives can be placed
# select only planets sufficiently far away from player home systems
Expand Down
22 changes: 8 additions & 14 deletions default/python/universe_generation/planets.py
Expand Up @@ -2,6 +2,7 @@
import random
import freeorion as fo
import util
import universe_tables as tables


# tuple of all valid planet sizes (with "no world")
Expand Down Expand Up @@ -39,17 +40,17 @@ def calc_planet_size(star_type, orbit, planet_density, galaxy_shape):
max_roll = 0
for candidate in planet_sizes_all:
roll = random.randint(1, 100) \
+ fo.density_mod_to_planet_size_dist(planet_density, candidate) \
+ fo.star_type_mod_to_planet_size_dist(star_type, candidate) \
+ fo.orbit_mod_to_planet_size_dist(orbit, candidate) \
+ fo.galaxy_shape_mod_to_planet_size_dist(galaxy_shape, candidate)
+ tables.DENSITY_MOD_TO_PLANET_SIZE_DIST[planet_density][candidate] \
+ tables.STAR_TYPE_MOD_TO_PLANET_SIZE_DIST[star_type][candidate] \
+ tables.ORBIT_MOD_TO_PLANET_SIZE_DIST[orbit][candidate] \
+ tables.GALAXY_SHAPE_MOD_TO_PLANET_SIZE_DIST[galaxy_shape][candidate]
if max_roll < roll:
max_roll = roll
planet_size = candidate
except:
# in case of an error play save and set planet size to invalid
# in case of an error play it safe and set planet size to invalid
planet_size = fo.planetSize.unknown
util.report_error("Python calc_planet_size: Pick planet size failed\n" + sys.exc_info()[1])
util.report_error("Python calc_planet_size: Pick planet size failed" + str(sys.exc_info()[1]))

# if we got an invalid planet size (for whatever reason),
# just select one randomly from the global tuple based
Expand All @@ -65,14 +66,7 @@ def calc_planet_size(star_type, orbit, planet_density, galaxy_shape):

def calc_planet_type(star_type, orbit, planet_size):
"""
Calculate planet type for a potential new planet.
TEMP: For now, pick planet type randomly, unless it is required by size
TODO: Consider using the universe tables that modify planet type again,
this has been (temporarily?) disabled in C code. But the respective
tables are there, the Python interface to them is in place, and
this function is already prepared to take all necessary parameters.
So if anyone feels like experimenting, go for it... :)
Calculate planet type randomly for a potential new planet.
"""

# check specified planet size to determine if we want a planet at all
Expand Down
4 changes: 2 additions & 2 deletions default/python/universe_generation/specials.py
@@ -1,6 +1,7 @@
import random
import freeorion as fo
import statistics
import universe_tables


def distribute_specials(specials_freq, universe_objects):
Expand All @@ -9,8 +10,7 @@ def distribute_specials(specials_freq, universe_objects):
"""

# get basic chance for occurrence of specials from the universe tables
# the values there are integers, so we have to divide them by 10,000 to get the actual basic probability value
basic_chance = float(fo.specials_frequency(specials_freq)) / 10000.0
basic_chance = universe_tables.SPECIALS_FREQUENCY[specials_freq]
if basic_chance <= 0:
return

Expand Down
5 changes: 3 additions & 2 deletions default/python/universe_generation/starsystems.py
Expand Up @@ -3,6 +3,7 @@
import freeorion as fo
import planets
import util
import universe_tables


# tuple of available star types
Expand All @@ -26,8 +27,8 @@ def pick_star_type(galaxy_age):
max_roll = 0
for candidate in star_types:
roll = random.randint(1, 100) \
+ fo.universe_age_mod_to_star_type_dist(galaxy_age, candidate) \
+ fo.base_star_type_dist(candidate)
+ universe_tables.UNIVERSE_AGE_MOD_TO_STAR_TYPE_DIST[galaxy_age][candidate] \
+ universe_tables.BASE_STAR_TYPE_DIST[candidate]
if max_roll < roll:
max_roll = roll
star_type = candidate
Expand Down
15 changes: 7 additions & 8 deletions default/python/universe_generation/statistics.py
@@ -1,6 +1,7 @@
import freeorion as fo
import planets
import natives
import universe_tables


species_summary = {species: 0 for species in fo.get_native_species()}
Expand Down Expand Up @@ -59,13 +60,12 @@ def log_species_summary():
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))
native_chance = universe_tables.NATIVE_FREQUENCY[fo.get_galaxy_setup_data().nativeFrequency]
# 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:
# a value of 0 means no natives, in this case return immediately
if native_chance <= 0:
return
print "Natives Placement Summary (native frequency: %.1f%%)" % (100 * native_chance)
native_potential_planet_total = sum(potential_native_planet_summary.values())
for species in species_summary:
if species_summary[species] > 0:
Expand All @@ -80,7 +80,7 @@ def log_species_summary():
100.0 * species_summary[species] / (1E-10 + 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 "Planet Type Summary for Native Planets (native frequency: %.1f%%)" % (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():
Expand All @@ -95,8 +95,7 @@ def log_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)
monster_chance = universe_tables.MONSTER_FREQUENCY[fo.get_galaxy_setup_data().monsterFrequency]
# 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" %\
Expand Down
3 changes: 2 additions & 1 deletion default/python/universe_generation/universe_generator.py
Expand Up @@ -11,6 +11,7 @@
from monsters import generate_monsters
from specials import distribute_specials
from util import int_hash, seed_rng, report_error, error_list
from universe_tables import MAX_JUMPS_BETWEEN_SYSTEMS, MAX_STARLANE_LENGTH
import statistics


Expand Down Expand Up @@ -59,7 +60,7 @@ def create_universe(psd_map):

# generate Starlanes
seed_rng(seed_pool.pop())
fo.generate_starlanes(gsd.starlaneFrequency)
fo.generate_starlanes(MAX_JUMPS_BETWEEN_SYSTEMS[gsd.starlaneFrequency], MAX_STARLANE_LENGTH)
print "Starlanes generated"

print "Compile list of home systems..."
Expand Down

0 comments on commit 125203f

Please sign in to comment.