ÿØÿà JFIF ` ` ÿþxØ
| Server IP : 109.234.164.53 / Your IP : 216.73.216.110 Web Server : Apache System : Linux cervelle.o2switch.net 4.18.0-553.32.1.lve.el8.x86_64 #1 SMP Thu Dec 19 13:14:03 UTC 2024 x86_64 User : computer3 ( 1098) PHP Version : 7.1.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /opt/alt/python37/share/doc/alt-python37-pyparsing-doc/examples/ |
Upload File : |
# adventureEngine.py
# Copyright 2005-2006, Paul McGuire
#
# Updated 2012 - latest pyparsing API
#
from pyparsing import *
import random
import string
def aOrAn(item):
if item.desc[0] in "aeiou":
return "an " + item.desc
else:
return "a " + item.desc
def enumerateItems(l):
if len(l) == 0:
return "nothing"
out = []
if len(l) > 1:
out.append(", ".join(aOrAn(item) for item in l[:-1]))
out.append("and")
out.append(aOrAn(l[-1]))
return " ".join(out)
def enumerateDoors(l):
if len(l) == 0:
return ""
out = []
if len(l) > 1:
out.append(", ".join(l[:-1]))
out.append("and")
out.append(l[-1])
return " ".join(out)
class Room:
def __init__(self, desc):
self.desc = desc
self.inv = []
self.gameOver = False
self.doors = [None, None, None, None]
def __getattr__(self, attr):
return {
"n": self.doors[0],
"s": self.doors[1],
"e": self.doors[2],
"w": self.doors[3],
}[attr]
def enter(self, player):
if self.gameOver:
player.gameOver = True
def addItem(self, it):
self.inv.append(it)
def removeItem(self, it):
self.inv.remove(it)
def describe(self):
print(self.desc)
visibleItems = [it for it in self.inv if it.isVisible]
if random.random() > 0.5:
if len(visibleItems) > 1:
is_form = "are"
else:
is_form = "is"
print("There {} {} here.".format(is_form, enumerateItems(visibleItems)))
else:
print("You see %s." % (enumerateItems(visibleItems)))
class Exit(Room):
def __init__(self):
super().__init__("")
def enter(self, player):
player.gameOver = True
class Item:
items = {}
def __init__(self, desc):
self.desc = desc
self.isDeadly = False
self.isFragile = False
self.isBroken = False
self.isTakeable = True
self.isVisible = True
self.isOpenable = False
self.useAction = None
self.usableConditionTest = None
self.cantTakeMessage = "You can't take that!"
Item.items[desc] = self
def __str__(self):
return self.desc
def breakItem(self):
if not self.isBroken:
print("<Crash!>")
self.desc = "broken " + self.desc
self.isBroken = True
def isUsable(self, player, target):
if self.usableConditionTest:
return self.usableConditionTest(player, target)
else:
return False
def useItem(self, player, target):
if self.useAction:
self.useAction(player, self, target)
class OpenableItem(Item):
def __init__(self, desc, contents=None):
super().__init__(desc)
self.isOpenable = True
self.isOpened = False
if contents is not None:
if isinstance(contents, Item):
self.contents = [
contents,
]
else:
self.contents = contents
else:
self.contents = []
def openItem(self, player):
if not self.isOpened:
self.isOpened = not self.isOpened
if self.contents is not None:
for item in self.contents:
player.room.addItem(item)
self.contents = []
self.desc = "open " + self.desc
def closeItem(self, player):
if self.isOpened:
self.isOpened = not self.isOpened
if self.desc.startswith("open "):
self.desc = self.desc[5:]
class Command:
"Base class for commands"
def __init__(self, verb, verbProg):
self.verb = verb
self.verbProg = verbProg
@staticmethod
def helpDescription():
return ""
def _doCommand(self, player):
pass
def __call__(self, player):
print(self.verbProg.capitalize() + "...")
self._doCommand(player)
class MoveCommand(Command):
def __init__(self, quals):
super().__init__("MOVE", "moving")
self.direction = quals.direction[0]
@staticmethod
def helpDescription():
return """MOVE or GO - go NORTH, SOUTH, EAST, or WEST
(can abbreviate as 'GO N' and 'GO W', or even just 'E' and 'S')"""
def _doCommand(self, player):
rm = player.room
nextRoom = rm.doors[
{
"N": 0,
"S": 1,
"E": 2,
"W": 3,
}[self.direction]
]
if nextRoom:
player.moveTo(nextRoom)
else:
print("Can't go that way.")
class TakeCommand(Command):
def __init__(self, quals):
super().__init__("TAKE", "taking")
self.subject = quals.item
@staticmethod
def helpDescription():
return "TAKE or PICKUP or PICK UP - pick up an object (but some are deadly)"
def _doCommand(self, player):
rm = player.room
subj = Item.items[self.subject]
if subj in rm.inv and subj.isVisible:
if subj.isTakeable:
rm.removeItem(subj)
player.take(subj)
else:
print(subj.cantTakeMessage)
else:
print("There is no %s here." % subj)
class DropCommand(Command):
def __init__(self, quals):
super().__init__("DROP", "dropping")
self.subject = quals.item
@staticmethod
def helpDescription():
return "DROP or LEAVE - drop an object (but fragile items may break)"
def _doCommand(self, player):
rm = player.room
subj = Item.items[self.subject]
if subj in player.inv:
rm.addItem(subj)
player.drop(subj)
else:
print("You don't have %s." % (aOrAn(subj)))
class InventoryCommand(Command):
def __init__(self, quals):
super().__init__("INV", "taking inventory")
@staticmethod
def helpDescription():
return "INVENTORY or INV or I - lists what items you have"
def _doCommand(self, player):
print("You have %s." % enumerateItems(player.inv))
class LookCommand(Command):
def __init__(self, quals):
super().__init__("LOOK", "looking")
@staticmethod
def helpDescription():
return "LOOK or L - describes the current room and any objects in it"
def _doCommand(self, player):
player.room.describe()
class DoorsCommand(Command):
def __init__(self, quals):
super().__init__("DOORS", "looking for doors")
@staticmethod
def helpDescription():
return "DOORS - display what doors are visible from this room"
def _doCommand(self, player):
rm = player.room
numDoors = sum([1 for r in rm.doors if r is not None])
if numDoors == 0:
reply = "There are no doors in any direction."
else:
if numDoors == 1:
reply = "There is a door to the "
else:
reply = "There are doors to the "
doorNames = [
{0: "north", 1: "south", 2: "east", 3: "west"}[i]
for i, d in enumerate(rm.doors)
if d is not None
]
# ~ print doorNames
reply += enumerateDoors(doorNames)
reply += "."
print(reply)
class UseCommand(Command):
def __init__(self, quals):
super().__init__("USE", "using")
self.subject = Item.items[quals.usedObj]
if quals.targetObj:
self.target = Item.items[quals.targetObj]
else:
self.target = None
@staticmethod
def helpDescription():
return "USE or U - use an object, optionally IN or ON another object"
def _doCommand(self, player):
rm = player.room
availItems = rm.inv + player.inv
if self.subject in availItems:
if self.subject.isUsable(player, self.target):
self.subject.useItem(player, self.target)
else:
print("You can't use that here.")
else:
print("There is no %s here to use." % self.subject)
class OpenCommand(Command):
def __init__(self, quals):
super().__init__("OPEN", "opening")
self.subject = Item.items[quals.item]
@staticmethod
def helpDescription():
return "OPEN or O - open an object"
def _doCommand(self, player):
rm = player.room
availItems = rm.inv + player.inv
if self.subject in availItems:
if self.subject.isOpenable:
if not self.subject.isOpened:
self.subject.openItem(player)
else:
print("It's already open.")
else:
print("You can't open that.")
else:
print("There is no %s here to open." % self.subject)
class CloseCommand(Command):
def __init__(self, quals):
super().__init__("CLOSE", "closing")
self.subject = Item.items[quals.item]
@staticmethod
def helpDescription():
return "CLOSE or CL - close an object"
def _doCommand(self, player):
rm = player.room
availItems = rm.inv + player.inv
if self.subject in availItems:
if self.subject.isOpenable:
if self.subject.isOpened:
self.subject.closeItem(player)
else:
print("You can't close that, it's not open.")
else:
print("You can't close that.")
else:
print("There is no %s here to close." % self.subject)
class QuitCommand(Command):
def __init__(self, quals):
super().__init__("QUIT", "quitting")
@staticmethod
def helpDescription():
return "QUIT or Q - ends the game"
def _doCommand(self, player):
print("Ok....")
player.gameOver = True
class HelpCommand(Command):
def __init__(self, quals):
super().__init__("HELP", "helping")
@staticmethod
def helpDescription():
return "HELP or H or ? - displays this help message"
def _doCommand(self, player):
print("Enter any of the following commands (not case sensitive):")
for cmd in [
InventoryCommand,
DropCommand,
TakeCommand,
UseCommand,
OpenCommand,
CloseCommand,
MoveCommand,
LookCommand,
DoorsCommand,
QuitCommand,
HelpCommand,
]:
print(" - %s" % cmd.helpDescription())
print()
class AppParseException(ParseException):
pass
class Parser:
def __init__(self):
self.bnf = self.makeBNF()
def makeBNF(self):
invVerb = oneOf("INV INVENTORY I", caseless=True)
dropVerb = oneOf("DROP LEAVE", caseless=True)
takeVerb = oneOf("TAKE PICKUP", caseless=True) | (
CaselessLiteral("PICK") + CaselessLiteral("UP")
)
moveVerb = oneOf("MOVE GO", caseless=True) | empty
useVerb = oneOf("USE U", caseless=True)
openVerb = oneOf("OPEN O", caseless=True)
closeVerb = oneOf("CLOSE CL", caseless=True)
quitVerb = oneOf("QUIT Q", caseless=True)
lookVerb = oneOf("LOOK L", caseless=True)
doorsVerb = CaselessLiteral("DOORS")
helpVerb = oneOf("H HELP ?", caseless=True)
itemRef = OneOrMore(Word(alphas)).setParseAction(self.validateItemName)
nDir = oneOf("N NORTH", caseless=True).setParseAction(replaceWith("N"))
sDir = oneOf("S SOUTH", caseless=True).setParseAction(replaceWith("S"))
eDir = oneOf("E EAST", caseless=True).setParseAction(replaceWith("E"))
wDir = oneOf("W WEST", caseless=True).setParseAction(replaceWith("W"))
moveDirection = nDir | sDir | eDir | wDir
invCommand = invVerb
dropCommand = dropVerb + itemRef("item")
takeCommand = takeVerb + itemRef("item")
useCommand = (
useVerb
+ itemRef("usedObj")
+ Optional(oneOf("IN ON", caseless=True))
+ Optional(itemRef, default=None)("targetObj")
)
openCommand = openVerb + itemRef("item")
closeCommand = closeVerb + itemRef("item")
moveCommand = moveVerb + moveDirection("direction")
quitCommand = quitVerb
lookCommand = lookVerb
doorsCommand = doorsVerb
helpCommand = helpVerb
# attach command classes to expressions
invCommand.setParseAction(InventoryCommand)
dropCommand.setParseAction(DropCommand)
takeCommand.setParseAction(TakeCommand)
useCommand.setParseAction(UseCommand)
openCommand.setParseAction(OpenCommand)
closeCommand.setParseAction(CloseCommand)
moveCommand.setParseAction(MoveCommand)
quitCommand.setParseAction(QuitCommand)
lookCommand.setParseAction(LookCommand)
doorsCommand.setParseAction(DoorsCommand)
helpCommand.setParseAction(HelpCommand)
# define parser using all command expressions
return (
invCommand
| useCommand
| openCommand
| closeCommand
| dropCommand
| takeCommand
| moveCommand
| lookCommand
| doorsCommand
| helpCommand
| quitCommand
)("command") + LineEnd()
def validateItemName(self, s, l, t):
iname = " ".join(t)
if iname not in Item.items:
raise AppParseException(s, l, "No such item '%s'." % iname)
return iname
def parseCmd(self, cmdstr):
try:
ret = self.bnf.parseString(cmdstr)
return ret
except AppParseException as pe:
print(pe.msg)
except ParseException as pe:
print(
random.choice(
[
"Sorry, I don't understand that.",
"Huh?",
"Excuse me?",
"???",
"What?",
]
)
)
class Player:
def __init__(self, name):
self.name = name
self.gameOver = False
self.inv = []
def moveTo(self, rm):
self.room = rm
rm.enter(self)
if self.gameOver:
if rm.desc:
rm.describe()
print("Game over!")
else:
rm.describe()
def take(self, it):
if it.isDeadly:
print("Aaaagh!...., the %s killed me!" % it)
self.gameOver = True
else:
self.inv.append(it)
def drop(self, it):
self.inv.remove(it)
if it.isFragile:
it.breakItem()
def createRooms(rm):
"""
create rooms, using multiline string showing map layout
string contains symbols for the following:
A-Z, a-z indicate rooms, and rooms will be stored in a dictionary by
reference letter
-, | symbols indicate connection between rooms
<, >, ^, . symbols indicate one-way connection between rooms
"""
# start with empty dictionary of rooms
ret = {}
# look for room symbols, and initialize dictionary
# - exit room is always marked 'Z'
for c in rm:
if c in string.ascii_letters:
if c != "Z":
ret[c] = Room(c)
else:
ret[c] = Exit()
# scan through input string looking for connections between rooms
rows = rm.split("\n")
for row, line in enumerate(rows):
for col, c in enumerate(line):
if c in string.ascii_letters:
room = ret[c]
n = None
s = None
e = None
w = None
# look in neighboring cells for connection symbols (must take
# care to guard that neighboring cells exist before testing
# contents)
if col > 0 and line[col - 1] in "<-":
other = line[col - 2]
w = ret[other]
if col < len(line) - 1 and line[col + 1] in "->":
other = line[col + 2]
e = ret[other]
if row > 1 and col < len(rows[row - 1]) and rows[row - 1][col] in "|^":
other = rows[row - 2][col]
n = ret[other]
if (
row < len(rows) - 1
and col < len(rows[row + 1])
and rows[row + 1][col] in "|."
):
other = rows[row + 2][col]
s = ret[other]
# set connections to neighboring rooms
room.doors = [n, s, e, w]
return ret
# put items in rooms
def putItemInRoom(i, r):
if isinstance(r, str):
r = rooms[r]
r.addItem(Item.items[i])
def playGame(p, startRoom):
# create parser
parser = Parser()
p.moveTo(startRoom)
while not p.gameOver:
cmdstr = input(">> ")
cmd = parser.parseCmd(cmdstr)
if cmd is not None:
cmd.command(p)
print()
print("You ended the game with:")
for i in p.inv:
print(" -", aOrAn(i))
# ====================
# start game definition
roomMap = """
d-Z
|
f-c-e
. |
q<b
|
A
"""
rooms = createRooms(roomMap)
rooms["A"].desc = "You are standing on the front porch of a wooden shack."
rooms["b"].desc = "You are in a garden."
rooms["c"].desc = "You are in a kitchen."
rooms["d"].desc = "You are on the back porch."
rooms["e"].desc = "You are in a library."
rooms["f"].desc = "You are on the patio."
rooms["q"].desc = "You are sinking in quicksand. You're dead..."
rooms["q"].gameOver = True
# define global variables for referencing rooms
frontPorch = rooms["A"]
garden = rooms["b"]
kitchen = rooms["c"]
backPorch = rooms["d"]
library = rooms["e"]
patio = rooms["f"]
# create items
itemNames = (
"""sword.diamond.apple.flower.coin.shovel.book.mirror.telescope.gold bar""".split(
"."
)
)
for itemName in itemNames:
Item(itemName)
Item.items["apple"].isDeadly = True
Item.items["mirror"].isFragile = True
Item.items["coin"].isVisible = False
Item.items["shovel"].usableConditionTest = lambda p, t: p.room is garden
def useShovel(p, subj, target):
coin = Item.items["coin"]
if not coin.isVisible and coin in p.room.inv:
coin.isVisible = True
Item.items["shovel"].useAction = useShovel
Item.items["telescope"].isTakeable = False
def useTelescope(p, subj, target):
print("You don't see anything.")
Item.items["telescope"].useAction = useTelescope
OpenableItem("treasure chest", Item.items["gold bar"])
Item.items["chest"] = Item.items["treasure chest"]
Item.items["chest"].isTakeable = False
Item.items["chest"].cantTakeMessage = "It's too heavy!"
OpenableItem("mailbox")
Item.items["mailbox"].isTakeable = False
Item.items["mailbox"].cantTakeMessage = "It's nailed to the wall!"
putItemInRoom("mailbox", frontPorch)
putItemInRoom("shovel", frontPorch)
putItemInRoom("coin", garden)
putItemInRoom("flower", garden)
putItemInRoom("apple", library)
putItemInRoom("mirror", library)
putItemInRoom("telescope", library)
putItemInRoom("book", kitchen)
putItemInRoom("diamond", backPorch)
putItemInRoom("treasure chest", patio)
# create player
plyr = Player("Bob")
plyr.take(Item.items["sword"])
# start game
playGame(plyr, frontPorch)