I just finished making(well, trying to make one) a small text adventure in Python and I was wondering what I could have improved with it. Please note that this is my first time using Python. I pretty much had to keep Google open the whole time.
"""
Created on Sat Dec 23 23:57:38 2017
"""
import time
hero_race = {1: "Human", 2: "Elf", 3: "Orc"}
race_choice = None
hero_class = {1: "Warrior", 2: "Mage", 3: "Healer"}
class_choice = None
hero_name = None
map_level = None # Map_level will act as the key for dungeon_map, dungeon_description and level_complete
dungeon_map = {1: "Training_Room", 2: "Slime_Room", 3: "Chimera_Room", 4: "Demon_Room"}
dungeon_description = {1: "You are standing in the knight's training chambers. "
"In front of you lies your master-at-arms.",
2: "You enter the room. You can barely make out anything from this dark area. However, you see "
"a glowing blue light straight ahead of you.\nThe light burns greater... it begins to make "
"the shape of a creature... a slime!",
3: "As you proceed into the room, you hear eerie noises from all across the room, "
"followed by a dark shape that moves too fast for you to catch. You stand in the middle of "
"the round room, you hear a loud growl behind you.\nYou turn around to fight a lion, no..."
"it's a two-headed creature, both a lion and a giant serpent.",
4: "As you step into the room, you find it hard to stand, as if an unknown force is pushing "
"your body down into the ground. You start shaking, your teeth grinding.\nIt takes"
" you a moment, but you are finally able to regain control of your body. Already tired "
"from your previous trials, you push ahead and find an empty throne.\nYou blink and all of a "
"sudden there is a dark figure sitting on the chair. He, no... It smiles and stands up, "
"then walks toward you.\n.... This is your final challenge."}
level_complete = {1: "After several excruciating blows, your sparring session is over.\n"
"Your teacher guides you to the gate where your "
"first true challenge begins to become a full-pledged knight.",
2: "you fight it off and you (surprisingly) beat your first real enemy.\n"
"Behind the gooey carcass of the now-defeated slime lies another room with the doorknob of a lion",
3: "You fight it off and you barely beat "
"this vicious creature. You reach the edge of the room to find a dark door. "
"Red mist flows through the gaps of the door.\nDo you proceed? This may be your final choice",
4: "With great struggle, you defeat your final challenge. Now you are ready to become a full-fledged"
" knight."
}
hero_health = 100
hero_attack = 50
class Monster:
def __init__(self):
self.health = 100
self.attack = 20
def create_hero():
global hero_name
global map_level
global race_choice
global class_choice
map_level = 1
print("What is your name?")
hero_name = input("My name is: ")
print("Choose a race")
print("1- Human\t\t2- Elf\t\t3- Orc")
race_choice = int(input("My race is: "))
print("Choose a class.")
print("1- Warrior\t\t2- Mage\t\t3- Healer")
class_choice = int(input("My class is: "))
return
def save_game():
global race_choice
global class_choice
global map_level
hero_info = str.format("{0:10}{1:10}{2:10}{3:10}{4:10}",
hero_name, hero_race[race_choice], hero_class[class_choice], dungeon_map[map_level],
hero_health)
f = open("hero_information.txt", "w")
f.writelines(hero_info)
f.close()
def load_game():
global hero_name
global race_choice
global class_choice
global map_level
global hero_health
try:
f = open("hero_information.txt", "r")
except FileNotFoundError:
print("Save file doesn't exist")
return 1
line = f.readline()
hero_info = str.split(line)
hero_name = hero_info[0]
# The save file contains the VALUES for the dictionary variables, we do this to obtain the keys
for k, v in hero_race.items():
if v == hero_info[1]:
race_choice = k
break
for k, v in hero_class.items():
if v == hero_info[2]:
class_choice = k
break
for k, v in dungeon_map.items():
if v == hero_info[3]:
map_level = k
break
hero_health = int(hero_info[4])
f.close()
def status():
global race_choice
global class_choice
print("Welcome back %s the %s %s, you have %s health" % (hero_name, hero_race[race_choice],
hero_class[class_choice], hero_health))
return
def encounter():
global map_level
if map_level < 5:
print(dungeon_description[map_level])
battle()
print(level_complete[map_level])
return
def map_navigation():
global map_level
while 1:
print("1- Proceed\t2- Status\t3- Save\t4- Exit")
map_choice = int(input("What should I do?... "))
if map_choice == 1:
map_level += 1
return 0
elif map_choice == 2:
status()
elif map_choice == 3:
save_game()
elif map_choice == 4:
return 1
def battle():
global hero_health
monster = Monster()
print("Prepare to battle!\n...")
time.sleep(3)
while monster.health > 0:
print("Prepare for monster attack! ....")
time.sleep(2)
print("Monster attacks you for {} damage".format(monster.attack))
hero_health -= monster.attack
time.sleep(1)
print("Your turn to fight back!\n...")
time.sleep(2)
print("You attack the monster for {} damage!".format(hero_attack))
monster.health -= hero_attack
print("Monster has only {} health remaining".format(monster.health))
def main():
global map_level
while 1:
print("1- New Game\n2- Load Game\n3- Exit")
start_choice = int(input())
if start_choice == 1:
create_hero()
while map_level < 5:
encounter()
if map_navigation() == 1:
break
print("To be continued.")
break
elif start_choice == 2:
if load_game() == 1: # 1 is the error return value if there is no save file
continue
while map_level < 5:
if map_navigation() == 1:
break
encounter()
print("To be continued.")
break
elif start_choice == 3:
break
if __name__ == "__main__":
main()
There isn't a lot of functionality yet (or even a coherent story line). The battles are automated and I haven't done anything in case the hero's health drops to 0 or below. I had a couple of things I was curious if I could improve, first of all, was it a good idea to keep the dungeon_description
and level_complete
as dictionaries?
Second of all, I noticed I had to use the keyword global [variable_name]
several times, could I have done something to avoid that?
P.S.: I just realized that I didn't need to use global
for the monster health or attack in the battle function, since they were initialized in a Monster
class. Should I have created a Class for hero and defined the variables there?
Also, any other notes on what else I could improve would be greatly appreciated! My biggest concern is how to optimize this.