-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc_builder_efficiency.py
115 lines (85 loc) · 2.43 KB
/
calc_builder_efficiency.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import math
import json
WORK = 'work'
CARRY = 'carry'
MOVE = 'move'
COSTS = {
WORK: 100,
CARRY: 50,
MOVE: 50,
}
DISTANCE = 20
WORK_PER_TICK = 5 # 1 for upgrading, 5 for building, 2 for harvesting
def extend_parts(parts):
assert type(parts) == dict
extended = []
for k, v in parts.items():
extended.extend([k] * v)
return extended
def repr_parts(parts):
return ', '.join(f"{k}: {v}" for k, v in parts.items())
def calc_info(parts, verbose=True):
cycle_time = 0
# Add trip time
move_count = parts[MOVE]
non_move_count = sum(parts.values()) - move_count
ticks_per_move = math.ceil(non_move_count / (move_count * 2))
# We assume all movement is on roads
round_trip_time = ticks_per_move * DISTANCE * 2
cycle_time += round_trip_time
# Add work time
carry_count = parts[CARRY]
cycle_energy = carry_count * 50
work_count = parts[WORK]
working_time = math.ceil(cycle_energy / (WORK_PER_TICK * work_count))
cycle_time += working_time
# Calculate energy cost
cost = sum(COSTS[p] for p in parts)
# Calculate work per cost
cycles_per_life = math.floor(1500 / cycle_time)
total_energy = cycle_energy * cycles_per_life
energy_per_cost = total_energy / cost
energy_per_tick = cycle_energy / cycle_time
if verbose:
print(f'Cost: {cost}, parts: ({repr_parts(parts)})')
print(f'Energy delivered for energy spent: {energy_per_cost}')
print(f'Cycle time: {cycle_time}, (t{round_trip_time} + w{working_time})')
print(f'Energy per tick: {energy_per_tick}')
return energy_per_cost
# MAX_ENERGIES = [
# 300,
# 550,
# 800,
# 1300,
# 1800,
# 2300,
# 5300,
# 12300,
# ]
MAX_ENERGIES = range(300, 12350, 50)
max_epc = 0
best_parts = None
energy_to_body = {}
for max_energy in MAX_ENERGIES:
max_move_parts = math.floor((max_energy - 150) / 50)
for move_parts in range(1, max_move_parts + 1):
energy_after_move = max_energy - (move_parts * 50)
max_work_parts = math.floor((energy_after_move - 50) / 100)
for work_parts in range(1, max_work_parts + 1):
energy_after_work = energy_after_move - (work_parts * 100)
parts = {
MOVE: move_parts,
WORK: work_parts,
CARRY: math.floor(energy_after_work / 50)
}
epc = calc_info(parts, verbose=False)
if epc > max_epc:
max_epc = epc
best_parts = parts.copy()
print(
f'Energy: {max_energy}, '
f'max EPC: {max_epc}, '
f'best parts: {repr_parts(best_parts)}'
)
energy_to_body[max_energy] = extend_parts(best_parts)
print(json.dumps(energy_to_body))