Created
September 8, 2015 04:49
-
-
Save Fruglemonkey/66a2fb42bd527b4c654f to your computer and use it in GitHub Desktop.
Simple simulation of Barrage CoC, assuming basic rules.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division | |
from random import random | |
import matplotlib.pyplot as plt | |
class Barrage(object): | |
def __init__(self, aps = 1, accuracy = 1, crit = 0.95, spells = 1, | |
projectile_count = 8, windup = 0.40): | |
self.aps = aps | |
self.accuracy = accuracy | |
self.crit = crit | |
self.spells = {} | |
for i in range(spells): | |
self.spells['spell{}'.format(i)] = 0 | |
self.projectile_count = projectile_count | |
self.attack_time = 0 | |
self.windup_time = 1000/aps * windup | |
self.projectile_delay = 0 | |
# Might cause errors due to off-by-1, but too lazy to workaround. | |
self.projectile_gap = int((1000/aps * (1 - windup)) / projectile_count) | |
self.attack_gap = 1000/aps | |
self.spells_fired = 0 | |
self.projectiles_fired = 0 | |
seconds = 1000 | |
# Use this if you want to test a series of values of aps | |
tests = {'1.08':Barrage(aps=1.08), '1.20':Barrage(aps=1.20), | |
'1.33':Barrage(aps=1.33), '1.39':Barrage(aps=1.39), | |
'1.49':Barrage(aps=1.49), '1.67':Barrage(aps=1.67), | |
'4':Barrage(aps=4) } | |
# Use this if you want to test a range of aps | |
# for i in range(100): | |
# tests['{}'.format(1 + i/100)] = Barrage(aps = 1 + i/100) | |
for y, x in sorted(tests.iteritems()): | |
# For every millisecond, update our timers | |
for i in range(seconds * 1000): | |
# If we're in the middle of an attack, do stuff | |
if x.attack_time < x.attack_gap: | |
x.attack_time += 1 | |
# If we're waiting to fire a projectile, lower that cooldown | |
if x.projectile_delay: x.projectile_delay -= 1 | |
# Same for spell cooldowns | |
for spell in x.spells: | |
if x.spells[spell]: | |
x.spells[spell] -= 1 | |
# If we're not waiting to fire a projectile, fire one. | |
if x.projectile_delay == 0 and x.projectiles_fired < 8\ | |
and x.attack_time > x.windup_time: | |
x.projectile_delay = x.projectile_gap | |
x.projectiles_fired += 1 | |
for spell in x.spells: | |
# If the spell isn't on cooldown, try and fire it | |
if not x.spells[spell]: | |
if random() < .66: | |
x.spells[spell] = 50 | |
x.spells_fired += 1 | |
# Otherwise, start a new attack | |
else: | |
x.attack_time = 0 | |
x.projectile_delay = 0 | |
x.projectiles_fired = 0 | |
print x.aps, '\t', x.spells_fired/seconds | |
plt.plot([x.aps for y, x in sorted(tests.iteritems())], [x.spells_fired/seconds for y, x in sorted(tests.iteritems())], 'bo') | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment