I'm a beginner working on a text adventure. It's quite bare-bones at this point but I would appreciate feedback before I continue and the flaws in my code become further ingrained.
I plan to add an item pickup and inventory system which can store items to heal and deal damage to enemies, some problem-solving and expand the number of locations. I'd like to hear some things I should implement which could help me learn though.
# A Countryside Adventure
#from questionmodule import * # moved module to this file for posting on forum
from sys import exit
import random
def ask_yes_no(question):
"""Ask a yes or no question"""
allowed_answers = ("y", "yes", "n", "no")
response = None
while response not in allowed_answers :
response = input(question).lower()
if response not in allowed_answers:
print("That is not a valid response.")
return response
def ask_yes_no_boolean(question):
"""As a yes or no question and return response as boolean"""
allowed_answers = ("y", "yes", "n", "no")
response = None
while response not in allowed_answers:
response = input(question).lower()
if response not in allowed_answers:
print("That is not a valid response.")
if response in ("y", "yes"):
return True
return False
def two_option_q(question, option_one, option_two):
"""As a two option question and return response as boolean"""
allowed_answers = (option_one, option_two)
response = None
while response not in allowed_answers:
response = input(question).lower()
if response not in allowed_answers:
print("That is not a valid response.")
if response == (option_one):
return option_one
else:
return option_two
def ask_left_right(question):
"""Ask a left or right question"""
allowed_answers = ("left", "l", "right", "r")
response = None
while response not in allowed_answers:
response = input(question).lower()
if response not in allowed_answers:
print("Sorry that is not a valid response.")
if response in ("r", "right"):
return "right"
else:
return "left"
class Character(object):
"""A character in a fictional world"""
def __init__(self, name, health):
self.name = name
self.health = health
def __str__(self):
rep = self.name + " has health: " + str(self.health)
return rep
def attack(self, other):
raise NotImplementedError
class Player(Character):
"""A player in a fictional world"""
STRIKES = {"headbutt" : 4 , "kick" : 3, "punch" : random.randrange(1, 4)}
def __init__(self, name, health = 10):
super(Player, self).__init__(name, health)
def attack(self, other):
strike = ask_yes_no_boolean("\nStrike the {}(yes/no)?".format(other.name))
if strike:
strike_type = input("What type of strike(headbutt, kick, punch)? ")\
.lower()
if strike_type in Player.STRIKES:
print("You got the {} with a {} and dealt {} damage!".format(\
other.name, strike_type, Player.STRIKES.get(strike_type)))
other.health -= Player.STRIKES.get(strike_type)
else:
print("Oops. You missed!")
else:
print("You wuss!")
class Enemy(Character):
"""An enemy is a fictional world"""
def __init__(self, name, health = 7, damage = 2):
super(Enemy, self).__init__(name, health)
self.damage = damage
def attack(self, other):
other.health -= self.damage
print("The {} attacks and deals you {} damage!".format(self.name,\
self.damage))
def die(self):
print("You have defeated the {}!".format(self.name))
class Location(object):
"""A location in an adventure game"""
## ENEMY_NAMES = ["Boar", "Troll", "Wild cat"]
## enemy = Enemy(random.choice(ENEMY_NAMES))
def enter(self):
pass
def battle(self, player, enemy):
print("A {} suddenly appears!".format(enemy.name))
fight = two_option_q("\nFight or run(fight/run)? ", "fight",\
"run")
if fight == "fight":
while player.health and enemy.health > 0:
#print("\n")
enemy.attack(player)
if player.health <= 0:
break
print(player)
print(enemy)
player.attack(enemy)
if enemy.health <= 0:
print("You have defeated the {}!".format(enemy.name))
#enemy.die()
elif player.health <= 0:
print("You are killed by the {}!".format(enemy.name))
return True
else:
print("You escaped unharmed. But he shall be waiting should you \
venture")
print("to these parts again!")
class Meadow(Location):
"""A meadow in an adventure game"""
ENEMY_NAMES = ["Boar", "Troll", "Wild cat"]
enemy = Enemy(random.choice(ENEMY_NAMES))
def enter(self, player):
print(player)
print("{}, you are in a meadow.".format(player.name))
if Meadow.enemy.health > 0:
player_dead = self.battle(player, Meadow.enemy)
if player_dead:
return "death"
else:
print("The slain body of the {} lies slumped pathetically on the\
ground.".format(Meadow.enemy.name))
print("\nTo your left is a beach, to your right a forest.")
left_right = two_option_q("Which way do you go(left/right)? ", "left",\
"right")
if left_right == "left":
return "beach"
else:
return "forest"
class Beach(Location):
"""A beach location in an adventure game"""
ENEMY_NAMES = ["Boar", "Troll", "Wild cat"]
enemy = Enemy(random.choice(ENEMY_NAMES))
def enter(self, player):
print(player)
print("You are at the beach.")
if Beach.enemy.health > 0:
player_dead = self.battle(player, Beach.enemy)
if player_dead:
return "death"
else:
print("You pass the lifeless body of the {}.".format(Beach.enemy.\
name))
print("\nTo your left is a meadow, to your right a forest.")
left_right = two_option_q("Which way do you go(left/ right)? ", "left"\
, "right")
if left_right == "left":
return "meadow"
else:
return "forest"
class Forest(Location):
"""A forest in an adventure game"""
ENEMY_NAMES = ["Boar", "Troll", "Wild cat"]
enemy = Enemy(random.choice(ENEMY_NAMES))
def enter(self, player):
print(player)
print("You are in the forest.")
if Forest.enemy.health > 0:
player_dead = self.battle(player, Forest.enemy)
if player_dead:
return "death"
else:
print("You smile as you pass the corpse of the {}.".format(\
Forest.enemy.name))
print("\nTo your left is meadow, to your right a beach.")
left_right = two_option_q("Which way do you go(left/right)?", "left",\
"right")
if left_right == "left":
return "meadow"
else:
return "beach"
class Death(object):
"""The death of a player in an adventure game"""
def enter(self, player):
print("Game Over.")
return "break"
class Game(object):
"""A fictional countryside adventure"""
def __init__(self, location_map):
self.location_map = location_map
def play(self):
current_location = self.location_map.start_location()
while True:
next_location_name = current_location.enter(self.\
location_map.player)
if next_location_name == "break":
break
current_location = self.location_map.next_location\
(next_location_name)
class Map(object):
LOCATIONS = {"meadow" : Meadow(),
"beach" : Beach(),
"forest" : Forest(),
"death" : Death()}
def __init__(self, location, player):
self.location = location
self.player = player
def next_location(self, location_name):
return Map.LOCATIONS.get(location_name)
def start_location(self):
return self.next_location(self.location)
def main():
print("\n\n\t\tCountryside adventure")
name = input("\n\nWelcome adventurer! What might be your name? ")
print("\nI wish you the very best of luck, {}!.\n".format(name))
player = Player(name)
a_map = Map("meadow", player)
game = Game(a_map)
game.play()
play = True
while play:
main()
play = ask_yes_no_boolean("Do you want to play again? ")