Skip to content

Instantly share code, notes, and snippets.

@radix
Created August 1, 2015 16:09
Show Gist options
  • Save radix/1124c4c60e4616b791da to your computer and use it in GitHub Desktop.
Save radix/1124c4c60e4616b791da to your computer and use it in GitHub Desktop.
## Model
from pyrsistent import PClass, field, pmap_field, pvector_field
class Thing(PClass):
name = field(basestring)
class Location(PClass):
name = field(basestring)
description = field(basestring)
exits = pmap_field(basestring, tuple) # direction name -> (required thing, location name)
items = pmap_field(basestring, Thing)
class GameState(PClass):
location_name = field(basestring)
world = pmap_field(basestring, Location)
inventory = pvector_field(Thing)
@property
def location(self):
return self.world[self.location_name]
## Strategies
from random import choice # This could be a bad idea
from hypothesis.strategies import builds, text, dictionaries, tuples, just, lists, recursive, none
item_names = text(average_size=5, max_size=10)
exit_names = text(average_size=4, max_size=10)
location_names = text(average_size=10, max_size=20)
descriptions = text(average_size=140, max_size=300)
# This is basically the seed of the map: generates a bunch of location names.
# Each one will become a location.
world_location_names = lists(location_names,
min_size=1, average_size=10, max_size=20)
# Strategy for building {item_name: item}
items = builds(
dict,
lists(
item_names.flatmap(
lambda name: (just(name), builds(Thing, name=just(name)))),
average_size=2,
max_size=5,
))
def locations(actual_loc_names):
"""Build a *single* location, given access to all location names."""
some_location_name = builds(choice, just(actual_loc_names)) # non-determinism here. not sure if this is okay.
if actual_loc_names:
exits = dictionaries(
exit_names, tuples(none(), some_location_name),
average_size=3)
else:
exits = just({})
return builds(Location, name=some_location_name, description=descriptions,
exits=exits, items=items)
# Build a {location_name: location}.
worlds = world_location_names.flatmap(
lambda actual_loc_names:
tuples(*[
locations(actual_loc_names)
for lname in actual_loc_names])).flatmap(
lambda locs: just({x.name: x for x in locs}))
# and finally compose everything together to build game states, with the player in an arbitrary room.
game_states = worlds.flatmap(
lambda world: builds(
GameState,
location_name=just(choice(world.keys())), # Is it bad to have non-deterministic strategies?
world=just(world),
inventory=items.flatmap(lambda items_dict: just(items_dict.values())),
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment