parent
77563ec9e5
commit
9cc4854732
@ -0,0 +1,25 @@ |
||||
Boost Software License - Version 1.0 - August 17th, 2003 |
||||
|
||||
Copyright (c) 2014, 2019, 2020, Cas Rusnov |
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization |
||||
obtaining a copy of the software and accompanying documentation covered by |
||||
this license (the "Software") to use, reproduce, display, distribute, |
||||
execute, and transmit the Software, and to prepare derivative works of the |
||||
Software, and to permit third-parties to whom the Software is furnished to |
||||
do so, all subject to the following: |
||||
|
||||
The copyright notices in the Software and this entire statement, including |
||||
the above license grant, this restriction and the following disclaimer, |
||||
must be included in all copies of the Software, in whole or in part, and |
||||
all derivative works of the Software, unless such copies or derivative |
||||
works are solely in the form of machine-executable object code generated by |
||||
a source language processor. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT |
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE |
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, |
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
@ -1,6 +0,0 @@ |
||||
"""PYOO: A python MOO-like verb based text adventure engine.""" |
||||
|
||||
from .interpret import Interpreter, PyooError, PyooVerbNotFound |
||||
from .base import verb, prepositions, normalized_preps |
||||
from .things import Thing, Container, Place, Player |
||||
from .placeloader import PlaceLoader |
@ -1,43 +1,51 @@ |
||||
prepositions = ('with/using', |
||||
'at/to', |
||||
# 'in front of', |
||||
'in/inside/into', |
||||
# 'on top of/on/onto/upon', |
||||
# 'out of/from inside/from', |
||||
'over', |
||||
'through', |
||||
'under/underneath/beneath', |
||||
'behind', |
||||
'beside', |
||||
'for/about', |
||||
'is', |
||||
'as', |
||||
'off') |
||||
#'off/off of') |
||||
|
||||
normalized_preps = tuple([x.split('/') for x in prepositions]) |
||||
PREPOSITIONS = ( |
||||
"with/using", |
||||
"at/to", |
||||
# 'in front of', |
||||
"in/inside/into", |
||||
# 'on top of/on/onto/upon', |
||||
"on/onto/upon", |
||||
# 'out of/from inside/from', |
||||
"from", |
||||
"over", |
||||
"through", |
||||
"under/underneath/beneath", |
||||
"behind", |
||||
"beside", |
||||
"for/about", |
||||
"is", |
||||
"as", |
||||
"off", |
||||
) |
||||
|
||||
NORMALIZED_PREPS = tuple([x.split("/") for x in PREPOSITIONS]) |
||||
|
||||
# this simple decorator adds verb metadata to a method or function |
||||
# verbname is a comma-separated list of verb names with possible woldcard |
||||
# dobjspec is 'this' or 'that' or 'none' or 'any' (this = the object which defines the verb, that = an object in the soup, any = any string, none = blank) |
||||
# dobjspec is 'this' or 'that' or 'none' or 'any' (this = the object which defines the verb, that = an object in the |
||||
# soup, any = any string, none = blank) |
||||
# iobjspec is 'this' or 'that' or 'none' or 'any' |
||||
# prepspec is one of prepositions strings |
||||
# verb prototypes are: (verbname, dobjstr, prepstr, iobjstr, dobj, iobj, argstr) |
||||
|
||||
|
||||
def verb(verbname, dobjspec, prepspec, iobjspec): |
||||
def verb_decorate(verbfunc): |
||||
names = [x.strip() for x in verbname.split(',')] |
||||
names = [x.strip() for x in verbname.split(",")] |
||||
verbfunc.name = names[0] |
||||
verbfunc.names = names |
||||
ps = prepspec |
||||
if isinstance(ps, basestring): |
||||
if ps.find('/') > 0: |
||||
ps = ps.split('/') |
||||
if isinstance(ps, str): |
||||
if ps.find("/") > 0: |
||||
ps = ps.split("/") |
||||
else: |
||||
for p in normalized_preps: |
||||
for p in NORMALIZED_PREPS: |
||||
if ps in p: |
||||
ps = p |
||||
break |
||||
verbfunc.callspec = (dobjspec, ps, iobjspec) |
||||
verbfunc.is_verb = True |
||||
return verbfunc |
||||
|
||||
return verb_decorate |
||||
|
@ -1,46 +1,58 @@ |
||||
from enum import Enum |
||||
from typing import TextIO |
||||
|
||||
from .things import Place |
||||
from .things import Place, Thing |
||||
|
||||
|
||||
class PlaceLoaderStates(Enum): |
||||
START = 0 |
||||
DESC = 1 |
||||
EXITS = 2 |
||||
|
||||
(ST_START, ST_DESC, ST_EXITS) = range(3) |
||||
|
||||
class PlaceLoader(object): |
||||
def __init__(self, infile, baseplace=Place): |
||||
"""Create the factory by reading the contents of infile (an iteratable object [file-like or otherwise]). Specify the base class for place with baseplace.""" |
||||
""" |
||||
A factory which loads a simple data format containing a description of rooms, and how |
||||
they are connected, and produces room objects for each one. |
||||
""" |
||||
def __init__(self, in_file: TextIO, baseplace: Thing = Place): |
||||
"""Initialize the factory by loading a description file.""" |
||||
self.base = baseplace |
||||
self.places = dict() #indexed by name |
||||
self.places = {} # indexed by name |
||||
|
||||
if infile: |
||||
self.process_file(infile) |
||||
if in_file: |
||||
self.process_file(in_file) |
||||
|
||||
def process_file(self, inf): |
||||
state = ST_START |
||||
def process_file(self, in_file: TextIO): |
||||
"""Load any room information from the passed in file.""" |
||||
state = PlaceLoaderStates.START |
||||
rm = None |
||||
desc = list() |
||||
for line in inf: |
||||
desc = [] |
||||
for line in in_file: |
||||
line = line.strip() |
||||
if state == ST_START: |
||||
if state == PlaceLoaderStates.START: |
||||
rm = self.base(line) |
||||
rm.temp_exits = list() |
||||
state = ST_DESC |
||||
state = PlaceLoaderStates.DESC |
||||
desc = list() |
||||
elif state == ST_DESC: |
||||
if line == '.': |
||||
state = ST_EXITS |
||||
elif state == PlaceLoaderStates.DESC: |
||||
if line == ".": |
||||
state = PlaceLoaderStates.EXITS |
||||
rm.description = desc |
||||
else: |
||||
desc.append(line) |
||||
elif state == ST_EXITS: |
||||
if line == '.': |
||||
state = ST_START |
||||
elif state == PlaceLoaderStates.EXITS: |
||||
if line == ".": |
||||
state = PlaceLoaderStates.START |
||||
self.places[rm.name] = rm |
||||
rm = None |
||||
else: |
||||
rm.temp_exits.append(line) |
||||
|
||||
# assemble the exits |
||||
for place in self.places.values(): |
||||
for place in list(self.places.values()): |
||||
for ext in place.temp_exits: |
||||
names, destination = ext.split(' ',1) |
||||
for nm in names.split(','): |
||||
names, destination = ext.split(" ", 1) |
||||
for nm in names.split(","): |
||||
place.ways[nm] = self.places[destination] |
||||
place.update_go() |
||||
|
@ -0,0 +1,21 @@ |
||||
"""Module setup.""" |
||||
|
||||
import os.path |
||||
from setuptools import setup, find_packages |
||||
|
||||
PACKAGE_NAME = "pyoo" |
||||
VERSION = "0.0.2" |
||||
|
||||
srcpath = os.path.dirname(__file__) |
||||
|
||||
if __name__ == "__main__": |
||||
setup( |
||||
name=PACKAGE_NAME, |
||||
version=VERSION, |
||||
packages=find_packages(), |
||||
python_requires=">=3.6.3", |
||||
# scripts=["scripts/adventure.py"] |
||||
description="A simple LambdaMOO-like command interpreter for Python", |
||||
long_description=open(os.path.join(srcpath, "README.md"), "r").read(), |
||||
long_description_content_type="text/markdown", |
||||
) |
@ -1,42 +1,45 @@ |
||||
import pyoo |
||||
from pyoo import PlaceLoader, Thing, verb, Interpreter, Container, Place, Player, PyooVerbNotFound |
||||
from pyoo.things import Place, Player |
||||
from pyoo.placeloader import PlaceLoader |
||||
from pyoo.interpret import Interpreter, PyooVerbNotFound |
||||
from pyoo.base import verb |
||||
|
||||
class DescriptivePlace(Place): |
||||
def handle_enter(self, player): |
||||
self.do_look() |
||||
|
||||
@verb('look,l', 'none','none','none') |
||||
@verb("look,l", "none", "none", "none") |
||||
def look(self, verbname, dobjstr, prepstr, iobjstr, dobj, iobj, argstr): |
||||
self.do_look() |
||||
|
||||
def do_look(self): |
||||
print self.name |
||||
if isinstance(self.description, basestring): |
||||
print self.description |
||||
print(self.name) |
||||
if isinstance(self.description, str): |
||||
print(self.description) |
||||
else: |
||||
for line in self.description: |
||||
print line |
||||
print(line) |
||||
|
||||
loader = PlaceLoader(file('roomtest.txt','r'), DescriptivePlace) |
||||
game = Interpreter([], Player(), loader.places.values(), None) |
||||
porch = game.get_placematches('Porch')[0][1] |
||||
|
||||
loader = PlaceLoader(open("roomtest.txt", "r"), DescriptivePlace) |
||||
game = Interpreter([], Player(), list(loader.places.values()), None) |
||||
porch = game.get_placematches("Porch")[0][1] |
||||
run = True |
||||
|
||||
# REPL |
||||
if __name__ == '__main__': |
||||
if __name__ == "__main__": |
||||
game.handle_move(porch) |
||||
while (run): |
||||
cmd = '' |
||||
while run: |
||||
cmd = "" |
||||
try: |
||||
cmd = raw_input('>') |
||||
cmd = input(">") |
||||
except EOFError: |
||||
run = False |
||||
if cmd.startswith('quit'): |
||||
run = False |
||||
if cmd.startswith("quit"): |
||||
run = False |
||||
else: |
||||
try: |
||||
game.interpret(cmd) |
||||
except PyooVerbNotFound: |
||||
print "I don't understand that." |
||||
print("I don't understand that.") |
||||
|
||||
print "Bye!" |
||||
print("Bye!") |
||||
|
Loading…
Reference in new issue