text adventure question

A

Ara Kooser

I am working on a text adventure game for python to get back into
python programming. My version 0.1 used only functions so I could get
familiar with how those work. I want to move beyond that. I am not
sure what would be a good Python way of handling this. I was
wondering if classes would help? What things should be included in the
main program?

A couple of my goals are:
1) Remove the rooms (or areas) from the main program and have them
called in as needed.
2) Remove NPC's and monsters from the main program and have them
called in as needed.
3) A way of keeping track of time passing in the game
4) Having the main character info stored somewhere else.

Below is pasted a section of my code. Each room is a function that is
later called. I included only one room to keep this short. Thanks you
for suggestions and your time.

Code:

#A sample text adventure game
#Version 0.1
#By Ara Kooser

import random
import sys
import string



#Using global variables for the character
#Want to use a function instead

stre = 9
con = 8
inte = 11
agl = 14
app = 10
mag = 6
sz = 9

hp = 17

reputation = 0

stealth = False

quest1 = False
quest2 = False

cruse = False
poison = False
diseased = False

ducats = 50
lira = 25
florin = 80


equipment = {'Sword': 1, 'Dagger': 1, 'Walking staff': 1, 'Leather Armor':1}
backpack = {'Flint and steel': 1, 'Rations': 7, 'dressing kit': 6,
'waterskin': 2}
belt_pouch = {}

#####################################################################################

day = False

### Global variables for items ###

#grass blades in meadow_1
getGrass_m1 = 0
#mushroom in edge_forest1
getMushroom_ef1 = 0
#orc in forest2
aliveOrc = 0



#####################################################################################

# help function that will give you a list of commands
def help():
print "look, examine (object), n, w, e, s, take (item)"
print "climb, stealth, fishing, herbalism, forage, haggle"
print "field dressing"
print "wield (object), attack, flee, close, withdraw, maintain"
print "backpack, belt pouch, cs"
print "Example: examine book, take ducats, attack orc"

def character_sheet():
print """\
============================================================================
Name: Profession:
Social Class: Race:

============================================================================
Strength
Constitution
Intelligence
Agility
Appearance
Magic
Size
============================================================================
Ducats: Lira: Florin:

Skills: Forage, Haggle, Stealth, Fishing, Herbalism, Climb, Sword, Staff,
Dagger, Field Dressing

Equipment: Backpack, Belt Pouch, Run of the Mill Sword, Dagger, Flint&Steel
1 week food, 2 waterskins, walking stick, dressing kit
============================================================================
"""



def start():
print '''
SAMPLE TEXT ADVENTURE V0.1
You are the last person to leave the small village of Hommlet. The wooden
gate closes behind you and twilight reaches across the land. A dense mist
creeps up out of the ground, only to be kept at bay by the watchmens torches.
Somewhere deep in the woods lies the foul orcs you have tracked for several
days.

'''

print

def outside1():
global hp
global reputation
print " Current Hit Points = ",hp
print " Current Reputation = ",reputation
print ''' You are outside the town gates. The dirt road heads
(N)orth to another
town several days away. The forest lies (E)ast and (W)est through the
meadows. The
rumors you heard in town describe the orcs as being to the west. The town's gate
is to the (S)outh but it is locked for the night.
Type 'help' for a full list of commands.'''
print
prompt_out1()

def out1_desc():
print ''' The fog is growing denser as the sun sets on the meadows.
The exits are (N)orth, (E)ast and (W)est.'''
print
prompt_out1()

def prompt_out1():
global day
prompt_o1 = raw_input("Type a command: ").lower()
try:

if prompt_o1 == "help":
help()
print
prompt_out1()

elif prompt_o1 == "cs":
character_sheet()
print
prompt_out1()

elif prompt_o1 == "status":
print " Current Hit Points = ",hp
print " Current Reputation = ",reputation
prompt_out1()

elif prompt_o1 == "backpack":
print backpack
prompt_out1()

elif prompt_o1 == "belt pouch":
print belt_pouch
prompt_out1()

elif prompt_o1 == "equipment":
print equipment
prompt_out1()

########################################################################################
elif prompt_o1 == "examine fog":
print "The fog seems natural enough for this time of year."
print
prompt_out1()

elif prompt_o1 == "examine road":
print ''' The road is a well travelled dirt road
winding many leagues'''
print
prompt_out1()

