pythontextadventure

text adventure list does not display like it should


I have a combat function in my text adventure that has you pick melee or magic when magic is selected it states choose a spell to cast:

if user_input == 'magic':
    for i, magic_spell in enumerate(spell, 1):
        print("Choose a spell to cast: ")
        print("{}. {}".format(i,magic_spell))

and is supposed to list the spells like this

choose spell to cast:

  1. Magic Missile
  2. Fireball

but for some reason it displays

choose spell to cast:

  1. Magic Missile

choose spell to cast:

2.fireball

other than that the function works you can select wither one and go through the combat steps it looks exactly like my heal function that displays the items in your inventory you can heal with but not with the spell selection. I am pretty sure I'm not missing something but who knows. here is the whole player.py file the spell list command is in the attack function

import items
import world
import enemies
import magic

class Player:

def __init__(self):
    self.inventory = [items.Dagger(),items.Rock(),items.CrustyBread()]
    self.spell_book = [magic.magic_missle(), magic.fire_ball()]
    self.x = world.start_tile_location[0]
    self.y = world.start_tile_location[1]
    self.hp = 100
    self.gold = 5
    self.victory = False
    self.exp = 199
    self.player_lvl = 1
    self.mana = 100
def is_alive(self):

    return self.hp > 0 
def move(self,dx,dy):
    self.x += dx
    self.y += dy
def move_north(self):
    self.move(dx=0, dy=-1)
def move_south(self):
    self.move(dx=0, dy=1)
def move_east(self):
    self.move(dx=1, dy=0)
def move_west(self):
    self.move(dx=-1, dy=0)
def player_stats(self):
    print("Level: {}".format(self.player_lvl), "HP: {}".format(self.hp),"Mana:{}".format(self.mana),"Gold: {}".format(self.gold), "EXP: {}".format(self.exp))
def print_spellbook(self):
    print('\n Spell Book')
    for magic in self.spell_book:
        print('*'+str(magic))

def print_inventory(self):
    print("\n Inventory:")
    for item in self.inventory:
        print('* ' + str(item))
    print("Gold: {}".format(self.gold))


'''
def check_lvl_up(self,enemy):
    new_exp = self.exp + enemy.exp
    levels = [0,200,450,1012]
    if True:
        current_level = sum(1 for x in levels if x<= total_exp)
        self.player_lvl = current_level
'''
def most_powerful_weapon(self):
    max_damage = 0 
    best_weapon = None
    for item in self.inventory: 
        try:
            if item.damage > max_damage:
                best_weapon = item 
                max_damage = item.damage
                if self.player_lvl >= 2:
                    item.damage = item.damage + 1
        except AttributeError:
            pass

    return best_weapon
def attack(self):

    spell = [magic_spell for magic_spell in self.spell_book if isinstance(magic_spell,magic.Spell)]
    if not spell:
        print("You have no spells to cast!")
    
    user_input = input('What do you want to attack with? melee or magic: ')

    if user_input == 'magic':
        for i, magic_spell in enumerate(spell, 1):
            print("Choose a spell to cast: ")
            print("{}. {}".format(i,magic_spell))
        
        valid =False
        while not valid:
            choice = input("")
            try:
                if self.mana == 0:
                    print("You dont have enough mana")
                else:   
                    room = world.tile_at(self.x,self.y)
                    enemy = room.enemy
                    print("You use {} against {}!".format(magic_spell,enemy.name))
                    enemy.hp -= magic_spell.damage
                    self.mana = self.mana - magic_spell.mana

                    if not enemy.is_alive():
                        print("You killed {}!".format(enemy.name))
                        
                    else:
                        print("{} HP is {}.".format(enemy.name,enemy.hp))
            except(ValueError,IndexError):
                print("Invalid choice, try again")  
            break
    elif user_input == 'melee':
        best_weapon = self.most_powerful_weapon()
        room = world.tile_at(self.x,self.y)
        enemy = room.enemy
        print("You use {} against {}!".format(best_weapon.name,enemy.name))
        enemy.hp -=  best_weapon.damage

        if not enemy.is_alive():
            print("You killed {}!".format(enemy.name))
            
        else:
            print("{} HP is {}.".format(enemy.name,enemy.hp))

def heal(self):
    consumables = [item for item in self.inventory if isinstance(item,items.Consumables)]
    if not consumables:
        print("You dont have any items to heal you!")
        return 

    for i, item in enumerate(consumables, 1):
        print("Choose an item to use to heal: ")
        print("{}. {}".format(i, item))
    
    valid = False
    while not valid:
        choice = input("")
        try:
            to_eat = consumables[int(choice)-1]
            self.hp = min(100,self.hp + to_eat.healing_value)
            self.inventory.remove(to_eat)
            print("Current HP: {}".format(self.hp))
            valid = True
        except (ValueError,IndexError):
            print("Invalid choice, try again")

def trade(self):
    room = world.tile_at(self.x,self.y)
    room.check_if_trade(self)

def current_locaton(self):
    room = world.tile_at(self.x,self.y)
    self.current_location = room

def saveload(self):
    player_Stats = {
        self.player.hp,
        self.player.gold,
        self.player.lvl,
        self.player.current_location(),
    }
    filename = 'save.json'
    with open(filename, 'w') as f:
        json.dump(player_Stats)
    

Solution

  • Your logic is slightly off, simply modify to:

    if user_input == 'magic':
        print("Choose a spell to cast: ")
        for i, magic_spell in enumerate(spell, 1):
            print("{}. {}".format(i,magic_spell))
    

    Because your print was in the loop, it was printing "Choose a spell to cast:" with each spell.