Created
October 4, 2014 11:59
-
-
Save RemyPorter/a68dbbdc3a519997e229 to your computer and use it in GitHub Desktop.
I'm building tools to generate a declarative API. The purpose of the API is to describe rules for manipulating a state object, and is specifically designed around describing board game 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
""" | |
>>> SomeEffect = Effect("SomeEffect", someFunc) | |
>>> OtherEffect = Effect("OtherEffect", someFunc) | |
>>> CompositeEffect = SomeEffect + OtherEffect | |
>>> newstate = CompositeEffect()(oldstate) | |
And we can generate effects, too: | |
>>> effects = [Effect("Do" + e.title(), funcGen(e)) for e in effectTypes] | |
This is the real strength of this snippet of code- generating variations of behaviors | |
which can then be used in a declarative fashion. | |
Combined with Condition, ConditionalEffect, and many other variations of metaclasses, | |
I can, with a few lines of code, build thousands of variations on a single set of board | |
game rules, and quickly prototype them and sanity check them against a simulator. | |
""" | |
class EffectType(type): | |
def __init__(cls, name, bases, dct): | |
behavior = dct["behavior"] | |
def init(self): | |
self.__behavior = behavior | |
def call(self, state, *args, **kwargs): | |
return self.__behavior(state, *args, **kwargs) | |
cls.__call__ = call | |
cls.__init__ = init | |
cls.__doc__ = document(behavior) | |
super().__init__(name, bases, dct) | |
def __add__(cls, other): | |
name = "{0}.{1}".format(cls.__name__, other.__name__) | |
doc = "{0}\n{1}".format(cls.__doc__, other.__doc__) | |
t = EffectComposeType(name, (object,), | |
{"subtypes":(cls, other), "__doc__":doc}) | |
return t | |
class EffectComposeType(EffectType): | |
def __init__(cls, name, bases, dct): | |
subtypes = dct["subtypes"] | |
def group_call(statecont, *args, **kwargs): | |
nextstate = statecont | |
for t in subtypes: | |
nextstate = t()(nextstate, *args, **kwargs) | |
return nextstate | |
dct["behavior"] = group_call | |
super().__init__(name, bases, dct) | |
docs = [document(s) for s in subtypes] | |
cls.__doc__ = "do: " + "; ".join(docs) | |
def Effect(name, behavior, bases=(object,)): | |
"""Construct a new Effect type, based on the supplied behavior.""" | |
return EffectType(name, bases, {"behavior": behavior}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment