-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptimizer.py
90 lines (69 loc) · 2.63 KB
/
optimizer.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
import itertools
from copy import deepcopy
import progressbar
import army
class Optimizer(object):
def __init__(self, attacker, defender, show_pbar=False):
self.attacker = attacker
self.defender = defender
self.show_pbar = show_pbar
def get_attack_power(self, variation):
attacker = army.Army(variation)
power = attacker.power
result, report = attacker.attack(
self.defender,
report=False,
dry_run=True
)
if not result:
return 0
return power
def try_attack(self, variation):
if self.get_attack_power(variation) > 0:
return True
else:
return False
def brute_units(self, variation, currval, maxval):
if self.show_pbar:
widgets = ["Optimizing variation %d of %d: " % (currval, maxval),
progressbar.Percentage(), ' ',
progressbar.Bar(left='[', right=']'),
' ', progressbar.ETA()]
current = deepcopy(variation)
numbers = tuple(range(monster.stack, -1, -1) for monster in variation)
if self.show_pbar:
max_combs = reduce(lambda x, y: x * y, [len(n) for n in numbers])
pbar = progressbar.ProgressBar(widgets=widgets, maxval=max_combs)
pbar.start()
results = []
for i, counts in enumerate(itertools.product(*numbers)):
if self.show_pbar:
pbar.update(i)
for n, unit in enumerate(current):
unit.stack = counts[n]
power = self.get_attack_power(current)
if power > 0:
results.append((power, counts))
if self.show_pbar:
pbar.finish()
return min(results, key=lambda x: x[0])
def brute(self):
stack_variations = []
for variation in itertools.permutations(self.attacker):
if self.try_attack(variation):
stack_variations.append(variation)
unit_variations = []
for n, variation in enumerate(stack_variations):
result = self.brute_units(variation, n+1, len(stack_variations))
unit_variations.append((result, variation))
if len(unit_variations) == 0:
return None
best = min(unit_variations, key=lambda x: x[0])
best_var = best[0][1]
best_basevar = best[1]
for n, var in enumerate(best_var):
best_basevar[n].stack = var
return army.Army(best_basevar)
def optimize(attacker, defender, show_pbar=True):
o = Optimizer(attacker, defender, show_pbar)
return o.brute()