9
\$\begingroup\$

I am brand new to coding in Python, and programming in general. I have picked up the Learning Python book and have been slowly making my way through it. I decided that I would try to implement what I have learned by writing a simple word-based game that I could run through the Mac OS Terminal.

I would love to hear any feedback on any segment of the code, or on the code as a whole! Please bear in mind that any suggestion that would be considered "advanced" would be lost on me at this point in my learning.

There might be a lot of irrelevant code. This practice was mostly to drill in what I have been learning.

###___def___ practice in game format

import time

def skip():       
    print

# Created to create adequate space after endgame()

def resskip():    
    print() * 10

#Used to repeat inputs if wrong input is selected
#Also used reset "inpot" value for choiceloop2() for sceneselect when
#an incorrect input is selected

def choiceerror2(option, frame): 
    inpot = option
    if inpot == '1':
        return choiceloop2(inpot, frame)
    elif inpot == '2':
        return choiceloop2(inpot, frame)
    else:
        print('Invalid option! Please try again!')
        inpot = raw_input('What do you choose?:  ')
        return choiceerror2(inpot, frame)

#has the same functionality as choiceerror2(), scenes with 3 choices

def choiceerror3(option, frame):
    inpot = option
    if inpot == '1':
        return choiceloop3(inpot, frame)
    elif inpot == '2':
        return choiceloop3(inpot, frame)
    elif inpot == '3':
        return choiceloop3(inpot, frame)
    else:
        print('Invalid option! Please try again!')
        inpot = raw_input('What do you choose?:  ')
        return choiceerror3(inpot, frame)

#used primarily to assign a "scene" value for sceneselect

def choiceloop2(option, frame):
    inpot = option
    if inpot == '1':
        return sceneselect(frame, '1')
    else:
        return sceneselect(frame, '2')

#used for the same thing as choiceloop3(), scenes with 3 choices

def choiceloop3(option, frame):
    inpot = option
    if inpot == '1':
        return sceneselect(frame, '1')
    elif inpot == '2':
        return sceneselect(frame, '2')
    else:
        return sceneselect(frame, '3')

#selects scenes based on the "frame" value assigned at the end of each
#scene, as well as the scene value assigned during choiceloop

def sceneselect(frame, scene):
    if frame == '1':
        if scene == '1':
            scenesewer()
        else:
            scenefield()
    elif frame == '2sewer':
        if scene == '1':
            scenefield()
        if scene == '3':
            scenehall()
    elif frame == '2field':
        scenesewer()

#End of game prompt. Also has invalid input loop prompting for re-input

def endgame():
    print('YOU HAVE DIED....\nWould you like to try again?:   ')
    time.sleep(2)
    inpot = raw_input('Y/N ...  ')
    if inpot == 'Y':
        resskip()
        main()
    elif inpot == 'N':
        skip()
        print('Thank you for playing!')
        exit()
    else:
        print('Invalid input!')
        endgame()

#Win Game prompt.

def wingame():
    print('Thank you for playing!')
    time.sleep(5)
    exit()

#Beginning of game

def opening():
    skip()
    skip()
    print("Welcome to the beginning of an adventure...") 
    time.sleep(5)
    skip()
    print('There will be many paths to choose from...')
    time.sleep(5)
    skip()
    print('Will you be able to make it to the end?')
    time.sleep(5)
    skip()
    print('You wake up in a dungeon, you are injured and do not have any weapons.\nYou hear loud growling, and shortly after, some scratches at a door behind you.\nYou become frightened.\nYou see there is a window with a few broken bars that you can squeeze through to make an escape.\nLikewise, there is a sewer you can try to escape through!')
    time.sleep(2)
    skip()
    print('1 = Sewer, 2 = Window')
    inpot = raw_input('What do you choose?:  ')
    skip()
    if inpot == '1':
        choiceloop2(inpot, '1')
    elif inpot == '2':
        choiceloop2(inpot, '1')
    else:
        choiceerror2(inpot, '1')

#Field "scene"

def scenefield():
    print('You find yourself in a large field outside of the dungeon.\nYou see an apple tree. Hoping to find food, you begin to approach it\nAs you approach the tree, two wolves show themselve!\nYou turn to run back to where you came from. As you make your way, you spot two other escape routes.\n One is a large hole in the side of the dungeon leading down.\nThe other is a river crossing.\n....')
    skip()
    time.sleep(15)
    print('1 - Big Hole, 2- River Crossing')
    inpot = raw_input('Which do you choose?:   ')
    if inpot == '1':
        skip()
        print('You jump through the hole wihout hesitation. You slide back down into the dungeon.\n...')
        time.sleep(3)
        choiceloop2(inpot, '2field')
    elif inpot == '2':
        skip()
        time.sleep(3)
        print('You jump into the river in an attempt to cross.\nThe river current is much stronger than you anticipated.\nYou knew this was a bad idea before you choose it.\nYou drown in the current.\n...')
        time.sleep(8)
        endgame()
    else:
        choiceerror2(inpot, '2field')

#Sewer "scene"

def scenesewer():
    print('You tread through the dark sewer.\nAs you make your way through the darkness, you can hear the growling behind you grow faint.\nYou realise that you have lost your sense of direction!\nYou come to an intersection that divides into three paths... ')
    skip()
    time.sleep(2)
    print('1 - Left, 2 - Center, 3 - Right')
    inpot = raw_input('Which way do you choose?:   ')
    if inpot == '1':
        skip()
        print('You take the path on the left.\nYou find yourself walking on a slight incline.\nYou find it hard to get a solid footing, but you make it up.\nYou find a door, and you open it. As you open the door, the sunlight blinds you.\nAs you step through, you find yourself in a field...')
        time.sleep(3)
        choiceloop3(inpot, '2sewer')
    elif inpot == '2':
        skip()
        print('You take the center path.\nYou feel elated that you can finally see a light at the end of the path.\nYou start to move quickly in an attempt to get out of the sewer as soon as possible.\nYou suddenly fall, and severly injure your leg.\nYou do no survive!\n.....')
        time.sleep(10)
        skip()
        endgame()
    elif inpot == '3':
        skip()
        print('You take the path on the right. You make your way through the sewer until you come to a hatch.\nYou open the hatch and jump into the space above.\nYou find yourself in a long hall...')
        time.sleep(3)
        choiceloop3(inpot, '2sewer')
    else:
        choiceerror3(inpot, '2sewer')

#End of game

def scenehall():
    skip()
    print('It is late and I am tired of writing this code. I only want to sleep now.\nYOU WIN BY DEFAULY!')
    time.sleep(5)

# def main() made for no reason but practice

def main():          
    opening()
main()
\$\endgroup\$
4
\$\begingroup\$

It's a bit of a pet peeve, but I hate seeing huge piles of if statements. Replace them with a dictionary lookup:

actions = { 'house': scene_house,
            'garden': scene_garden,
            'street': scene_street
          }

def unknown_action():
    print("Invalid action! Please try again!")
    return raw_input("What do you want to do?")

current_scene = raw_input("What do you want to do?")
while current_scene != 'dead':
    current_scene = actions.get(current_scene, unknown_action)()
\$\endgroup\$
  • 1
    \$\begingroup\$ You probably want to actually call the function returned by actions.get. \$\endgroup\$ – Mathias Ettinger Jan 3 '16 at 23:03
  • \$\begingroup\$ hah, good point! Fixed in an edit. \$\endgroup\$ – pjz Jan 4 '16 at 18:54
6
\$\begingroup\$

You are using Python 2.x so print is a statement, not a function, remove all parentheses from the prints or write in the first line of your code

from __future__ import print_function

In reskip * 10 is not doing, what you think, it takes 10 times the elements of an empty tuple (e.g. nothing); the result is an empty tuple which is printed. You need a for-loop for your wanted result.

Don't use untransparent recursion. opening calls choiceloop calls sceneselect calls choiceerror calls choiceloop calls ... Your code looks like a snake biting in her own tail. A programm should more look like a tree, go through branches to leafs and back the branches to other leafs: opening calls first scene, scene calls choiceloop, choiceloop returns a valid choice and scene returns this choice, so that opening can call the next scene. Then you also don't have to get frame through all these functions.

Each of your choiceloops looks the same, you can write one general function:

def choice(options):
    print ', '.join('%d - %s' % (i, option) for i, option in enumerate(options, 1))
    while True:
        try:
            answer = int(raw_input('Which way do you choose?:   '))
            if 1 <= answer <= len(options):
                return options[answer - 1]
        except ValueError:
            pass
        print('Invalid option! Please try again!')

and your game would look like:

def scene_house():
    print "nice room"
    answer = choice(["street", "garden"])
    if answer == "street":
        print "you go through the front door"
    return answer

def scene_garden():
    print "nice trees"
    answer = choice(["house"])
    return answer

def scene_street():
    print "car comes"
    return "dead"

def main():
    current_scene = "house"
    while current_scene != "dead":
        if current_scene == "house":
            current_scene = scene_house()
        if current_scene == "garden":
            current_scene = scene_garden()
        if current_scene == "street":
            current_scene = scene_street()
    print "you are dead"        

if __name__ == '__main__':
    main()
\$\endgroup\$
  • 1
    \$\begingroup\$ I disagree with the suggestion to "remove all parentheses from the prints"—this is just busy-work that would make it more difficult to port to Python 3 later. \$\endgroup\$ – Gareth Rees Jan 3 '16 at 13:18
  • \$\begingroup\$ @GarethRees that's why he recommended to import the print_function \$\endgroup\$ – Eli Korvigo Jan 3 '16 at 13:30
  • \$\begingroup\$ @EliKorvigo: That half of the advice was fine, it's the other half that I am disagreeing with. \$\endgroup\$ – Gareth Rees Jan 3 '16 at 13:58
  • \$\begingroup\$ @GarethRees: from the view of clean programming both advices are equal. Every one is free to choose what he/she likes most. But you have to choose one way. If not, you see the problems in the OP's resskip function. \$\endgroup\$ – Daniel Jan 3 '16 at 14:04
  • 1
    \$\begingroup\$ @Daniel: A mistake on one line requires a fix to that line. It doesn't justify a pointless change to the rest of the program. \$\endgroup\$ – Gareth Rees Jan 3 '16 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.