I am making a small text game, and one of my methods is behaving unexpectedly, and I can't figure out why. If I import the module and run the method in python, it works fine. Some parts of the game aren't complete, but that parts that I need run fine.
With the module pasted below, choose method is changing a list into a string, but only when the module is run. I'm running this on 2.7.3, on a mac.
Edit: I figured it out. The program execution had continued, and I was confused by the choose call in the match method. The options parameter sent in match was a string, instead of the list it should have been, but that was simple to figure out why.
import fighters
import weapons
from random import randint
from sys import exit
class Hero(object):
weapons = ["spikeglove", "shortsword"]
hp = {"actual":50, "base":50}
score = 0
def attack(self, weapon, method):
return None
class Scene(object):
# Returns one or more items from the provided choices
def choose(self, options, max_choices, prompt):
chosen = []
while len(chosen) < max_choices and len(options) > 0:
print
print prompt
print options, chosen
for o in options:
print "- {}".format(o)
print type(options)
choice = raw_input("> ")
if choice in options:
chosen.append(choice)
options.remove(choice)
print options, chosen
else:
print "That is not one of the options!"
if len(chosen) == 1:
return chosen[0]
else:
return chosen
class Death(Scene):
def enter(self):
print "You are now dead"
return "menu"
class Exit(Scene):
def enter(self):
print "Thanks for playing!"
return exit(1)
class Menu(Scene):
def enter(self):
menu_options = ["play", "train", "exit"]
choice = self.choose(menu_options, 1, "Welcome to the Arena!")
return choice
class Level(Scene):
def __init__(self):
self.prologue = "Welcome to {}".format(self.__class__.__name__)
next_scene = "level1"
# A match is the fight between the Hero and a particular Enemy
# A Hero must defeat each Enemy via a match to win the tournament/level
def match(self, hp, weapons, enemy):
hero_hp = hp
enemy_hp = enemy.stats["hp"]
last_attack = ""
while hero_hp and enemy_hp:
weapon_choice = self.choose(weapons, 1, "> ")
attack_choice = self.choose(weapon_choice.available_attacks(last_attack), 1, "> ")
last_attack = attack_choice
hero_attack = hero.attack(attack_choice)
enemy_attack = enemy.attack()
print "Hero: {} {}: {}".format(hero_hp, enemy, enemy_hp)
if hero_hp:
return "victory", hero_hp
else:
return "defeat"
# The game cycles through the enemies that our hero has to face
# passing the setup to the "match" function for the fighting
def enter(self):
print
print
print self.prologue
start_hp = hero.hp['actual']
weapons = self.choose(hero.weapons, 2, "Choose a weapon")
while self.enemies:
enemy = fighters.roster[self.enemies.pop()]
match_outcome, finish_hp = self.match(start_hp, weapons, enemy)
if match_outcome == "defeat":
hero.hp['actual'] = hero.hp['base']
return "death"
# The Hero enters the next match with the current HP obtained from the previous match
start_hp = finish_hp
# Add our Hero's victory points, and get them some medical attention
# before heading back to the Barracks
points_award = 5
hero.points += points_award
hero.hp['actual'] = hero.hp['base']
new_weapon = "shortsword"
hero.add_weapon(new_weapon)
epilogue = """Congratulations!
You have gained {} points for a total score of {}.\n
You have unlocked the \"{}\" """.format(
points_award, hero.points, new_weapon)
return next_scene
class Train(Scene):
pass
class Level1(Level):
enemies = ["boxer", "boxer"]
next_scene = "level2"
class Level2(Level):
pass
class Level3(Level):
pass
class Level4(Level):
pass
class Level5(Level):
pass
class Engine(object):
def __init__(self, start_scene):
self.start_scene = start_scene
scenes = {
"menu": Menu(),
"death": Death(),
"exit": Exit(),
"play": Level1(),
"level2": Level2(),
"level3": Level3(),
"level4": Level4(),
"level5": Level5(),
}
def next_scene(self, scene_name):
return self.scenes[scene_name]
def play(self):
current_scene = self.scenes[self.start_scene]
while True:
next_scene = current_scene.enter()
current_scene = self.scenes[next_scene]
if __name__ == "__main__":
hero = Hero()
game = Engine("menu")
game.play()
Terminal output:
$ python arena.py
Welcome to the Arena!
['play', 'train', 'exit'] []
- play
- train
- exit
<type 'list'>
> play
['train', 'exit'] ['play']
Welcome to Level1
Choose a weapon
['spikeglove'] []
- spikeglove
<type 'list'>
> spikeglove
[] ['spikeglove']
>
spikeglove []
- s
- p
- i
- k
- e
- g
- l
- o
- v
- e
<type 'str'>
Yet when I run in python:
>>> import arena
>>> s = arena.Level1()
>>> s.choose(['shortsword', 'spikeglove'], 2, "Choose a weapon")
Choose a weapon
['shortsword', 'spikeglove'] []
- shortsword
- spikeglove
<type 'list'>
> shortsword
['spikeglove'] ['shortsword']
Choose a weapon
['spikeglove'] ['shortsword']
- spikeglove
<type 'list'>
> spikeglove
[] ['shortsword', 'spikeglove']
['shortsword', 'spikeglove']