Skip to content

Instantly share code, notes, and snippets.

@Fruglemonkey
Created September 8, 2015 04:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fruglemonkey/66a2fb42bd527b4c654f to your computer and use it in GitHub Desktop.
Save Fruglemonkey/66a2fb42bd527b4c654f to your computer and use it in GitHub Desktop.
Simple simulation of Barrage CoC, assuming basic rules.
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