All pastes #432212 Raw Edit

Untitled

public text v1 · immutable
·published 2007-04-10 03:18 UTC
rendered paste body
# Fill out the information between the lines
#----------------------------------------------------------------------------------------

# prices at which your buildings will buy externally produced commodities
imports = {'food':250, 'water':220, 'energy':110, 'exotic matter':500, 'nebula gas':150, 'animal embryos':50}

# prices at which excess production will be sold by your buildings, if commodity isn't listed here, any excess is assumed to be dumped into space
exports = {'drugs':15000, 'droid modules':8000}

# Specify end building type/number. Generally you can't have equal profits in a sector that
# mixes two different industries. Specify one building type to get equal profit for all
# buildings in the industry. If you specify several end-level building types, you'll get equal
# profit for supporting buildings, but unequal profits for end-level buildings.
end_buildings = {'droid ass complex':1, 'battleweapon factory':1, 'weapon factory':1}

# level of your buildings
level = 6

# per-ton profit for traders doing upkeep (only for internally produced resources)
upkeep_profit = 150

# specifies how profit is divided between buildings 1/1/1/2 means illegal buildings get twice
# as much profit as all others
low_level_building_share = 1.
mid_level_building_share = 1.
high_level_building_share = 1.
illegal_building_share = 1

# --------------------------------------------------------------------------------------

from math import ceil
import sys

# initialize upkeep/production data
# building names
building_names = 'fuel collector','gas collector','space farm','energy well','chemical lab','asteroid mine','radiation collector','medical lab','brewerie','plastic facility','smelting facility','slave camp','optics research center','electronics facility','recycletron','clod generator','nebula plant','drug station','dark dome','weapon factory','battleweapon factory','robot factory','droid ass complex','leech nursery','military outpost','trade outpost'

low_level_buildings = ['fuel collector','gas collector','space farm','energy well','chemical lab','asteroid mine','radiation collector','nebula plant']
mid_level_buildings = ['medical lab','brewerie','plastic facility','smelting facility','optics research center','electronics facility','recycletron','clod generator']
high_level_buildings = ['weapon factory','battleweapon factory','robot factory','droid ass complex','leech nursery']
illegal_buildings = ['slave camp','drug station','dark dome']


# initialize profit factors
profit_factors = {}
for b in building_names:
  if b in low_level_buildings:
    profit_factors[b] = low_level_building_share
  elif b in mid_level_buildings:
    profit_factors[b] = mid_level_building_share
  elif b in high_level_buildings:
    profit_factors[b] = high_level_building_share
  elif b in illegal_buildings:
    profit_factors[b] = illegal_building_share

commodity_names = 'food','energy','water','animal embryos','ore','metal','electronics','robots','heavy plastics','weapons','medicines','nebula gas','chemical supplies','gem stones','optical components','liqour','hydrogen fuel','exotic matter','radioactive cells','droid modules','bio waste','slaves','drugs','nutrient clods','battleweapon parts','leech baby','body parts'

# increased profit for these buildings, because of additional factors (reputation loss, high construction cost, XP requirements)

# increased profit for trading with these commodities, ie dangerous route, or infrequent runs
trading_factors = {'exotic matter':2}

upkeep_s = """
,Food,,2,,1,1,1,1,2,2,2,2,3,1,1,,,2,3,,1,1,2,1,2,,,125,,,,100,150
,Energy,4,2,4,,3,1,3,2,2,2,2,1,3,4,3,4,,1,1,2,2,2,3,6,5,,,375,,375,125,250
,Water,,2,,1,1,1,1,2,2,2,2,3,1,1,,,2,3,,1,1,2,1,10,,,93.75,,125,,,100
,Animal Embryos,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Ore,,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,
,Metal,,,,,,,,,,,,,,3,,,,,,,3,1,,,,,,,,,,
,Electronics,,,,,,,,,,,,,,,,,,,,3,3,4,,,,,,,,,,
,Robots,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,
,Heavy Plastics,,,,,,,,,,,,,,2,,,,,,3,,,,,,,,,,,,
,Weapons,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Medicines,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,
,Nebula Gas,,,,,,,,7,,3,,,,,,,,,,,,,,,,,,,,,,
,Chemical Supplies,1,,,,,,,,4,3,,,,,1,4,,,,,,,,,,,,,,,,
,Gem Stones,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,25,,,
,Optical Components,,,,,,,,,,,,,,,,,,,,3,4,2,,,,,,,,,,
,Liqour,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,
,Hydrogen Fuel,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,,
,Exotic Matter,,,,,,,,,,,,,,,,,3,3,,,,,,,,,,,,,,
,Radioactive Cells,,,,,,,,,,,,,,,,,,,,,,,3,6,,,,,,,,
,Droid Modules,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Bio Waste,,,,,,,,,,,,,,,5,18,,,,,,,,,,,,,,,,
,Slaves,,,,,,,,,,,,,,,,,,3,2,,,,,,,,,,,,,
,Drugs,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Nutrient Clods,,,,,,,,,,,,,,,,,,,,,,,,40,,,,,,,,
,Battleweapon Parts,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Leech Baby,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
"""
production_s = """
,Food,,,8,,,,,,,,,,,,7,,,,,,,,,,,,,250,,,,
,Energy,,,,6,,,,,,,,,,,,,35,,,,,,,,,,187.5,,,,,
,Water,,,2,,,,,,,,,,,,5,,,,,,,,,,,,,312.5,,500,,
,Animal Embryos,,,,,,,,,,,,,,,,,,,,,,,,,,,62.5,31.25,,31.25,50,62.5
,Ore,,,,,,9,,,,,,,,,,,,,,,,,,,,,,,,,,75
,Metal,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,25
,Electronics,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,
,Robots,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,,,
,Heavy Plastics,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,
,Weapons,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,
,Medicines,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,
,Nebula Gas,,20,,,,,,,,,,,,,,,4,,,,,,,,,,,,,,250,
,Chemical Supplies,,,,,9,,,,,,,,,,,,,,,,,,,,,,,,,,25,
,Gem Stones,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,
,Optical Components,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,
,Liqour,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,
,Hydrogen Fuel,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Exotic Matter,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,Radioactive Cells,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,
,Droid Modules,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,
,Bio Waste,,,1,,,,,,,,,,,,,,,,4,,,,,3,,,,,,,,
,Slaves,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,6.25,,,
,Drugs,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,
,Nutrient Clods,,,,,,,,,,,,,,,,5,,,,,,,,,,,,,,,,
,Battleweapon Parts,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,
,Leech Baby,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,
,Body Parts,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,,
"""

# parses amounts, ignores planets, starbases
def parseit(s):
  d = {}
  for line in s.split('\n'):
    line = line.strip()
    if not line: continue
    toks = line.split(',')
    prod = toks[1].lower()
    toks = toks[2:]
    for (i, building) in enumerate(building_names):
      tok = toks[i]
      if 'planet' in building or 'starbase' in building: continue
      d.setdefault(building, {})
      if not tok: continue
      amount = float(tok)
      d[building][prod]=amount
  return d

upkeep_dict = parseit(upkeep_s)
production_dict = parseit(production_s)

def upkeep(b):
  result = {}
  d = upkeep_dict[b]
  for commodity in d:
    result[commodity] = int(round(d[commodity]*(1+(level-1)*.5)))
  return result

def production(b):
  result = {}
  d = production_dict[b]
  for commodity in d:
    result[commodity] = int(round(d[commodity]*(1+(level-1)*.5)))
  return result

def get_profits(buy_prices, sell_prices):
  p = {}
  for b in building_names:
    in_credits = 0
    out_credits = 0
    unable_to_determine = False
    if not b in buildings: continue
    for (com, am) in upkeep(b).items():
      if com not in buy_prices:
        unable_to_determine = True
        break
      out_credits+=buy_prices[com]*am
    for (com, am) in production(b).items():
      if com not in sell_prices:
        unable_to_determine = True
        break
     
      in_credits+=sell_prices[com]*am*consumed[com]/produced[com]
    if not unable_to_determine:
      p[b] = in_credits-out_credits
  return p

# initialize starting requirements
balance = dict([(c, 0) for c in commodity_names])
produced = dict([(c, 0.) for c in commodity_names]) # keeps track of total resource produced
consumed = dict([(c, 0.) for c in commodity_names]) # keeps track of total resource consumed

buildings = []

# Set initial needs, from the list of buildings
for bname,num_buildings in end_buildings.items():
  for commodity,amount in production(bname).items():
    balance[commodity]+=amount*num_buildings
    produced[commodity]+=amount*num_buildings
  for commodity,amount in upkeep(bname).items():
    balance[commodity]=-amount*num_buildings
    consumed[commodity]+=amount*num_buildings
  buildings.extend([bname]*num_buildings)

