Browse Source

First commit

main
Jonathan Humphreys 10 years ago
commit
f8f9082992
  1. 1
      classes/__init__.py
  2. 216
      classes/star.py
  3. 88
      galaxy_generator.py

1
classes/__init__.py

@ -0,0 +1 @@

216
classes/star.py

@ -0,0 +1,216 @@
from math import floor
from os import system, name
class Star(object):
def __init__(self, star_bins):
self.x = self.set_basic(star_bins[1][:8]) # X coordinate on the map.
self.y = self.set_basic(star_bins[0][:8]) # Y coordinate on the map.
self.radius_x = self.set_radius(star_bins[2][4:8]) # Radius of the planet in km (not really used beyond flavour text?).
self.gov = self.set_basic(star_bins[1][10:13]) # Government type.
self.eco = int(self.set_eco(star_bins[0][5:8])) # Economy type.
# The positions on the digram string, from which 3 or 4 digrams will be extracted.
self.digrams = self.set_digrams(star_bins[0][9:10], [star_bins[2][3:8], star_bins[3][3:8], star_bins[4][3:8], star_bins[5][3:8]])
# The dominant inhabitants on this planet.
self.inhabitants = self.set_inhabitants([star_bins[2][3:6], star_bins[2][0:3], [star_bins[0], star_bins[1]], star_bins[2][6:8]])
# Has this world been colonised by humans?
self.humans = self.set_humans(star_bins[2][8:])
self.tech_level = self.set_tech_level([star_bins[0], star_bins[1]]) # Level of technological advancement on the planet.
self.population = self.set_population() # Population of inhabitants, in billions.
self.production = self.set_production([star_bins[0], star_bins[1]]) # Production rate of the planet, in Mcr (whatever that is).
# -----------------------------------------------------------------------------------
# Methods to retrieve data from star_bins and use them in the various calculations
# made to determine each star's data.
# -----------------------------------------------------------------------------------
# Method for setting the value of a property if all that is needed is to convert
# the extracted binary to an integer.
# Used by x, y and gov.
def set_basic(self, binary_extract):
return int("0b" + binary_extract, 2)
# Converts a binary value to integer and uses it to calculate the radius of a planet
# in km.
def set_radius(self, binary_extract):
modifier = int("0b" + binary_extract, 2)
return 256 * (11 + modifier) + self.x
# Converts a binary value to integer. If gov is less than 2, does maths on it.
# Otherwise, just returns the vanilla converted value.
def set_eco(self, binary_extract):
eco = int("0b" + binary_extract, 2)
if self.gov < 2:
return floor(eco / 4) * 4 + 2 + (eco % 2)
else:
return eco
# Determines the number of digrams with which to construct a planet name (3 or 4).
# Then returns a list of values.
def set_digrams(self, digram_count_binary, digram_binaries):
digram_count = int("0b" + digram_count_binary, 2) + 3
digrams = [] # List to which digrams will be appended to and returned.
for digram in range(0, digram_count):
digrams.append(int("0b" + digram_binaries[digram], 2) * 2)
return digrams
# Assembles a list of values with which to construct a description of a planet's
# inhabitants, and returns it.
def set_inhabitants(self, binary_extracts):
inhabitants = [None] * 4 # List to which inhabitant description values will be appended to and returned.
extract_values = [None] * 2 # Stores the integer versions of the values stored in binary_extracts.
# Ensures the first and second description values cannot exceed 3 and 6,
# respectively, since these values are used in list lookups.
inhabitants[0] = min([int("0b" + binary_extracts[0], 2), 3])
inhabitants[1] = min([int("0b" + binary_extracts[1], 2), 6])
third_attribute = 0 # Calculated value used as the third description value and to calculate the fourth.
for step in range(3):
# Start and end positions for list slicing. In each iteraction of step,
# the for loop ahead takes one of the last three bits of the highest
# significant byte, last bit first, and converts it to int.
binary_start = 8 - (step + 1)
binary_end = binary_start + 1
for val in range(2):
extract_values[val] = int("0b" + binary_extracts[2][val][binary_start:binary_end], 2)
combined_values = (extract_values[0] + extract_values[1]) % 2
# If this isn't the first step, multiply the combined values by 2 or 4,
# respectively, before adding to third_attribute.
if step > 0:
combined_values *= (2*step)
third_attribute = third_attribute + combined_values
inhabitants[2] = min([third_attribute, 6]) # The third description value cannot exceed 6.
inhabitants[3] = (int("0b" + binary_extracts[3], 2) + third_attribute) % 8
return inhabitants
# Returns a true/false value with which to determine whether a planet has human
# colonists rather than a unique indigenous species.
def set_humans(self, binary_extract):
if int("0b" + binary_extract, 2) < 127:
return 1 # Human Colonists
else:
return 0 # Indigenous Species
# Calculates the technology level of the planet.
def set_tech_level(self, binary_extracts):
tl = self.get_tl_data(binary_extracts)
return float((1 - tl[0]) * 4 + (1 - tl[1]) * 2 + 1 - tl[2] + tl[3] + tl[4] + tl[5] + 1)
# Calculates the production rate of a planet. This depends on some of the data used
# to calculate tech_level.
def set_production(self, binary_extracts):
tl = self.get_tl_data(binary_extracts)
return ((1 - tl[0]) * 4 + (1 - tl[1]) * 2 + 1 - tl[2] + 3) * (self.gov + 4) * self.population * 80
# Converts the bits of data used in the calculation of both tech_level and production.
def get_tl_data(self, binary_extracts):
tl = [None] * 6
tl[0] = int("0b" + binary_extracts[0][5:6], 2)
tl[1] = int("0b" + binary_extracts[0][6:7], 2)
tl[2] = int("0b" + binary_extracts[0][7:8], 2)
tl[3] = int("0b" + binary_extracts[1][6:8], 2)
tl[4] = int("0b" + binary_extracts[1][10:12], 2)
tl[5] = int("0b" + binary_extracts[1][12:13], 2)
return tl
# Calculates the population of the planet, in billions. Relies on tech_level, gov
# and eco for this calculation.
def set_population(self):
return ((self.tech_level - 1) * 4 + self.gov + self.eco + 1) / 10
# -----------------------------------------------------------------------------------
# Methods to output a star's data onto the screen.
# -----------------------------------------------------------------------------------
# Outputs a star's data to screen.
def print_data(self, digram_string):
system("cls" if name == "nt" else "clear")
print "Name: " + self.get_star_name(digram_string)
print "Loc: " + str(self.x) + ":" + str(self.y)
print "Radius: " + str(self.radius_x) + " km"
print "Government: " + self.get_gov()
print "Economy: " + self.get_eco()
print "Inhabitants: " + self.get_inhabitants()
print "Tech Level: " + str(int(self.tech_level))
print "Population: " + str(self.population) + " Billion"
print "Production: " + str(int(self.production)) + " Mcr"
# Constructs the name of the planet, based on the values provided in the digrams
# list, and returns it.
def get_star_name(self, digram_string):
# The star's name, into which each digram extracted from digram_string will be
# concatenated before it is returned.
star_name = ""
for ind, digram in enumerate(self.digrams):
# Get the start and end positions within which to extract the two-letter
# digrams.
digram_start = digram
digram_end = digram_start + 2
# Find
star_name = star_name + digram_string[digram_start:digram_end]
# Remove instances of special characters from the star's name, further
# shortening the name and even producting odd-numbered name lengths.
star_name = star_name.replace("@","")
star_name = star_name.replace("'","")
return star_name
# Constructs and returns the inhabitant description for a planet as long as humans
# is set to 0. Otherwise just returns the phrase "Human Colonists".
def get_inhabitants(self):
if self.humans == 0:
inhabitants = ""
in_data = [["Large", "Fierce", "Small", ""],
["Green", "Red", "Yellow", "Blue", "Black", "Harmless", ""],
["Slimy", "Bug-Eyed", "Horned", "Bony", "Fat", "Furry", ""],
["Rodents", "Frogs", "Lizards", "Lobsters", "Birds", "Humanoids", "Felines", "Insects"]]
for ind, val in enumerate(self.inhabitants):
if not in_data[ind][val] == "":
inhabitants = inhabitants + in_data[ind][val]
if ind < 3:
inhabitants = inhabitants + " "
return inhabitants.strip()
else:
return "Human Colonists"
# Finds the government type that corresponds to the value of gov and returns it.
def get_gov(self):
governments = ["Anarchy", "Feudal", "Multi-Government", "Dictatorship", "Communist", "Confederacy", "Democracy", "Corporate State"]
return governments[self.gov]
# Finds the economy type that corresponds to the value of gov and returns it.
def get_eco(self):
economies = ["Rich Industrial", "Average Industrial", "Poor Industrial", "Mainly Industrial", "Mainly Agricultural", "Rich Agricultural", "Average Agricultural", "Poor Agricultural"]
return economies[self.eco]

