5
\$\begingroup\$

This is my 2nd attempt at this game, I took advice and tips on the last one from here.

I took tips on how to not let memory stack overflow and to write a bit better story. Do suggest on how I can improve my code in general ? Thank you.

import time #added to enable pause

#A text based vampire survival game

#possible answers
answer_A = ['A', 'a']
answer_B = ['B', 'b']
answer_C = ['C', 'c']
y = ['yes', 'Yes', 'y', 'Y']
n = ['no', 'No', 'n', 'N']


#story begins here
def intro():
    print('You wake up in front of a castle, you have no idea where you are or why you are here.'
    'You suddenly see a colony of bats fly away.' 'You turn back and see a vampire figure appear out of nowhere. You will:')
    print('''    A. Ask for direction.
    B. Run inside the castle.
    C. Run to the cave.''')
    choice = input('>>>  ')
    if choice in answer_A:
        print('\n Well you dont ask vampires for directions. \n\nRip')
        return "Gameover"
    elif choice in answer_B:
        return "castle"
    elif choice in answer_C:
        return "cave"
    else:
        print("Invalid input")
        time.sleep(1)
        intro()


def option_castle():
    print('You ran inside the castle and see a glass front cubbord with garlic inside.You hear the Vampire coming,''You will: ')
    print('''    A. Take the garllic to scare the vampire.
    B. Hide
    C. Escape from backdoor.''')
    choice = input('>>>  ')
    if choice in answer_A:
        print("The garlic did stopped the vampire but it did not stopped it's blood thirsty bats.\n\n RIP")
        return "Gameover"
    elif choice in answer_B:
        print("This is not hide n'seek \n\n RIP" )
        return "Gameover"
    elif choice in answer_C:
        return "village"
    else:
        print('Invalid input')
        time.sleep(1)
        option_castle()


def option_cave():
    print('You ran inside a dark cave, you were not sure if its a good idea or not but in there you see a shiny silver dagger.' 'Hurry bats are coming: ')
    print('''    A. You pick up the dagger and fight.
    B. You pick up the dagger and hide.
    C. You run.''')
    choice = input('>>>  ')
    if choice in answer_A:
        print('You picked the silver dagger and stood there like a fearsome warrior. The vampire attacked you but you were cunning and avoiding its attack stabbed the vampire right in its heart. Well done vampire slayer, you may live.')
        return "Gameover"
    elif choice in answer_B:
        print("Cowards don't get to fight and live. \n\n RIP")
        return "Gameover"
    elif choice in answer_C:
        return "village"
    else:
        print("Invalid input")
        time.sleep(1)
        option_cave()


def option_abdvilllage():
    print('You ran towards an abandoned village in the open. The bats are coming faster than before, you will: ')
    print('''    A. Hide 
    B. Pick a wood to stab the vampire
    C. Enter the cave''')
    choice = input('>>>  ')
    if choice in answer_A:
        print('You hid in a hut and well it worked, you were lucky and the sun rose killing the vampire. You were a coward but a lucky one.')
        return "Gameover"
    elif choice in answer_B:
        print("You were ready to stab the vampire with the wood but neither you were fast enough nor the wood was pointed enough. \n\n RIP")
        return "Gameover"
    elif choice in answer_C:
        return "cave"
    else:
        print('Invalid Input')
        time.sleep(1)
        option_abdvilllage()

def main_loop():
    state = "intro"

    while state != "end":
        if state == "intro":
            state = intro()
        elif state == "castle":
            state = option_castle()
        elif state == "village":
            state = option_abdvilllage()
        elif state == "cave":
            state = option_cave()
        elif state == "Gameover":
            again = input("\nDo you want to play again? (Y or n)").lower()
            if again in y:
                state = "intro"
            else:
                print('\nvery well')
                break

def play(): 
    start = input('Do you want to play? Y or N  ')
    if start in y:
        main_loop()
    elif start in n:
        print('very well')
    else:
        print('wrong input')
        time.sleep(1)
        play()

play()
\$\endgroup\$
  • 1
    \$\begingroup\$ Hello, I added a link to the original question and I slightly changed the title of your question. \$\endgroup\$ – dariosicily Aug 1 at 10:37
  • 1
    \$\begingroup\$ "I took advice and tips on the last one from here." It may be confusing but the stack overflow error comes from recursion. You'd need to remove; intro() from intro, option_cave() from ` option_cave`, ..., to fix this. (You can use a while loop) \$\endgroup\$ – Peilonrayz Aug 2 at 5:13
2
\$\begingroup\$

Note: those are my personal opinions, whenever I write that you should do something, treat it as 'I think you should'. Although I usually don't do that, I will not give you solutions to the 'issues' that I am going to point out, it seems like you are good at figuring things by yourself. However, if you don't know how to - ask away.

Positives

  1. I really like the idea of the variables like answer_A.
  2. Functions are named as I would expect them, when I read the name - I know what is happening.
  3. Same goes for variable names, most of the variables are properly named
  4. Your code is very readable, I didn't even have to have any explanation to understand what it is doing - keep it up!

Extract more functions

  1. The following can be generalised to a separate function and hence you can have the same logic for other main functions.

    if choice in answer_A:
            print("The garlic did stopped the vampire but it did not stopped it's blood thirsty bats.\n\n RIP")
            return "Gameover"
        elif choice in answer_B:
            print("This is not hide n'seek \n\n RIP" )
            return "Gameover"
        elif choice in answer_C:
            return "village"
        else:
            print('Invalid input')
            time.sleep(1)
            option_castle()
    
  2. Printing options can be generalized as well - not only to make the code easier but so you can easily expand your number of options - read about args.

    print('''    A. Take the garllic to scare the vampire.
        B. Hide
        C. Escape from backdoor.''')
    

Variables
"Gameover","intro", "cave" etc should be extracted to variables so you can easily translate/refactor it later.

Generalizations

You might want to extract reading user input and writing the output to a separate class/function (class is preferable). This will give you opportunity to port your game to UI other than console.

nits

  1. Usually, it is a good practice to use if __name__ == "__main__" (see here) when you want to run script directly (play())
  2. Variables y and x could be better named to indicate what they contain
  3. Extract 1 in time.sleep(1) to a variable. You might want to change it later and if you would have more functions, it would be annoying.
| improve this answer | |
\$\endgroup\$

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.