Created
January 1, 2017 13:19
-
-
Save MostAwesomeDude/71c1f330f895f0751fcadff68b3da622 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import math | |
BASE = 4 | |
def XPForLevel(level): | |
"The amount of XP to reward for a given power level." | |
return int(BASE ** level) | |
print "Level 2.7 enemy is worth", XPForLevel(2.7) | |
def advanceBuckets(buckets, offset): | |
"Advance buckets by a number of levels." | |
if offset == 0: | |
return buckets | |
elif offset > len(buckets): | |
return [0] * len(buckets) | |
else: | |
return ([0] * offset) + buckets[:-offset] | |
class Level(object): | |
"A power level, represented as a logarithmic tree." | |
cutoff = 3 | |
def __init__(self, level, buckets): | |
self.level = level | |
if buckets: | |
self.buckets = buckets[:self.cutoff] | |
else: | |
self.buckets = [0] * self.cutoff | |
def __repr__(self): | |
return "<level %.02f (%d xp) (%d + %r)>" % (self.asFloat(), | |
XPForLevel(self.asFloat()), self.level, self.buckets) | |
@classmethod | |
def fromXP(cls, xp): | |
level = int(math.log(xp, BASE)) | |
e = 4 ** level | |
buckets = [] | |
for i in range(cls.cutoff): | |
if e: | |
b, xp = divmod(xp, e) | |
buckets.append(b) | |
else: | |
buckets.append(0) | |
e //= 4 | |
return cls(level, buckets) | |
@classmethod | |
def fromLevel(cls, level): | |
return cls.fromXP(XPForLevel(level)) | |
def asFloat(self): | |
acc = 0 | |
for i, bucket in enumerate(self.buckets): | |
acc += bucket * BASE ** (self.level - i) | |
return math.log(acc, BASE) | |
def add(self, other): | |
left = self.buckets | |
right = other.buckets | |
level = self.level | |
offset = self.level - other.level | |
if offset < 0: | |
offset = -offset | |
left, right = right, left | |
level = other.level | |
right = advanceBuckets(right, offset) | |
buckets = left[:] | |
carry = False | |
for i, b in reversed(list(enumerate(right))): | |
if carry: | |
b += 1 | |
buckets[i] += b | |
if buckets[i] >= BASE: | |
buckets[i] -= BASE | |
carry = True | |
else: | |
carry = False | |
if carry: | |
level += 1 | |
buckets = advanceBuckets(buckets, 1) | |
buckets[0] = 1 | |
return Level(level, buckets) | |
level = Level.fromXP(60) | |
print "60 xp:", level | |
print "60 xp (float):", level.asFloat() | |
other = Level.fromLevel(2.7) | |
print "2.7 level:", other | |
print "60 xp + 2.7 level:", level.add(other) | |
print "60 xp + 2.7 level (float):", level.add(other).asFloat() | |
other = Level.fromLevel(4.2) | |
print "4.2 level:", other | |
print "60 xp + 4.2 level:", level.add(other) | |
print "60 xp + 4.2 level (float):", level.add(other).asFloat() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment