diff options
-rw-r--r-- | src/unlock.py | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/unlock.py b/src/unlock.py index cf3e6fd..f87e5b1 100644 --- a/src/unlock.py +++ b/src/unlock.py @@ -1,6 +1,7 @@ import re LEVEL_RE = re.compile(r'^([0-9]{1,2})-([0-9]{1,2})( secret)?$') +COINS_RE = re.compile(r'^(unspent |total )?star coins (<|>|==|!=) ([0-9]{1,3})$') COMBINER_RE = re.compile(r'[ ]*(and|or)[ ]*') class UnlockParseError(ValueError): @@ -29,6 +30,16 @@ def _parseUnlockBit(text): raise UnlockParseError('world must be between 1 to 10 inclusive; not %s' % w) return ('level', w, l, (secret != None)) + # ... or star coins? + m = COINS_RE.match(text) + if m: + is_unspent, op, count_s = m.groups() + if is_unspent == 'unspent ': + mode = 'unspent' + else: + mode = 'total' + return ('star_coins', op, int(count_s), mode) + # OK, let's parse parentheses pLevel = 0 endAt = len(text) - 1 @@ -41,7 +52,7 @@ def _parseUnlockBit(text): currentSubTermStart = None skip = 0 - + for index, char in enumerate(text): if skip > 0: skip -= 1 @@ -108,6 +119,8 @@ def stringifyUnlockData(data): return '' elif kind == 'level': return '%02d-%02d%s' % (data[1], data[2], (' secret' if data[3] else '')) + elif kind == 'star_coins': + return '%s star coins %s %d' % (data[3], data[1], data[2]) elif kind == 'and' or kind == 'or': return (' %s ' % kind).join(map(lambda x: '(%s)' % stringifyUnlockData(x), data[1])) @@ -125,6 +138,16 @@ def packUnlockSpec(data): return chr(one) + chr(level - 1) + elif kind == 'star_coins': + k, op, count, mode = data + ops = ('==', '!=', '<', '>') + one = (4 << 6) | ops.index(op) + if mode == 'unspent': + modeID = 0x80 + else: + modeID = 0 + return chr(one) + chr(modeID | (count >> 8)) + chr(count & 0xFF) + elif kind == 'and' or kind == 'or': terms = data[1] cond = 2 if (kind == 'and') else 3 @@ -136,6 +159,7 @@ def packUnlockSpec(data): if __name__ == '__main__': p1 = parseUnlockText('((01-01 secret) and (01-02)) or (02-99 secret) or (01-01)') p2 = parseUnlockText('(1-1 secret) or ((1-2) and (1-3 secret)) or (2-1)') + p3 = parseUnlockText('(star coins > 200) or ((unspent star coins == 300) and (total star coins != 400))') print print repr(p1) @@ -145,6 +169,10 @@ if __name__ == '__main__': print repr(p2) print print stringifyUnlockData(p2) + print + print repr(p3) + print + print stringifyUnlockData(p3) from sys import exit exit() |