Skip to content

Instantly share code, notes, and snippets.

@MostAwesomeDude
Created January 1, 2017 13:19
Show Gist options
  • Save MostAwesomeDude/71c1f330f895f0751fcadff68b3da622 to your computer and use it in GitHub Desktop.
Save MostAwesomeDude/71c1f330f895f0751fcadff68b3da622 to your computer and use it in GitHub Desktop.
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