9 Replies - 962 Views - Last Post: 25 March 2013 - 03:28 AM Rate Topic: -----

#1 little_fatty  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 22-March 13

Text based adventure game hp issue

Posted 22 March 2013 - 08:56 PM

import textwrap # nice and clean
import sys      # exit

scenes = {
    "opening_scene": {
        "description": "You are a rat, a rat that life dealt an interesting hand to. What you " \
                       "do with that hand is up to you. Unfortunately, you know nothing beyond " \
                       "your cold stainless steel cage. Fortunately, you were in the delightful " \
                       "position to be part of an experiment that taught rats how to read. Due " \
                       "to a careless mistake on the part of 'Hairless Ones' an adventure awaits. " \
                       "The door to your cage has been left open.",
        "paths": [
            { "go_to": "stay",      "phrase": "wait for the careless 'Hairless One' to return and right the wrong."},
            { "go_to": "first_step","phrase": "eagerly seize the opportunity, taking your first step into the world." }
        ]
        
    },
    "stay": {
        "description": "You've noticed some patterns in the time you've been here, it should be " \
                       "back one last time before the world goes dark. You hear a familiar howl, "    \
                       "a creature in pain. You've heard it many times, it almost slips past you.",
        "paths": [
            { "go_to": "wait_more",        "phrase": "continue to wait." },
            { "go_to": "slow_first_steps", "phrase": "finally decide to investigate the world." }
        ]
    },
    "wait_more": {
        "description": "You aren't much of a daring soul afterall, you decide not to check things out. It  "   \
                       "doesn't sound like whoever is out there is having that much fun anyway. You " \
                       "have everything you need right here, no need to leave.  Suddenly, the lights " \
                       "flicker and go out. Looks like the 'Hairless One' should be called the 'Careless " \
                       "One' right? It was a stupid joke, but you laugh at yourself anyway. It can't hurt " \
                       "to have a little peek outside can it? Plus the cage doesn't seem as safe with the " \
                       "door wide open.",
        "paths": [
            { "go_to": "skeptical", "phrase": "cautiously take your first steps into the world." },
            { "go_to": "call_out",  "phrase": "you call out into the dark to find out if anyone can hear you." },
            { "go_to": "close_cage","phrase": "decide to try to close the door yourself."}
            ]
    },
    "first_step": {
        "description": "You trip running out of your cage. You have been waiting for the day to get " \
                       "out of that awful cage your entire life.  Your ankle hurts, but you seem to be " \
                       "able to shrug it off. You hear a shrieking howl, you've heard it often, but this " \
                       "time is differnt, you aren't behind the safety of your bars. A shiver runs down " \
                       "your spine.",
        "paths": [
            { "go_to": "wait_more", "phrase": "quickly jump back into your cage." },
            { "go_to": "be_brave",  "phrase": "face your fears." }
        ]
}
    }

# Function definitions
def menu_input(paths):
    prompt = "Make a selection (0 - %i): " % len(paths)

    try:
        choice = raw_input(prompt)
        menu_selection = int(choice)

        if menu_selection == 0:
            selected_path = "quit"
        else:
            index = menu_selection - 1
            selected_path = paths[ index ]
    except (IndexError, ValueError):
        print choice, "is not a valid selection!"
        # Try again!
        selected_path = menu_input(paths)

    return selected_path

def select_path(paths):
    # Show the menu for this scene.
    for i in range(0, len(paths)):
        path = paths[i]
        menu_item = i + 1
        print "\t", menu_item, path["phrase"]

    print "\t(0 Quit)"
    # Get the user selection from the menu.
    next_step = menu_input(paths)
    return next_step

def play_game(start_scene):
    scene = start_scene
    global health
    health = 100

    while 1 == 1:  # loop
        description = scene["description"]
        paths = scene["paths"]
        if health > 0:
            print "HP ", health, "/100"
            print textwrap.fill(description)
            next_step = select_path(paths)

            if next_step == "quit":
                print "Good bye!"
                sys.exit()
            else:
                scene = scenes[ next_step["go_to"] ]
                print "You ", next_step["phrase"]
        else:
            print "You have died."

# Game starts here.
play_game(scenes["opening_scene"])




So I am trying to make a text based adventure game as a gift for my sister. I don't have much coding experience, just thought it would be something fun to do.

I have hit my first major hiccup and I can't seem to figure it out. I've been working a few days on trying to figure out the problem and its killing me haha, I'm clueless. So as you can see I have "global health" after the scene "first_step" I want the player to lose a few health points. I can get it to work if I don't have the dictionary and have it as a series of if:then statements, but that seems pretty sloppy to me. When I keep the scenes in the dictionary, its a lot easier for me to keep track of the story, so I'd rather keep it this way.