88
galaxy_generator.py

@ -0,0 +1,88 @@
from classes.star import Star
# Seed values from which the galaxy will be constructed.
seed = [0x5A4A, 0x0248, 0xB753]
galaxy_seed = seed
#List to hold all the galaxies, represented as lists holding its stars as objects.
galaxies = []
star_bins = [] # Holds the six binary strings used to calculate a star's data.
seed_bin = "" # Used to hold the binary value of each seed value in order to perform a roll-left.
# Input variables used to look up a planet by its galaxy and star numbers.
galaxy_num = ""
star_num = ""
DIGRAM_STRING = "@@LEXEGEZACEBISOUSESARMAINDIREA'ERATENBERALAVETIEDORQUANTEISRION"
for galaxy in range(8):
# Adds a new list to galaxies, into which new stars will be added.
galaxies.append([])
# List holding each set of values that will make up each star and its properties.
star_twists = []
for star in range(256):
# If it's the first star, add the seed values, otherwise use the last three
# values from the last twist.
if star == 0:
star_twists.append(galaxy_seed[:])
else:
# First two values are the last two from the previous twist.
# Last one is the sum of the last twist's final three values modulo 65536.
star_twists.append(star_twists[star - 1][4:6])
star_twists[star].append(sum(star_twists[star - 1][3:6]) % 65536)
# Add the last three values to the current twist by taking the previous three
# values in the same twist modulo 65536.
for extra_twists in range(3,6):
star_twists[star].append(sum(star_twists[star][extra_twists - 3:extra_twists]) % 65536)
# Convert the values in the current twist to binary.
star_bins = []
for ind, new_bin in enumerate(star_twists[star]):
star_bins.append(bin(new_bin)[2:])
# Append leading zeros to ensure each binary string is 16 characters long.
star_bins[ind] = "0" * (16 - len(star_bins[ind])) + star_bins[ind]
# Add a new star object to the current galaxy, using the newly-converted binary
# strings to calculate its properties.
galaxies[galaxy].append(Star(star_bins))
# Perform an 8-bit roll-left operation on the seed values.
# Basically, in every 8 bits of each value, the first binary digit becomes the last
# binary digit.
for ind, seed_val in enumerate(galaxy_seed):
seed_bin = bin(seed_val)
seed_bin = "0" * (16 - len(seed_bin[2:])) + seed_bin[2:]
seed_bin = "0b" + seed_bin[1:8] + seed_bin[0] + seed_bin[9:16] + seed_bin[8]
galaxy_seed[ind] = int(seed_bin, 2)
# Get rid of now-redundant variables.
del star_twists
del star_bins
while not galaxy_num == -1:
try:
galaxy_num = int(raw_input("Enter galaxy number: "))
except ValueError:
print "Not a number."
continue
else:
if galaxy_num >= len(galaxies):
print "There aren't that many galaxies."
continue
try:
star_num = int(raw_input("Enter star number: "))
except ValueError:
print "Not a number."
continue
else:
if star_num >= len(galaxies[galaxy_num]):
print "There aren't that many stars."
continue
galaxies[galaxy_num][star_num].print_data(DIGRAM_STRING)
Loading…
Cancel
Save