upkeep_done = False
counter = 0
upkeep_transferred = 0


# create support buildings
while not upkeep_done:
  changed = False
  for commodity,amount in balance.items():
    if amount>=0 or commodity in imports: continue

    for b in building_names:
      p = production(b)
      u = upkeep(b)
     
      if commodity in p:
        num_buildings = int(ceil(float(abs(amount))/p[commodity]))
        buildings.extend([b]*num_buildings)

        for commodity2,am in p.items():
          balance[commodity2] += am*num_buildings
          produced[commodity2] += am*num_buildings
        for commodity2,am in u.items():
          balance[commodity2] -= am*num_buildings
          consumed[commodity2] += am*num_buildings
        changed = True
        break
    if not changed:
      print 'Couldnt find source for %s'%(commodity,)
      sys.exit()

    break
 
  upkeep_done = True
  for commodity,amount in balance.items():
    if commodity not in imports and amount<0:
      upkeep_done = False
      break

# calculate total upkeep to transfer (not including imports,exports)
for b in buildings:
  for (com, amount) in upkeep(b).items():
    if com in imports: continue
    upkeep_transferred+=amount


# Assume that every produced item that's in exports if "consumed"
for com, am in produced.items():
  if com in exports:
    consumed[com]+=am

# get credit balance
credits = 0
import_transferred = 0

print 'Target buildings'
for b,am in end_buildings.items():
  print '%25s %d' %(b, am)
 

print 'Total Buildings'
b_dict = {}
for b in buildings:
  b_dict[b] = b_dict.get(b, 0)+1
for (b, amt) in b_dict.items():
  print '%25s %d' %(b, amt)

print 'Exports'
for com,amount in balance.items():
  if amount>0:
    credits+=amount*exports.get(com, 0)
    if not com in exports: s = 'Excess'
    else: s = ''
    print '%25s %6d %s'%(com, amount, s)

print 'Imports'
for com,amount in balance.items():
  if amount<0:
    credits-=abs(amount)*imports[com]
    import_transferred+=abs(amount)
    print '%25s %6d'%(com, abs(amount))

owner_profit = credits-upkeep_transferred*upkeep_profit

# calculate desired building profits
profits = {}
profit_denom = 0.
for b in buildings:
  profit_denom+=profit_factors.get(b, 1)
for b in buildings:
  profits[b] = owner_profit*profit_factors.get(b, 1)/profit_denom
  #print '%20s %d'%(b, profits[b])

# calculate prices
buy_prices = dict(imports)
sell_prices = dict(exports)

counter = 0
while counter<100:
  # find a building with no incoming edges (all buying commodities have prices)
  for b in buildings:
    buy_determined = True
    sell_determined = True
    for com in upkeep(b):
      if not com in buy_prices:
        buy_determined = False
        break
    for com in production(b):
      if not com in sell_prices:
        sell_determined = False
    if buy_determined and not sell_determined:
      out_credits = 0
      in_credits = 0
      for (com, amount) in upkeep(b).items():
        out_credits+=buy_prices[com]*amount
      in_credits = profits[b]+out_credits
      tons_produced = 0

      # adjust for inefficiencies (pretend that produce only as many tons as are consumed)
      for (com, amount) in production(b).items():
        tons_produced+=amount*consumed[com]/produced[com]
        if consumed[com] == 0: print 'Warning, commodity %s isnt consumed....did you specify it as an export?'%(com,)

      if tons_produced>0:
        price_per_ton = in_credits/tons_produced
      else:
        price_per_ton = -1
      for com in production(b):
        sell_prices[com] = price_per_ton
        buy_prices[com] = price_per_ton+upkeep_profit
      break
  counter+=1

print 'Profits:'
for (building, profit) in get_profits(buy_prices, sell_prices).items():
  print '%25s %6d'%(building, profit)


print 'Prices:'
for com in commodity_names:
  if com not in buy_prices and com not in sell_prices: continue
  print '%20s %5d %5d'%(com, buy_prices.get(com, -1), sell_prices.get(com, -1))

print

print 'Upkeep tons to transfer per cycle: %d' %(upkeep_transferred,)
print 'Upkeep tons to import per cycle: %d' %(import_transferred,)
print 'Total upkeep trader profit: %d' %(upkeep_transferred*upkeep_profit,)
print 'Per building owner profit: %d' %(owner_profit/len(building),)
#print 'Profit per building: %d'% (owner_profit/len(buildings),)

print '-'*30