B.A. Ceradsky
B.A. Ceradsky

Reputation: 37

Lists and pop() are not working as I'd expect

My program is an adventure game with potions and chests. I've set these up in lists so when the user drinks a potion or opens a chest, I can use pop() to remove it from the list. This works fine while the user is in the same room, but if they come back to the room they are able to use that potion or chest again.

In pseudocode, the system should work something like this:

if potions:
    if there are still potions in the list:
        drink potion
        potions.pop()
    else:
        print "There are no potions left."
else:
    print "There are no potions to drink."

I think what is happening is when I pop the potion from the list, if potions doesn't compute to being true, and it automatically goes to the else block, but I'm not sure why it does that, nor am I sure why when I come back to the room the list resets itself.

if room.potions:
    if len(room.potions) > 0:  # if there are potions left
        if hasattr(room.potions[0], 'explode'): # if the potion is a bomb
            room.potions[0].explode(You) # explode using zeroeth item from the list
            room.potions[0].pop # remove zeroeth item from the list`
        else:
            room.potions[0].heal(You)  # heal using zeroeth potion from the list
            room.potions.pop(0)  # remove zeroeth item from the list
    else:
        print "There are no more potions to drink"
else:
    print "There are no potions to drink"

Upvotes: 0

Views: 128

Answers (4)

thesonyman101
thesonyman101

Reputation: 821

What you could do is when they drink it do this

potions = 1
    if potions > 0:
        drink potion
        potions = potions - 1
    else:
        print "There are no potions left."

Upvotes: 1

niyasc
niyasc

Reputation: 4490

You can simply write your code as follows:

if potions: # same as len(potions) > 0
    # drink potion
    potions.pop()
else:
    print "There are no potions to drink."

So check if any potion is left, if it is left drink it and remove from list otherwise show there is no potion left.

Upvotes: 0

Jose Raul Barreras
Jose Raul Barreras

Reputation: 859

OK. I was tempted... :) Of course, should exist a hierarchy of potions and the print() method could be a message to the 'world'. And so forth...

import random

class Potion:
    """Define the Potion class. Could be explosive and provoke a damage"""
    def __init__(self, explosive=None, damage=None):
        if explosive == None:
            self.__explosive = bool(random.getrandbits(1))
        else:
            self.__explosive = explosive

        if self.__explosive:
            if damage == None:
                self.__damage = random.randint(1,5)
            else:
                self.__damage = damage
        else:
            self.__damage = 0

    def isExplosive(self):
        return self.__explosive

    def explode(self):
        if self.isExplosive():
            return self.__damage
        else:
            return 0

    def __str__(self):
        if self.isExplosive():
            res = "explosive potion"
        else:
            res = "simple potion"
        return res

class Hero:
    """Simple Hero class"""
    def __init__(self, name):
        self.__name = name
        self.__hp = 100
        self.__potions = []

    def receiveDamage(self, damage):
        self.__hp = self.__hp - damage
        if self.__hp <= 0:
            print("I'm dead!")

    def isAlive(self):
        return self.__hp > 0

    def getPotion(self, room):
        """ Get the first potion in the room.If the potion 
            is explosive, explode and receive some damage
            TODO: Trapped potions?
        """
        potion = room.getFirstPotion()
        print("%s take a %s" % (self.__name, potion))
        if potion.isExplosive():
            damage = potion.explode()
            print("%s received %d hp of damage!!" % (self.__name, damage))
            self.receiveDamage(damage)
        else:
            self.__potions.append(potion)

    def __str__(self):
        res = "%s have %d HP and %d potions." % (self.__name, self.__hp, len(self.__potions))
        return res

class Room:
    def __init__(self, potions):
        """Create a room with some potions"""
        self.__potions = potions

    def getFirstPotion(self):
        """Return the first potion """
        if self.__potions:
            potion = self.__potions.pop()
        else:
            potion = None
        return potion 

    def havePotions(self):
        return len(self.__potions) > 0

    @property
    def potions(self):
        return self.__potions

    def __str__(self):
        return "This room have %s potions" % len(self.__potions)

peter = Hero('Peter')
room = Room(potions=[Potion() for i in range(5)])
print(room)
print(peter)

while room.havePotions():
    print("___________")
    peter.getPotion(room)
    print(room)
    print(peter)

Output:

This room have 5 potions
Peter have 100 HP and 0 potions.
___________
Peter take a simple potion
This room have 4 potions
Peter have 100 HP and 1 potions.
___________
Peter take a explosive potion
Peter received 3 hp of damage!!
This room have 3 potions
Peter have 97 HP and 1 potions.
___________
Peter take a explosive potion
Peter received 3 hp of damage!!
This room have 2 potions
Peter have 94 HP and 1 potions.
___________
Peter take a explosive potion
Peter received 5 hp of damage!!
This room have 1 potions
Peter have 89 HP and 1 potions.
___________
Peter take a explosive potion
Peter received 1 hp of damage!!
This room have 0 potions
Peter have 88 HP and 1 potions.

Upvotes: 0

coredump
coredump

Reputation: 38799

EAFP approach:

try:
    potions.pop()
except IndexError:
    print "No potion left"

Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.

Upvotes: 0

Related Questions