summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/api_misc.rst4
-rw-r--r--doc/index.rst1
-rw-r--r--doc/testing.rst13
-rwxr-xr-xtest_tile.py25
-rw-r--r--weatbag/__init__.py52
-rw-r--r--weatbag/tiles/centre.py2
-rw-r--r--weatbag/tiles/e1.py5
-rw-r--r--weatbag/tiles/n2.py2
-rw-r--r--weatbag/utils.py23
9 files changed, 110 insertions, 17 deletions
diff --git a/doc/api_misc.rst b/doc/api_misc.rst
index 4830e1c..674ab08 100644
--- a/doc/api_misc.rst
+++ b/doc/api_misc.rst
@@ -24,4 +24,8 @@ Understanding commands
.. automodule:: weatbag.words
+Utility functions
+-----------------
+
+.. autofunction:: weatbag.utils.transfer
diff --git a/doc/index.rst b/doc/index.rst
index 61d7ed2..c4184d5 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -21,6 +21,7 @@ The idea is that anything goes, but we do need a few house rules:
interface.rst
api_misc.rst
+ testing.rst
If you prefer to learn by example, have a look at the `tiles already in the game
<https://github.com/takluyver/weatbag/tree/master/weatbag/tiles>`_.
diff --git a/doc/testing.rst b/doc/testing.rst
new file mode 100644
index 0000000..db70f09
--- /dev/null
+++ b/doc/testing.rst
@@ -0,0 +1,13 @@
+Testing tiles
+=============
+
+To save you repeatedly playing through the game to test your latest changes,
+there's a script to skip to any given tile::
+
+ ./test_tile.py n2
+
+If the player needs specific items to test the tile, add a list called test_items
+to the module. The test script will add these to the player's inventory. For
+example, tile n2 defines::
+
+ test_items = ['unlit torch']
diff --git a/test_tile.py b/test_tile.py
new file mode 100755
index 0000000..e6ab9e6
--- /dev/null
+++ b/test_tile.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+import sys
+from importlib import import_module
+from weatbag import Player, interact, name_to_coords
+
+if len(sys.argv) != 2:
+ print("Usage: ./test_tile.py <tile module>")
+ print("E.g. : ./test_tile.py n2")
+ sys.exit()
+
+player = Player('Test player')
+player.position = name_to_coords(sys.argv[1])
+
+mod = import_module('weatbag.tiles.' + sys.argv[1])
+if hasattr(mod, 'test_items'):
+ player.inventory.update(mod.test_items)
+ print("You have test items:")
+ for item, n in player.inventory.most_common():
+ if n < 1:
+ break
+ print(item, '(%d)' % n)
+ print()
+
+interact(player)
+
diff --git a/weatbag/__init__.py b/weatbag/__init__.py
index 303962e..9a743e0 100644
--- a/weatbag/__init__.py
+++ b/weatbag/__init__.py
@@ -1,5 +1,6 @@
from collections import Counter
from importlib import import_module
+import re
from . import action
@@ -53,18 +54,7 @@ class World:
try:
return self.tiles[key]
except KeyError:
- e,n = key
- modname = 'weatbag.tiles.'
- if n > 0:
- modname += 'n'+str(n)
- elif n < 0:
- modname += 's'+str(abs(n))
-
- if e > 0:
- modname += 'e'+str(e)
- elif e < 0:
- modname += 'w'+str(abs(e))
-
+ modname = 'weatbag.tiles.' + coords_to_name(*key)
try:
mod = import_module(modname)
except ImportError:
@@ -74,11 +64,47 @@ class World:
self.tiles[key] = tile
return tile
+def coords_to_name(e, n):
+ modname = ''
+ if n > 0:
+ modname += 'n'+str(n)
+ elif n < 0:
+ modname += 's'+str(abs(n))
+
+ if e > 0:
+ modname += 'e'+str(e)
+ elif e < 0:
+ modname += 'w'+str(abs(e))
+
+ return modname
+
+_tile_name_re = re.compile(r'([ns]\d+)?([ew]\d+)?')
+def name_to_coords(tilename):
+ ns, es = _tile_name_re.match(tilename).groups()
+ if ns is None:
+ n = 0
+ elif ns[0] == 'n':
+ n = int(ns[1:])
+ else:
+ n = -int(ns[1:])
+
+ if es is None:
+ e = 0
+ elif es[0] == 'e':
+ e = int(es[1:])
+ else:
+ e = -int(es[1:])
+
+ return e, n
+
def main():
name = input("What is your name? ")
player = Player(name)
+ interact(player)
+
+def interact(player):
world = World()
- tile = world[0,0]
+ tile = world[player.position]
tile.describe()
while True:
do = action.get_action()
diff --git a/weatbag/tiles/centre.py b/weatbag/tiles/centre.py
index 4aa9a30..c2709d7 100644
--- a/weatbag/tiles/centre.py
+++ b/weatbag/tiles/centre.py
@@ -5,7 +5,7 @@ class Tile:
self.contents = {'rope': 1}
def describe(self):
- print("You are in a sizeable clearing in the forest. Paths lead off in"
+ print("You are in a sizeable clearing in the forest. Paths lead off in "
"four directions, which your unerring sense of direction tells you "
"correspond to the four compass points.")
if self.contents.get('rope'):
diff --git a/weatbag/tiles/e1.py b/weatbag/tiles/e1.py
index 909f1b3..486a98f 100644
--- a/weatbag/tiles/e1.py
+++ b/weatbag/tiles/e1.py
@@ -1,4 +1,5 @@
from weatbag import words
+from weatbag.utils import transfer
class Tile:
def __init__(self):
@@ -17,9 +18,7 @@ class Tile:
print("Sorry, I don't understand.")
def take_berries(self, player):
- if self.contents['berries'] > 0:
- self.contents['berries'] -= 1
- player.give('berries')
+ if transfer('berries', self.contents, player.inventory):
print("Reaching up, you pick the berries.")
else:
print("There are no berries here.")
diff --git a/weatbag/tiles/n2.py b/weatbag/tiles/n2.py
index a9bca43..32e3ce4 100644
--- a/weatbag/tiles/n2.py
+++ b/weatbag/tiles/n2.py
@@ -26,3 +26,5 @@ class Tile:
else:
print("Sorry, I don't understand")
+
+test_items = ['unlit torch']
diff --git a/weatbag/utils.py b/weatbag/utils.py
new file mode 100644
index 0000000..0f73294
--- /dev/null
+++ b/weatbag/utils.py
@@ -0,0 +1,23 @@
+"""Utility functions for the game."""
+
+def transfer(item, from_collection, to_collection, n=1):
+ """Move an item from one dictionary of objects to another.
+
+ Returns True if the item was successfully transferred, False if it's not in
+ from_collection.
+
+ For example, to have the player pick up a pointy stick::
+
+ if transfer('pointy stick', tile.contents, player.inventory):
+ print("You take the stick.")
+ else:
+ print("There's no stick here.")
+ """
+ if from_collection.get(item, 0) < n:
+ return False
+ from_collection[item] -= n
+ if item in to_collection:
+ to_collection[item] += n
+ else:
+ to_collection[item] = n
+ return True