elif prompt_o1 == "look":
out1_desc()

#######################################################################################
elif prompt_o1 == "w":
meadow1()

elif prompt_o1 == "e":
meadow2()


elif prompt_o1 == "s":
#if day = False
print "The town's gate is closed for the night"
print
prompt_out1()
#elif
# town_1

elif prompt_o1 == "n":
n_road1()

######################################################################################
elif prompt_o1 == "haggle":
print "There is no one to haggle with here."
promt_out1()

elif prompt_o1 == "stealth":
print "You try and be stealthy"
prompt_out1()

else:
print "Please choose another command. That command is invalid"
print
prompt_out1()

except ValueError:
print "Please choose another command. That command is invalid"
print
prompt_out1()

#there are 5 more rooms that follow using functions

start()
outside1()
 
D

Dennis Lee Bieber

Below is pasted a section of my code. Each room is a function that is
later called. I included only one room to keep this short. Thanks you
for suggestions and your time.
Suggest you try to go back and reread some of the responses to such
a subject from whenever (Unfortunately, I suspect my responses are no
longer available as I run with x-noarchive active).

"Each room is a function" is the first thing that has to go, for
what you ask... In my opinion, that was the biggest flaw in your
approach -- "rooms" don't do things; they just are... so they should
just be some sort of data: a description of the fixed objects, a listing
of movable objects, a listing of exits. "Moving from room to room" is
just a case of using "current room" as an index, finding the list of
exits, retrieving the "room" that is attached to the desired exit, and
setting that to "current room"... Bang: no function calling another
function calling another function, ad infinitum (or until Python's stack
objects to recursion limits).

Write up a description of your game, then look for the major
nouns... These nouns will tend to be the starting point for determining
possible classes; look for verbs, verbs are the actions/methods in a
class; adjectives indicate properties of the class.

{I thought I had a copy of one of these, but seems I was wrong -- they
may be of assistance if you can find them though they may bias toward
Windows graphics}
http://www.amazon.com/Game-Programm..._bbs_sr_1/104-6504898-6017507?ie=UTF8&s=books
http://www.amazon.com/Game-Programm..._bbs_sr_2/104-6504898-6017507?ie=UTF8&s=books

{I can't seem to find any current "text/adventure" programming books,
closest is for full up MUDS -- and a pair from 1984, one using Pascal,
both practically out of print, found on the used market}
http://www.amazon.com/MUD-Game-Prog...f=sr_1_10/104-6504898-6017507?ie=UTF8&s=books

--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
N

Neil Cerutti

I am working on a text adventure game for python to get back
into python programming. My version 0.1 used only functions so
I could get familiar with how those work. I want to move beyond
that. I am not sure what would be a good Python way of handling
this. I was wondering if classes would help? What things
should be included in the main program?

The language used by the Infocom implementors was called ZIL, and
it so happens that the ZIL manual is available for download.
It was sort of a wimpy version of Lisp.

http://www.mv.com/ipusers/xlisper/zil.pdf

Anyway, the ZIL manual explains how Infocom's "library" for text
adventures worked. That should be inspirational for your design.
It's also an entertaining historical artifact, if the history of
computer games is your thing. Here's an amusing sampling:

EXERCISE THREE
Design and implement a full-size game. Submit it to testing,
fix all resulting bugs, help marketing design a package, ship
the game, and sell at lest 250,000 units.
 
S

Steven D'Aprano

I am working on a text adventure game for python to get back into
python programming. My version 0.1 used only functions so I could get
familiar with how those work. I want to move beyond that. I am not
sure what would be a good Python way of handling this. I was
wondering if classes would help? What things should be included in the
main program?

Think about nouns and verbs. Verbs, "doing words", are functions and
methods. Nouns, "things", are classes and objects. You should model nouns
in your game with classes and objects, and verbs (actions) with functions
and methods.

Here is a simple example: a room. A room is a thing. So we might define a
room like this:


class Room:
def __init__(self, name):
self.name = name

Now we create a new room, and fill it:

bedroom = Room("King's Bedroom")
bedroom.description = "You are in a fancy bedroom."
self.contents.append("crown")

Now we create a function for looking around:

def look(here):
"Look around the place you are in"
print here.description

And when you are in the King's bedroom, you (the programmer) would call
the look function like this:

look(bedroom)


But look above: I said that the King's bedroom contains a "crown", using
only a built-in object (str). Maybe that's all you need. Or perhaps you
need something more fancy:

