text adventure question

Discussion in 'Python' started by Ara Kooser, Dec 2, 2006.

  1. Ara Kooser

    Ara Kooser Guest

    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()
     
    Ara Kooser, Dec 2, 2006
    #1
    1. Advertisements

  2. 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

    HTTP://wlfraed.home.netcom.com/
    (Bestiaria Support Staff: )
    HTTP://www.bestiaria.com/
     
    Dennis Lee Bieber, Dec 2, 2006
    #2
    1. Advertisements

  3. Ara Kooser

    Neil Cerutti Guest

    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.
     
    Neil Cerutti, Dec 3, 2006
    #3
  4. 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.)
     
    Steven D'Aprano, Dec 3, 2006
    #4
  5. Ara Kooser

    Eric_Dexter Guest

    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
     
    Eric_Dexter, Dec 3, 2006
    #5
  6. 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?
     
    Steven D'Aprano, Dec 3, 2006
    #6
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.