So anywho, that said I have had three different results (if I don't get an error)

  • The players health stays at 100
  • The players health drops a few points, and the next scene continues to drop until death.
  • The players health drops a little, but in the next scene jumps back up to 100.


Any ideas?

Is This A Good Question/Topic? 0
  • +

Replies To: Text based adventure game hp issue

#2 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 759
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: Text based adventure game hp issue

Posted 22 March 2013 - 09:20 PM

Nowhere in the code you provided is the health decremented. Because of that, we can't see the behavior you mentioned. As it stands right now, it will stay at 100 cause you never change it :-P

This post has been edited by atraub: 22 March 2013 - 09:22 PM

Was This Post Helpful? 1
  • +
  • -

#3 little_fatty  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 22-March 13

Re: Text based adventure game hp issue

Posted 22 March 2013 - 09:54 PM

I took everything I've tried out, because they didn't work. I'm not asking you to write my code for me, just looking for someone to point me in the right direction.

Is there a way to implement it in the dictionary directly. Like at one point I wrote in the scenes
 "first_step": {
        "damage": health - 10,
        "description": "You have been waiting for the day to get out of that awful cage. You trip over a bar " \
                       "in your excitement, you almost fall off the small ledge. Your ankle hurts, but you seem " \
                       "to be able to shrug it off. You hear a shrieking howl, you've heard it often, but this " \
                       "time is differnt, you aren't behind the safety of your bars. A shiver runs down " \
                       "your spine.",
        "paths": [
            { "go_to": "wait_more", "phrase": "quickly jump back into your cage." },
            { "go_to": "be_brave",  "phrase": "face your fears." }


It got mad at me if every scene didn't have a "damage" so I made the rest "damage": health - 0, which obviously is what made the health drop, then pop back up the next scene.

I can't remember the rest of the 1000 things I've tried, like I've said its all I've been working on the last few days after work.
Was This Post Helpful? 0
  • +
  • -

#4 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 759
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: Text based adventure game hp issue

Posted 22 March 2013 - 10:04 PM

This, I can work with. I implemented the code you just gave me and made a tiny tweak here and there and your hp works just fine now. I'd recommend using a word other than damage, such as change. If you did that, you could make it more natural by adding the change to the hp and having damage be a negative change and gaining health be a positive one. I added a comment to the line of code that I changed, take a look and let me know if you have any questions :)

import textwrap # nice and clean
import sys      # exit

health = 100
scenes = {
    "opening_scene": {
        "description": "You are a rat, a rat that life dealt an interesting hand to. What you " \
                       "do with that hand is up to you. Unfortunately, you know nothing beyond " \
                       "your cold stainless steel cage. Fortunately, you were in the delightful " \
                       "position to be part of an experiment that taught rats how to read. Due " \
                       "to a careless mistake on the part of 'Hairless Ones' an adventure awaits. " \
                       "The door to your cage has been left open.",
        "paths": [
            { "go_to": "stay",      "phrase": "wait for the careless 'Hairless One' to return and right the wrong."},
            { "go_to": "first_step","phrase": "eagerly seize the opportunity, taking your first step into the world." }
        ]
        
    },
    "stay": {
        "description": "You've noticed some patterns in the time you've been here, it should be " \
                       "back one last time before the world goes dark. You hear a familiar howl, "    \
                       "a creature in pain. You've heard it many times, it almost slips past you.",
        "paths": [
            { "go_to": "wait_more",        "phrase": "continue to wait." },
            { "go_to": "slow_first_steps", "phrase": "finally decide to investigate the world." }
        ]
    },
    "wait_more": {
        "description": "You aren't much of a daring soul afterall, you decide not to check things out. It  "   \
                       "doesn't sound like whoever is out there is having that much fun anyway. You " \
                       "have everything you need right here, no need to leave.  Suddenly, the lights " \
                       "flicker and go out. Looks like the 'Hairless One' should be called the 'Careless " \
                       "One' right? It was a stupid joke, but you laugh at yourself anyway. It can't hurt " \
                       "to have a little peek outside can it? Plus the cage doesn't seem as safe with the " \
                       "door wide open.",
        "paths": [
            { "go_to": "skeptical", "phrase": "cautiously take your first steps into the world." },
            { "go_to": "call_out",  "phrase": "you call out into the dark to find out if anyone can hear you." },
            { "go_to": "close_cage","phrase": "decide to try to close the door yourself."}
            ]
    },
    "first_step": {
       "damage": 10,
       "description": "You have been waiting for the day to get out of that awful cage. You trip over a bar " \
                      "in your excitement, you almost fall off the small ledge. Your ankle hurts, but you seem " \
                      "to be able to shrug it off. You hear a shrieking howl, you've heard it often, but this " \
                      "time is differnt, you aren't behind the safety of your bars. A shiver runs down " \
                      "your spine.",
       "paths": [
           { "go_to": "wait_more", "phrase": "quickly jump back into your cage." },
           { "go_to": "be_brave",  "phrase": "face your fears." },
           ]
}
    }

# Function definitions
def menu_input(paths):
    prompt = "Make a selection (0 - %i): " % len(paths)

    try:
        choice = raw_input(prompt)
        menu_selection = int(choice)

        if menu_selection == 0:
            selected_path = "quit"
        else:
            index = menu_selection - 1
            selected_path = paths[ index ]
    except (IndexError, ValueError):
        print choice, "is not a valid selection!"
        # Try again!
        selected_path = menu_input(paths)

    return selected_path

def select_path(paths):
    # Show the menu for this scene.
    for i in range(0, len(paths)):
        path = paths[i]
        menu_item = i + 1
        print "\t", menu_item, path["phrase"]

    print "\t(0 Quit)"
    # Get the user selection from the menu.
    next_step = menu_input(paths)
    return next_step

def play_game(start_scene):
    scene = start_scene
    global health
    health = 100

    while 1 == 1:  # loop
        description = scene["description"]
        paths = scene["paths"]
        if health > 0:
            print "HP ", health, "/100"
            print textwrap.fill(description)
            next_step = select_path(paths)

            if next_step == "quit":
                print "Good bye!"
                sys.exit()
            else:
                scene = scenes[ next_step["go_to"] ]
                health -= scene.get("damage",0) #gets damage if there is a "damage" entry, otherwise returns 0
                print "You ", next_step["phrase"]
        else:
            print "You have died."

# Game starts here.
play_game(scenes["opening_scene"])



EDIT:
I wasn't accusing you of anything boss. I just wanted to fix the error you came with initially. If you'd like to discuss different approaches you could take with this application and perhaps consider a redesign, that's completely fine. I just like to keep goals narrow and clearly defined. In truth, I was just trying to understand your mindset so that we could find a solution that was intuitive to you... also I wanted to do less work lol.

This post has been edited by atraub: 22 March 2013 - 10:08 PM

Was This Post Helpful? 1
  • +
  • -

#5 little_fatty  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 22-March 13

Re: Text based adventure game hp issue

Posted 23 March 2013 - 01:54 AM

Thanks, it works like a charm! Acts exactly how I wanted, perfect. Thanks for your time!
Was This Post Helpful? 0
  • +
  • -

#6 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5775
  • View blog
  • Posts: 12,587
  • Joined: 16-October 07

Re: Text based adventure game hp issue

Posted 23 March 2013 - 03:33 AM

The approach of static text, while good for a choose your own adventure book, isn't much more flexible than that.

I would go with a function for each scene. Most of them will be boiler plate, but not all. Sometimes you'll have to react to certain conditions. Right now it's damage. What if you then want your rat to pick something up? Or throw a switch? Or basically have a scene change in some way.

This kind of layout will allow you to adapt to anything you can imagine in the future:

import textwrap

def show_description(d):
	print textwrap.fill(d)

def scene_opening(state):
	show_description("You are a rat, a rat that life dealt an interesting hand to. What you do with that hand is up to you. Unfortunately, you know nothing beyond your cold stainless steel cage. Fortunately, you were in the delightful position to be part of an experiment that taught rats how to read. Due to a careless mistake on the part of 'Hairless Ones' an adventure awaits. The door to your cage has been left open.")
	select_path(state, [
		(scene_stay, "wait for the careless 'Hairless One' to return and right the wrong."),
		(scene_first_step, 'eagerly seize the opportunity, taking your first step into the world.')
		])

def scene_wait_more(state):
	show_description("You aren't much of a daring soul afterall, you decide not to check things out. It  doesn't sound like whoever is out there is having that much fun anyway. You have everything you need right here, no need to leave.  Suddenly, the lights flicker and go out. Looks like the 'Hairless One' should be called the 'Careless One' right? It was a stupid joke, but you laugh at yourself anyway. It can't hurt to have a little peek outside can it? Plus the cage doesn't seem as safe with the door wide open.")
	select_path(state, [
		(scene_skeptical, 'cautiously take your first steps into the world.'), 
		(scene_call_out, 'you call out into the dark to find out if anyone can hear you.'), 
		(scene_close_cage, 'decide to try to close the door yourself.')
		])

def scene_first_step(state):
	show_description("You trip running out of your cage. You have been waiting for the day to get out of that awful cage your entire life.  Your ankle hurts, but you seem to be able to shrug it off. You hear a shrieking howl, you've heard it often, but this time is differnt, you aren't behind the safety of your bars. A shiver runs down your spine.")
	show_description("Your fear causes your hear to flutter. You take damage!")
	doDamage(state, 2)
	if not isDone(state):
		select_path(state, [
			(scene_wait_more, 'quickly jump back into your cage.'),
			(scene_be_brave, 'face your fears.')
			])

def scene_stay(state):
	show_description("You've noticed some patterns in the time you've been here, it should be back one last time before the world goes dark. You hear a familiar howl, a creature in pain. You've heard it many times, it almost slips past you.")
	select_path(state, [
		(scene_wait_more, 'continue to wait.'), 
		(scene_slow_first_steps, 'finally decide to investigate the world.')
		])

def scene_coming_soom(state):
	show_description("Coming soon")
	state['scene'] = scene_quit

def scene_slow_first_steps(state):
	scene_coming_soom(state)

def scene_be_brave(state):
	scene_coming_soom(state)

def scene_quit(state):
	state['done'] = True
	print "Good bye!"


def get_int(prompt):
	n = None
	while n==None:
		try:
			choice = raw_input(prompt)
			n = int(choice)
		except:
			print choice, "is not a valid selection!"
	return n

def select_path(state, paths):
	for i, (jump, phrase) in enumerate(paths):
		print "\t", (i+1), phrase
	print "\t(0 Quit)"
	menu_selection = get_int("Make a selection (0 - %i): " % len(paths))
	if menu_selection==0:
		state['scene'] = scene_quit
	elif menu_selection>0 and menu_selection<=len(paths):
		(jump, phrase) = paths[menu_selection-1]
		print "You ", phrase
		state['scene'] = jump
	else:
		print menu_selection, "is not a valid selection!"


def doDamage(state, hp):
	state['health'] -= hp
	if isAlive(state):
		showHealth(state)
		return True
	else:
		print "You have died."
		state['done'] = True
		return False

def isAlive(state):
	return state['health'] > 0
	
def isDone(state):
	return state['done']

def showHealth(state):
	print "HP ", state['health'], "/100"


def play(state):
	while not isDone(state):
		showHealth(state)
		state['scene'](state)

play({'health': 100, 'scene': scene_opening, 'done': False })



I had fun playing with this.

Hope it helps.
Was This Post Helpful? 0
  • +
  • -

#7 little_fatty  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 22-March 13

Re: Text based adventure game hp issue

Posted 23 March 2013 - 07:40 PM

That is something I def. want to include. I want to add an inventory and abilities one can learn that open new options. Would that be impossible with a dictionary?
Was This Post Helpful? 0
  • +
  • -

#8 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 759
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: Text based adventure game hp issue

Posted 23 March 2013 - 08:50 PM

Nothing's impossible with a dictionary!! Ok, that part was a lie, but it is doable with your current dictionary approach... but it will be difficult/weird/awkward. You'll want to create a separate structure for inventory rather than trying to use that massive dictionary. Same is true for abilities

This post has been edited by atraub: 23 March 2013 - 08:51 PM

Was This Post Helpful? 0
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5775
  • View blog
  • Posts: 12,587
  • Joined: 16-October 07

Re: Text based adventure game hp issue

Posted 24 March 2013 - 07:42 AM

Games have "state." That is, the data that reflects the current state in the game. This is also, essentially, the same game data.

You can see how I used a dictionary called state to avoid globals and also reinforce the concept. You can easily add an inventory by simply adding an inventory item to state dictionary.

More importantly, you can express the state of the "scene" as well. If the player enters a scene for the first time, you make an entry in state reflecting what they see. Specifically, for inventory, what items are there. The next time the player goes there, you check for that entry. If it's there, you use it. In this way, you can have the player remove items and have them stay removed.

I have an old Java implementation of this floating around the board. I may have to make a Python version...
Was This Post Helpful? 0
  • +
  • -

#10 little_fatty  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 22-March 13

Re: Text based adventure game hp issue

Posted 25 March 2013 - 03:28 AM

Sick,gunna work on this a bit. Thanks for all of your help! I'm sure I will be back with some more questions in the future!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1