class Object:
# note: not "object", lower case, as that is a built-in type
def __init__(self, name, value, description):
self.name = name
self.value = value
self.description = description


crown = Object("King's crown", 15000, "a gold crown with many jewels")
scepter = Object("King's scepter", 10000, "a silver scepter")
vorpel_sword = Object("vorpel sword", 200, "a strange looking sword")
bedpan = Object("bedpan", 3, "a smelly metal bowl")


Now you can write a function to look at any object:

def look_at(something):
print something.description


and it will work for both objects and rooms.

Let's put some more things in the King's bedroom:

bedroom.contents.extend([crown, bedpan, vorpel_sword, scepter])

Rooms also need doors:

bedroom.north = "wall"
bedroom.south = "wall"
bedroom.west = "wall"
bedroom.east = Room("corridor") # a corridor is just a long, empty room

Perhaps that's not the best way to do it, because now the King's bedroom
has an exit into the corridor, but the corridor has no exit into the
bedroom! Perhaps you need to think about a better way to map the world.
But for now, we can make a really simple fix for that:

corridor = bedroom.east
corridor.west = bedroom
corridor.north = "wall"
corridor.south = "wall"
corridor.east = Room('kitchen')

Hmmm... we're doing a lot of unnecessary typing here. Better to create
rooms with four walls already! Go back and change the definition of a room:

class Room:
def __init__(self, name):
self.name = name
self.north = "wall"
self.south = "wall"
self.east = "wall"
self.west = "wall"


and now you only need to change the directions that AREN'T walls.


Now you have defined the rooms and objects in your text adventure. You
should do something similar for monsters, and any other thing in the game.
Then create functions for verbs:

def fight(what):
if type(what) == Room:
print "Mindlessly attacking the room doesn't " \
"accomplish anything except bruising your fists."
elif type(what) == Object:
print "My, you have a bad temper. You pummel the object. " \
"It doesn't notice."
elif type(what) == Monster:
fight_monster() # you have to write this function
elif type(what) == Royalty:
print "You try to punch the King. His bodyguards leap " \
"out from the shadows and kick the bejeebus out of you, " \
"then drag you into the deepest dungeon. You have a long, "\
long LONG time to consider what you did wrong as the rats " \
"nibble at your toes."
end_game()
else:
print "You don't know how to fight", what


def say(words, what):
"""Say <words> to <what>."""
if "poot" in words:
print "Do you kiss your mommy with that potty-mouth?"

if type(what) == Room:
print "The room doesn't answer."
elif type(what) == Monster:
print "The monster doesn't understand English."
# and you can write the rest


One suggested improvement: if you find yourself writing lots of code like
the above, testing "if type(what) == Room" etc., there is a better way of
doing it. Move that block of code into a method of Room:

class Room:
# def __init__ stays the same as before
def hears(words):
"""The player says <words> to the Room, and the Room responds."""
print "The room doesn't answer."

and then your function becomes much simpler:

def say(words, what):
"""Say <words> to <what>."""
if "poot" in words:
print "Do you kiss your mommy with that potty-mouth?"
else:
# the player talks, so <what> hears and responds.
what.hears(words)


There is more that you can do too. You need a variable to store the
player's current position:

start = Room("the village")
position = start

And you need a function that understands written commands. Here is one
suggestion: define a class for commands:

commandlist = {}
class Command:
def __init__(self, name):
self.name = name
commandlist[name] = self

then define commands themselves:

Command("go")
Command("eat")
Command("sleep")
Command("fight")

(There is a lot more to it that that, I leave the rest to you.)
 
E

Eric_Dexter

When I was playing around with adventure games using oop (in c++)
I had all charecters defined as a type, no need to seperate non-player
charecters with user defined charecters. Makes it easier to create a
party of charecters or monsters. I left it up to the logic of the
program to define behavior after it was loaded in.

http://www.stormpages.com/edexter/csound.html
 
S

Steven D'Aprano

Suggest you try to go back and reread some of the responses to such
a subject from whenever (Unfortunately, I suspect my responses are no
longer available as I run with x-noarchive active).

That seems horribly anti-social, not to mention counter-productive. What's
the point of writing to the newsgroup if your response won't be around by
the time they go to read it? After all, what's the point of treating a
newsgroup like comp.lang.python as a chat group?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top