Skip to content

Instantly share code, notes, and snippets.

@caccavale
Last active March 29, 2021 02:27
Show Gist options
  • Save caccavale/eb48bc0da8874c18fc18b2ef5d9329d3 to your computer and use it in GitHub Desktop.
Save caccavale/eb48bc0da8874c18fc18b2ef5d9329d3 to your computer and use it in GitHub Desktop.
from itertools import product
from typing import Dict, Tuple
melee_as = 3.9
ranged_as = 2.9
ranged_haste = 1.15 * 1.2
auto_damage, steady_damage, raptor_damage, attack_damage = 1463, 1457, 1432, 1207
_ranged_cd = (ranged_as - .5) / ranged_haste
# skill, cast_time, cooldown, damage, relies on CD
actions : Dict[str, Tuple[float, int, int, str]] = {
"attack": (.4, melee_as, attack_damage, ""),
"raptor": (.4, 6, raptor_damage, "attack"),
"auto": (.5 / ranged_haste, _ranged_cd, auto_damage, ""),
"steady": (1.5 / ranged_haste, 1.5 - (1.5 / ranged_haste), steady_damage, ""),
}
index_of = dict(zip(actions.keys(), range(len(actions))))
def update_cooldowns(cooldowns, time_before_action, action_name):
wait_time = max(cooldowns[index_of[action_name]] - time_before_action, 0)
if depends_on := actions[action_name][3]:
wait_time = max(wait_time, cooldowns[index_of[depends_on]] - time_before_action)
time_spent = time_before_action + actions[action_name][0] + wait_time
cooldowns = [max(cd - time_spent, 0) for cd in cooldowns]
cooldowns[index_of[action_name]] = actions[action_name][1]
if depends_on:
cooldowns[index_of[depends_on]] = actions[depends_on][1]
return time_spent, cooldowns
input_lag = 0 # BRRTTTT
best_dps = 0
best_sequence = (0, 10, ())
for sequence_length in range(5, 11):
print(f"Solving for length {sequence_length}...")
for sequence in product(actions.items(), repeat=sequence_length):
total_damage = 0
total_time = 0
cooldowns_remaining = [0] * len(actions)
earliest_cast = [float("inf")] * len(actions)
for action_name, values in sequence:
cast_time, cooldown, damage, shared_cd = values
if earliest_cast[index_of[action_name]] == float("inf"):
earliest_cast[index_of[action_name]] = total_time
time_before_action = input_lag # for the action
time_spent, cooldowns_remaining = update_cooldowns(cooldowns_remaining, time_before_action, action_name)
total_damage += damage
total_time += time_spent
wait_before_repeating = input_lag + max(max(cdr - earliest , 0) for earliest, cdr in zip(earliest_cast, cooldowns_remaining))
total_damage = total_damage
total_time = total_time + wait_before_repeating
if total_damage / total_time > best_dps:
best_dps = total_damage / total_time
best_sequence = (total_damage, total_time, tuple(action for action, *_ in sequence))
print(f'New best: {best_sequence}')
print(best_dps)
print(best_sequence)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment