Skip to content

Instantly share code, notes, and snippets.

@RemyPorter
Created October 4, 2014 11:59
Show Gist options
  • Save RemyPorter/a68dbbdc3a519997e229 to your computer and use it in GitHub Desktop.
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.
"""
>>> 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