Saturday, January 21, 2017

Gaze at my syllogisms!

So I have been hacking away at the Text Adventure (pun intended) and I implemented the wear and wield actions yesterday.  They were far more complicated than I gave them credit for.  The character needs to wear and wield armor, but then I thought about the problem more, and it turned out that actually:

Characters have body slots to wear and wield weapons
Only weapons go in the Main Hand and Off Hand slots and only armor can be worn.
Characters have class constraints as to what they can wear and wield
Some weapons are two handed, some are not
Some characters can dual wield, others cannot
Main hand is always equipped first
Needs to support the use of keywords

I remembered that it is best to unit test first, then build your code.  I literally went through all of my axioms for the system, and then test by test built up the function to make sure it was working properly.  I LOVE pytest fixtures, because they made the testing process a whole hell of a lot easier.  Testing helps you to narrow down what the function is actually supposed to do.  I tried to test vigorously, going for each permutation and thinking about how to narrow down the possibilities so that the player is only allowed possibilities I want.  Yes, there was probably a less verbose, better way of doing all this, but it works and all of my unit tests passed.  Behold, my wield function in all of its syllogistic glory!

class WieldAction():
    def __init__(self,item_repository):
        self.item_repository = item_repository

def do(self,state,itemname):
    player = state.player
    if not itemname:
        print("Wield what?")
        return    for itemid in player.inventory:
        item = self.item_repository.get_by_id(itemid)
        if itemname == item.get_name():
            #Is it a weapon            if item.get_type() != "Weapon":
                print("That cannot be wielded.")
                return            #Does your class allow you to wield this?            elif item.get_weapon_type() not in player.guild.get_allowed_weapon_types():
                print("{0}s are not allowed to wield {1}s".format(player.guild.get_name(), item.get_weapon_type()))
                return            #Druids can't wield metal objects            elif player.guild.get_name() == "Druid" and item.get_material() in ["iron", "steel", "copper", "bronze"]:
                print("Druids may not wield weapons made of metal.")
                return            elif item.get_handed() == 2:
                if player.race.get_body_slot("Main Hand")==0 and player.race.get_body_slot("Off Hand") == 0:
                    player.race.set_body_slot("Main Hand", item.get_id())
                    player.race.set_body_slot("Off Hand", item.get_id())
                    print("You wield the {0} in both hands.".format(item.get_name()))
                    player.inventory.remove(item.get_id())
                    return                else:
                    print("You need two free hands to wield the {0}.".format(item.get_name()))
                    return            elif player.race.get_body_slot("Main Hand") != 0:
                if "Two Weapon Fighting" not in player.get_feats():
                    print("You cannot dual wield.")
                    return                elif player.race.get_body_slot("Off Hand") != 0:
                    offhanditem = self.item_repository.get_by_id(player.race.get_body_slot("Off Hand"))
                    print("You are already wielding {0} in your off hand.".format(offhanditem.get_name()))
                    return                else:
                    player.race.set_body_slot("Off Hand", item.get_id())
                    print("You wield the {0} in your off hand.".format(item.get_name()))
                    player.inventory.remove(item.get_id())
            else:
                player.race.set_body_slot("Main Hand", item.get_id())
                print("You wield the {0} in your main hand.".format(item.get_name()))
                player.inventory.remove(item.get_id())
        if itemname in item.get_keywords():
            #Is it a weapon            if item.get_type() != "Weapon":
                print("That cannot be wielded.")
                return            #Does your class allow you to wield this?            elif item.get_weapon_type() not in player.guild.get_allowed_weapon_types():
                print("{0}s are not allowed to wield {1}s".format(player.guild.get_name(), item.get_weapon_type()))
                return            #Druids can't wield metal objects            elif player.guild.get_name() == "Druid" and item.get_material() in ["iron", "steel", "copper", "bronze"]:
                print("Druids may not wield weapons made of metal.")
                return            elif item.get_handed() == 2:
                if player.race.get_body_slot("Main Hand")==0 and player.race.get_body_slot("Off Hand") == 0:
                    player.race.set_body_slot("Main Hand", item.get_id())
                    player.race.set_body_slot("Off Hand", item.get_id())
                    print("You wield the {0} in both hands.".format(item.get_name()))
                    player.inventory.remove(item.get_id())
                    return                else:
                    print("You need two free hands to wield the {0}.".format(item.get_name()))
                    return            elif player.race.get_body_slot("Main Hand") != 0:
                if "Two Weapon Fighting" not in player.get_feats():
                    print("You cannot dual wield.")
                    return                elif player.race.get_body_slot("Off Hand") != 0:
                    offhanditem = self.item_repository.get_by_id(player.race.get_body_slot("Off Hand"))
                    print("You are already wielding {0} in your off hand.".format(offhanditem.get_name()))
                    return                else:
                    player.race.set_body_slot("Off Hand", item.get_id())
                    print("You wield the {0} in your off hand.".format(item.get_name()))
                    player.inventory.remove(item.get_id())
            else:
                player.race.set_body_slot("Main Hand", item.get_id())
                print("You wield the {0} in your main hand.".format(item.get_name()))
                player.inventory.remove(item.get_id())

No comments:

Post a Comment