1

I am trying to make a mud but when making a equip command I ran into this error.

    if item.types == "weapon":
AttributeError: 'unicode' object has no attribute 'types'

I would like to fix my code so that it allows users to type equip sword and it will search for that item in his/her inventory and apply the stats.

Here is my item code

#weapons

class Weapon():
    def __init__(self, name, ATK, gold, types):
        self.name = name
        self.ATK = ATK
        self.gold = gold
        self.types = types


club = Weapon("club", 1, 3, "weapon")
sword = Weapon("sword", 3, 10,"weapon")
axe = Weapon("axe", 4, 15,"weapon")
bow = Weapon("Hailey's bow", 10, 40,"weapon")
swordX = Weapon("Gods Sword", 8000, 8000,"weapon")

and here is my player code

players[id] = { 
            "name": None,
            "room": "Tavern",
            "ATK": 5,
            "hp": 20,
            "inventory": {},
            "armorName": None,
            "armorPT": None,
            "weaponName": None,
            "weaponPT": None,
        }

and last my equip command code

elif command == "equip":
            x = params.lower()
            rm = rooms[players[id]["room"]]
            if x in players[id]["inventory"]:
                item = players[id]["inventory"][x]
                weapon = players[id]["weaponName"]
                wStat = players[id]["weaponPT"]
                armor = players[id]["armorName"]
                aStat = players[id]["armorPT"]
                hp = players[id]["hp"]
                ATK = players[id]["ATK"]
                if item.types == "weapon":
                    weapon = item.name
                    wStat = item.ATK
                    ATK += wStat
                    mud.send_message(id,"you equip %s" % weapon)
                    mud.send_message(id,"NEW ATK: %d" % ATK)
                elif item.type == "armor":
                    armor = item.name
                    aStat = item.DEF
                    hp += aStat
                    mud.send_message(id,"you equip %s" % armor)
                    mud.send_message(id,"NEW DEF: %d" % hp)

                else:
                    mud.send_message(id,"not a vaid item type")

            else:
                mud.send_message(id,"you dont have this item")

If you think I need to add any more code for it to make sense, please tell me.

EDIT: i think i found where the problem is but i don't know how to fix it i believe it is in the take command and hoe it is added to the inventory it is being added as a string i don't know how to fix this

here is the code

elif command == "take":
            x = params.lower()
            rm = rooms[players[id]["room"]]

            if rm["item"] == "yes":
                if x in rm["itemName"]:
                    players[id]["inventory"][x] = x
                    del rm["itemName"][x]
                    mud.send_message(id, "you picked up %s" % x)
                    print players[id]["inventory"][x]

                else:
                    mud.send_message(id,"You dont see that item")
            else:
                mud.send_message(id,"there is no item here")
Arcxes
  • 29
  • 9
  • Please check at how stuff is appended to the player's item's - could it be a string and not an object? – Vladimir Shevyakov Feb 24 '16 at 04:42
  • use a "print" statement to see what is in `players[id]["inventory"]` it looks like this is not the object you are expecting. – salparadise Feb 24 '16 at 04:45
  • The code you've provided doesn't show how values are assigned to the player's inventory. More generally: I'd strongly recommend that you run your code past the [Code Review Stack Exchange](http://codereview.stackexchange.com/). There are some rather serious issues with your current design which will make further development very difficult. –  Feb 24 '16 at 04:46
  • Can somebody give me an example of code that would work for what i need and items are added in this format {"item":item} – Arcxes Feb 24 '16 at 21:42
  • the code i already have has worked with the same format for my kill command so i dont see whats wrong here – Arcxes Feb 24 '16 at 21:48

2 Answers2

1

The error message tells that item is a unicode string, and not an instance of the class Weapon.

Therefore, when you try to access item.types you get an error.

N.B. not also that the next condition should be elif item.types == "armor": (missing s).

Sci Prog
  • 2,651
  • 1
  • 10
  • 18
1

One of the "bad smells" in OO programming is checking the type of an object yourself. If you're checking the type, there's a good chance you should change how you implement your design.

In this case, I'd like to suggest that you create Player methods called equip(self, obj), set_weapon(self, obj), set_armor(self, obj), and create various object methods called equip_on(self, Player) and unequip_on(self, Player).

Then you can divide up authority and responsibility based on class and type and which objects knows which things:

  • Player.equip could deal with weight limits and taking an object from the room that contained it.
  • Weapon.equip_on would know that it's a weapon, and call the appropriate method on Player.
  • Player.set_weapon would know it must first un-equip an existing weapon.
  • Weapon.unequip_on could refuse to be unequipped if it were cursed.

If you implement your methods correctly, each one of them will seem simple and straightforward, but they will add a little more information to the picture each time. This double dispatch is a fast, easy way to deal with type information without having to sprinkle if type(obj) == statements throughout your code.

aghast
  • 14,785
  • 3
  • 24
  • 56
  • um could you show an exampleright now my whole player is based as a dictionary would i need to make it into a class and where would i insert this code into the commands and i really need an example im new to this side of stuff – Arcxes Feb 25 '16 at 02:06
  • There's a reason why this kind of thing gets used frequently in OO programming books. It's practically made for it! That said, I'll try to gen up an example and edit my answer. – aghast Feb 25 '16 at 02:08
  • ok thanks it would really help id appreciate it sorry if i misspell things im lazy – Arcxes Feb 25 '16 at 02:10
  • oh i almost forgot would i need to change my take command at all for this to work – Arcxes Feb 25 '16 at 02:24