Created
August 1, 2015 16:09
-
-
Save radix/1124c4c60e4616b791da to your computer and use it in GitHub Desktop.
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
## 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