Zork like text based game python

Started by
18 comments, last by BeerNutts 10 years, 1 month ago

hello,

i've an absolute beginner and i'm trying to create a zork like text based game to learn. I have 2 questions, the first is that when I add 2 items to the list "inventory" it displays them like this:

flask, knife

flask, knife

so it displays them twice and i'm not sure why, also, i'd like it to just display them each on a different line such as

flask

knife

secondly, i'm sure what I have done so far is a really bad an inefficient way of doing it, are there any tips or ideas I could use to write it better and re-use certain code for the commands etc before I go further? thanks a lot


import os, random, time

global name
name = "unknown"
inventory = []

def displayinventory():
    print("\nInventory:")
    for i in inventory:
        print(inventory)

def introduction():
    global name
    print("banner")
    print("do intro text")
    name = str(input("Your name:"))

def easternfields():
    here = 1
    knifetaken = 0
    print("\nEastern Fields")
    print("\nDescription")
    while here == 1:
        command = str(input("> "))
        command.lower()
        lowcommand = command.lower()
        if lowcommand == "inv":
            displayinventory()
        elif lowcommand == "look":
            print("\nYou look around the eastern fields")
        elif lowcommand == "take knife" and knifetaken != 1:
            print("\nknife taken.")
            knifetaken = 1
            inventory.append('knife')
            lowcommand = ""
        elif lowcommand == "take knife" and knifetaken == 1:
            print("knife already taken")
        elif lowcommand == "drop":
            whichitem = str(input("item: "))
            if whichitem in inventory:
                inventory.remove(whichitem)
        else:
            print("\nCommand not recognised")


def southernfields():
    here = 1
    flasktaken = 0
    print("\nSouthern Fields")
    print("\nDescription")
    while here == 1:
        command = str(input("> "))
        command.lower()
        lowcommand = command.lower()
        if lowcommand == "inv":
            displayinventory()
        elif lowcommand == "look":
            print("\nYou look around the southern fields")
        elif lowcommand == "take flask" and flasktaken != 1:
            print("\nflask taken.")
            flasktaken = 1
            inventory.append('flask')
            lowcommand = ""
        elif lowcommand == "take flask" and flasktaken == 1:
            print("flask already taken")
        elif lowcommand == "drop":
            whichitem = str(input("item: "))
            if whichitem in inventory:
                inventory.remove(whichitem)
        elif lowcommand == "go east":
            here = 0
            easternfields()
        else:
            print("\nCommand not recognised")


southernfields()
Advertisement

There are a few things going on that you should think about:

def displayinventory():
print("\nInventory:")
for i in inventory:
print(inventory)

You're printing "inventory" for each item "i". You should have: "print i" not "print inventory" (no need for () around the parameter)

Also, you really should have a function defined for when you wait for input from your user, and, you should have set descriptions ready for generic responses. Otherwise, you'll have the exact same lines of code for waiting on input in all your rooms.

When you're more comfortable, you really should have an external file that lays out all the rooms, items in a room, actions possible in a room, and exits (and what rooms they connect to).

You'll get there, but take baby steps. If you find your self doing the same thing over and over, think about how you could make it a function, and do it just once.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

I am not sure about what language you are using (I should pay more attention to titles), but it looks to me like this code:


for i in inventory:
        print(inventory)

actually means: "For all items in the inventory, print the entire inventory." ph34r.png'd
So, maybe this will work?


for i in inventory:
        print( inventory[i] )
// Or maybe
for i in inventory:
        print( i )

About the efficiency, don't worry, ignoring this is probably the best thing you can do for now.
Concentrate on learning the basics first, then you can start to think about efficiency.

You might also think about having an inventory for each area. If the user drops the knife in an area and wanders elsewhere, he should be able to return to the area and pick the knife back up. You could also use an area inventory to fill out the "look" command. If the user picks something up, put it in the player inventory and remove it from the area inventory. Rather than setting up separate variables for each "taken" item, if the player "takes" something: look in his inventory to see if he already has it. Then check the area inventory to see if the item's there.

>look

You look around the fields.

You see a knife.

You see a flask.

>take bottle

You already have the bottle.

>take balloon

There is no balloon around here.

>take tree

The trees around here are firmly rooted.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

There are a few things going on that you should think about:


def displayinventory():
print("\nInventory:")
for i in inventory:
print(inventory)

You're printing "inventory" for each item "i". You should have: "print i" not "print inventory" (no need for () around the parameter)

That is only valid if you are not using python 3.0+ so it is generally consider a better practice to use the parentheses because it works across more version of python.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

thanks alot for your help and suggestions guys,

I did indeed fix the inventory listing problem by printing i instead of inventory


for i in inventory:
        print(i)

I also took up the suggestion of adding an item list for each area, allowing the user to drop items and return to them with this code for example:


southernfieldsitems = ['flask', 'shoe']

elif lowcommand == "look":
            print("\nYou look around the southern fields")
            print("\navailable items: ")
            for i in southernfieldsitems:
                print(i)

elif lowcommand == "take":
            takewhat = str(input("item: "))
            takewhatlow = takewhat.lower()
            if takewhatlow in southernfieldsitems:
                inventory.append(takewhatlow)
                southernfieldsitems.remove(takewhatlow)
            else:
                print("There is no item of that sort here")
        elif lowcommand == "drop":
            whichitem = str(input("item: "))
            if whichitem in inventory:
                inventory.remove(whichitem)
                southernfieldsitems.append(whichitem)
        elif lowcommand == "go east":
            here = 0
            easternfields()


I thought about creating a function that waits for the commands but i'm not quite sure how i'd do it because some commands will depend on whats in the area, plus I intend to add things like NPCs etc later on and combat. I suppose I wouldn't know how to pass all the relevant information back and forth between a command function and the area function so it knows what's going on.

also you'll notice i've been using 2 variables for the "take" and "drop" command, after you type either it asks you to type which item, that is because I don't know how to check the second word in a string variable so that instead the user could simply type "take flask" all in one line, then I check the second word against the areas item list. Is there an easy way to do that?

thanks again :)

Something like this should help.


splitCommand = lowcommand.split()
if splitCommand[0] == 'take':
    takewhat = splitCommand[1]

The split method of strings returns a list of what was in the string separated by whitespace like spaces. So 'take flask' would return ['take', 'flask'].

There are a few things going on that you should think about:


def displayinventory():
print("\nInventory:")
for i in inventory:
print(inventory)

You're printing "inventory" for each item "i". You should have: "print i" not "print inventory" (no need for () around the parameter)

That is only valid if you are not using python 3.0+ so it is generally consider a better practice to use the parentheses because it works across more version of python.

-Josh

You would be printing i as a tuple in versions of Python preceding 3.0 .

Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.

Something like this should help.


splitCommand = lowcommand.split()
if splitCommand[0] == 'take':
    takewhat = splitCommand[1]

The split method of strings returns a list of what was in the string separated by whitespace like spaces. So 'take flask' would return ['take', 'flask'].

yep, works perfect thank you





There are a few things going on that you should think about:


def displayinventory():
print("\nInventory:")
for i in inventory:
print(inventory)

You're printing "inventory" for each item "i". You should have: "print i" not "print inventory" (no need for () around the parameter)

That is only valid if you are not using python 3.0+ so it is generally consider a better practice to use the parentheses because it works across more version of python.

-Josh

You would be printing i as a tuple in versions of Python preceding 3.0 .

Not sure what you mean, but calling print(i) simply prints out the value of i in either python2 or python3 and has nothing to do with tuples.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

This topic is closed to new replies.

Advertisement