HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Small text adventure

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
textsmalladventure

Problem

I made this small text adventure just to see what I could do with Python, and I'm basically wondering how it could be optimized, especially my combat as right now I'd have to rewrite it every time I want combat.

``
import time
import random

spider_damage = 10
inventory = []
iron_dagger_damage = random.randint(5,12)
player_damage = iron_dagger_damage

def intro():
print("You are lost in the woods. You know that if you follow the right path, you will get to the nearest village.")
time.sleep(1)
print("You see that there are 2 paths ahead. In which one do you want to go(left or right)")
def left_or_right():
choice = ""
print("Where do you want to go, left or right?")
choice = input()
return choice

def intro_end(left_or_right):
if choice == "left":
print("You go down the path to the left and...")
time.sleep(1)
print("You die a horrible death")
input()
quit()

elif choice == "right":
print("You go down the path to the right and...")
time.sleep(1)
print("Notice that the trees are thinning out")
time.sleep(1)

def iron_dagger():
iron_dagger = ''
print("You see a flash of light in the forest. Do you want to risk the forest to go see what it was?(yes or no)")
iron_dagger = input()
return iron_dagger

def choice1_end(iron_dagger):
if iron_dagger == "yes":
print("You find an iron dagger!")
inventory.append("iron dagger")
print(inventory)
elif iron_dagger == "no":
print("You continue on")
else:
iron_dagger

def part_1():
print("You finally get out of the forest")
time.sleep(1)
print("You see a giant frost spider in the distance")
print("""
(
)
(
/\ .-" "-. /\
//\\/ ,,, \//\\
|/\| ,;;;;;, |/\|
//\\\;-" "-;///\\
// \/ . \/ \\
(| ,-_| \ | / |_-, |)
//
__\.-.-./__`\\
// /.-((

Solution

The most obvious problem is that parts of your code don't make any sense. For example:

iron_dagger()
iron_dagger = iron_dagger()
choice1_end(iron_dagger)


What?! This:

  • Calls the function and ignores the returned value;



  • Calls the function again and assigns the return value to the name of the function, preventing further access to the function; and



  • Passes the value to another function.



It's not much better inside iron_dagger where, in some sort of homage to Inception, there is a variable iron_dagger. You can simplify those lines to:

choice1_end(iron_dagger())


And should strongly consider renaming the variable.

It seems odd generally to split the program up the way you do. Why separate the function where the choice is made from the function for making the choice and the function where the choice has impact? Instead of:

intro()
choice = left_or_right()
intro_end(left_or_right)


Just have:

intro()


and handle getting and dealing with the choice inside that function (still potentially with sub-functions):

def section():
    print("introductory blah")
    choice = make_choice()
    if choice == "whatever":
        do_the_thing
    ...


This keeps all appropriate logic together.

Next is your reliance on scoping for variable access. Instead of e.g.

def intro_end(left_or_right):
    ...

choice = left_or_right()
intro_end(left_or_right)


where you pass the input function as an argument, make the return value from that function the argument:

def intro_end(choice):
    ...

intro_end(left_or_right())


Generally, prefer explicit arguments and return values to scoping or globals. It makes development and testing much, much easier. As another example, you should pass inventory around explicitly.

You have little in the way of input validation. There is a good community wiki on SO for this, I recommend modifying e.g. left_or_right to only ever return 'left' or 'right'. Then consider abstracting that to a def input_str(prompt, choices): function.

Your encounter suggests the use of OOP to me. Rather than two variables John_Smith_hp and Giant_spider_hp, this could be e.g.

class Character:

    def __init__(self, name, hp):
        self.name = name
        self.hp = hp

player = Character("John Smith", 50)
enemy = Character("Giant spider", 30)


The Characters could also have attributes like damage or inventory...

if choice == 'yes':
    player.inventory.append('iron dagger')
    player.damage += random.randint(5, 12)

Code Snippets

iron_dagger()
iron_dagger = iron_dagger()
choice1_end(iron_dagger)
choice1_end(iron_dagger())
intro()
choice = left_or_right()
intro_end(left_or_right)
def section():
    print("introductory blah")
    choice = make_choice()
    if choice == "whatever":
        do_the_thing
    ...
def intro_end(left_or_right):
    ...

choice = left_or_right()
intro_end(left_or_right)

Context

StackExchange Code Review Q#54016, answer score: 11

Revisions (0)

No revisions yet.