Example #1
0
class GameWorld(Observer, Observable, Visitable):

    def __init__(self):
        super(GameWorld, self).__init__()
        self._rounds = 1
        self._moveable_list = list()
        self._immovable_list = list()
        self._text_object_list = list()
        self._drawable = list()
        self._creature_list = list()
        self._player = None
        self._interface = None
        self.index = 0
        self.image_state = 0
        self.name = "game world"
        self._current_turn = ""
        self.start = False
        self.end_turn_boolean = True
        self.dark = False
        self.tk_end_turn_boolean = tk.BooleanVar
        self.distance = Distance()
        
        # Visitors
        self.attack_move_position_visitor = AttackMovePositionVisitor()
        self.move_position_visitor = MovePositionVisitor()
        
        # Move Position States
        self._attack_move_position = AttackMovePosition()
        self._move_position = MovePosition()
        self._move_position_state = None

    def accept_visitor(self, visitor):
        visitor.visit(self)

    def find_move_position(self, creature, end_goal):
        return self.move_position_state.find_move_position(creature, end_goal)

    @property
    def attack_move_position(self):
        return self._attack_move_position

    @property
    def move_position(self):
        return self._move_position

    @property
    def move_position_state(self):
        return self._move_position_state

    @move_position_state.setter
    def move_position_state(self, state):
        self._move_position_state = state

    @property
    def current_turn(self):
        return self._current_turn

    @current_turn.setter
    def current_turn(self, current_turn):
        self._current_turn = current_turn

    @property
    def creature_list(self):
        return self._creature_list

    @creature_list.setter
    def creature_list(self, creature_list):
        self._creature_list = creature_list

    @property
    def player(self):
        return self._player

    @player.setter
    def player(self, player):
        assert player in self._moveable_list
        self._player = player

    @property
    def interface(self):
        return self._interface

    @interface.setter
    def interface(self, game_canvas):
        assert self._interface is None
        self._interface = game_canvas

    @property
    def rounds(self):
        return self._rounds

    @rounds.setter
    def rounds(self, value):
        self._rounds = value

    def game_over(self):  # TODO Check if this works.
        if self._moveable_list[0].creature_type is "human":
            print("You are the only creature left alive.")
        else:
            print("You died.")
        print("Game over.")
        exit()

    def start_day(self, start_menu):
        start_menu.destroy()
        day_count = 1
        self.day(day_count)

    def day(self, day_count):
        self.creature_list.sort(key=lambda x: x.initiative_check())
        # TODO Remove creatures from list when they die, not just remove from observers?
        print("The sun comes up.")
        self.dark = False
        print("Day " + str(day_count))
        print("Turn Order:")
        for creature in self.creature_list:
            print(creature.name)
        self.round()
        day_count += 1
        self.day(day_count)

    def round(self):
        print("")
        print("Round " + str(self.rounds))
        if self.rounds > 25:
            self.dark = True
            print("")
            print("The sun goes down.")
            exit()
        self.turn()

    def turn(self):
        creature = self.creature_list[self.index]
        if len(self._moveable_list) == 1:
            self.game_over()
        self.info_pane = InfoPane(self.interface._root, self.interface.canvas, self, self.player)
        self.end_turn_boolean = True
        # creature.prepare_attack = False
        self.current_turn = creature.name
        if creature.hunger_points == 0:
            print("The human is starving.")
        print(creature.name + " attempts to perceive.")
        self.notify_perception_observers(self, creature)
        while self.end_turn_boolean:
            if creature.action_count <= 0:
                self.info_pane.end_turn()
            elif creature.creature_type is "human":
                self.interface.canvas.wait_variable(creature.end_turn)
            elif creature.current_state.name is not "dead":
                self.creature_action(creature)

    def end_turn(self, info_pane):
        info_pane.destroy()
        self.end_turn_boolean = False
        if self.index < (len(self.creature_list) - 1):
            self.index += 1
            self.turn()
        else:
            self.index = 0
            for creature in self.creature_list:
                if (creature.current_state.name == "unconscious and dying" or
                        creature.current_state.name == "unconscious, but stable" or
                        creature.current_state.name == "dead"):
                    creature.action_count = 0
                    creature.standard_action = 0
                    creature.move = 0
                if creature.current_state.name == "staggered":
                    creature.action_count = 1
                    creature.standard_action = 1
                    creature.move_action = 1
                else:
                    creature.action_count = 2
                    creature.standard_action = 1
                    creature.move_action = 2
            self.rounds += 1
            self.round()

    def creature_action(self, creature):
        """Creature Action

        Determines a type of action for the creature. A location is sent to the action method.
        Called by the turn method when on a non-human turn.

        Args:
            creature: the acting creature

        """
        # TODO Sneak is broken.
        # if creature.move.name is not "sneak":
            # creature.set_move(Sneak())
        # self.notify_stealth_observers(self, creature)

        if creature.creature_type is "wolf":
            if creature.standard_action > 0:
                creature.notify_attack_range_observers(creature)
            if creature.prepare_attack and creature.standard_action > 0:
                end = [creature.target.position_col, creature.target.position_row]
                self.action(creature, end)
            elif creature.prepare_attack and creature.standard_action <= 0:
                creature.action_count = 0
            else:
                creature.notify_attack_move_observers(creature)
                if creature.prepare_attack_move:
                    creature.prepare_attack_move = False
                    end_goal = [creature.target.position_col, creature.target.position_row]
                    self.accept_visitor(self.attack_move_position_visitor)
                    end = self.find_move_position(creature, end_goal)
                else:
                    start = [2024, 384]
                    if creature.position == start:
                        end = [creature.position_col - (creature.speed * 64), creature.position_row]
                    else:
                        self.accept_visitor(self.move_position_visitor)
                        end = self.find_move_position(creature, start)
                self.action(creature, end)
        else:
            # TODO Add deer action.
            creature.action_count -= 2
        self.redraw()

    def player_action(self, event):
        """Player Action

        Takes an event and turns it into a location.
        Called by the interface when the user clicks the screen.

        Args:
            event: a click event

        """
        event_col = int(self.interface.canvas.canvasx(event.x))
        event_row = int(self.interface.canvas.canvasy(event.y))
        end = [event_col, event_row]
        self.action(self.player, end)

    def action(self, creature, end):
        """Action

        Decides whether the action is a move or an attack and calls the right method.
        Both creature_action and player_action call action after a location is determined.

        Args:
            creature: the acting creature
            end: the end location for either an attack, a movement, or some other interaction

        """
        interval = 64
        move_distance = creature.speed * interval
        start = [creature.position_col, creature.position_row]
        distance = int(self.distance.compute(start, end))
        if creature.action_count > 0:
            if distance <= move_distance:
                creature.possible_move = end
                creature.prepare_move = True

            creature.notify_move_observers(creature)

            # TODO Add location interaction check
            # It should also be impossible to move through a location, instead it needs to find the best path
            # around the object.

            if creature.prepare_attack and creature.standard_action > 0:
                creature.possible_move_col = creature.position_col
                creature.possible_move_row = creature.position_row
                creature.prepare_move = False
                col = creature.position_col
                row = creature.position_row
                possible_col = creature.possible_move_col
                possible_row = creature.possible_move_row
                if (possible_col in range(int(col) - interval, int(col) + interval) and
                        possible_row in range(int(row) - interval, int(row) + interval)):
                    creature.execute_attack(creature, creature.target, self)
                    self.interface.action_text(creature)
                creature.prepare_attack = False
            elif creature.prepare_move:
                creature.execute_move(creature)
                self.move(creature)
                creature.prepare_move = False

    def move(self, creature):
        """Move

        Gradually moves changes a creatures location. Changes the human player's image for every step.
        Called by action.

        Args:
            creature: the acting creature

        """
        col_num = 4
        row_num = 4
        while (creature.possible_move_col != creature.position_col or
               creature.possible_move_row != creature.position_row):
            if creature.prepare_move:
                if creature.possible_move_col < creature.position_col:
                    creature.position_col += -col_num
                if creature.possible_move_col > creature.position_col:
                    creature.position_col += +col_num
                if creature.possible_move_row < creature.position_row:
                    creature.position_row += -row_num
                if creature.possible_move_row > creature.position_row:
                    creature.position_row += +row_num
                if self.image_state < 4 and creature.creature_type == "human":
                    # TODO This is happening too quickly
                    self.image_state += 1
                    if self.image_state == 4:
                        self.image_state = 0
                    creature.set_image_state(creature.image_list[self.image_state])
                creature.position = [creature.position_col, creature.position_row]
                if self.distance.compute(creature.possible_move, creature.position) < 4:
                    col_num = 1
                    row_num = 1
                self.redraw()
        self.image_state = 0
        if creature.creature_type == "human":
            creature.set_image_state(creature.image_list[self.image_state])
            self.redraw()

    def hide(self, creature):
        self._unregister_drawable(creature)
        self.redraw()

    def perceive(self, creature):
        self._register_drawable(creature)

    def death(self, creature):
        self._creature_list.remove(creature)

    def add_text_object(self, new_object):
        self._text_object_list.append(new_object)

    def remove_text_object(self, new_object):
        self._text_object_list.remove(new_object)

    def add_stationary_world_object(self, new_object):
        self._immovable_list.append(new_object)
        new_object.add_observer(self)
        self.add_observer(new_object)
        if isinstance(new_object, GameDrawable):
            self._drawable.append(new_object)

    def add_world_object(self, new_object):
        self._moveable_list.append(new_object)
        new_object.add_observer(self)
        self.add_observer(new_object)
        if isinstance(new_object, GameDrawable):
            self._register_drawable(new_object)

    def remove_world_object(self, old_object):
        if old_object in self._moveable_list:
            self._moveable_list.remove(old_object)
            old_object.remove_observer(self)
            self.remove_observer(old_object)
        if old_object in self._immovable_list:
            self._immovable_list.remove(old_object)
        if old_object in self._drawable:
            self._unregister_drawable(old_object)
        self.redraw()

    def _register_drawable(self, obj):
        assert isinstance(obj, GameDrawable)
        assert obj not in self._drawable
        self._drawable.append(obj)
        self.redraw()

    def _unregister_drawable(self, obj):
        assert isinstance(obj, GameDrawable)
        assert obj in self._drawable
        self._drawable.remove(obj)

    def redraw(self):
        self.interface.redraw(self._drawable)

    def move_update(self, player):
        self.notify_move_observers(player)

    def attack_range_update(self, creature):
        self.notify_attack_range_observers(creature)

    def attack_move_update(self, creature):
        self.notify_attack_move_observers(creature)

    def change_move(self, key_press):
        self.player.change_move(key_press)
Example #2
0
class Creature(Observable, GameDrawable):

    def __init__(self, **kwargs):
        super(Creature, self).__init__(**kwargs)
        self._name = ""
        self._creature_type = ""

        # States
        self.current_state = NormalState(self)
        self.normal_state = NormalState(self)
        self.staggered_state = StaggeredState(self)
        self.unconscious_stable_state = UnconsciousStableState(self)
        self.unconscious_dying_state = UnconsciousDyingState(self)
        self.dead_state = DeadState(self)

        # Behaviors
        self.attack = Attack()
        self.combat_maneuver = CombatManeuver()
        self.move = Move()
        self.posture = Posture()
        self.skill = Skill()

        # Abilities
        self.strength = 10
        self.dexterity = 10
        self.constitution = 10
        self.intelligence = 10
        self.wisdom = 10

        # Ability Modifiers
        self._str_mod = (self.strength // 2) - 5
        self._dex_mod = (self.dexterity // 2) - 5
        self._con_mod = (self.constitution // 2) - 5
        self._int_mod = (self.intelligence // 2) - 5
        self._wis_mod = (self.wisdom // 2) - 5

        # Other
        self._standard_action = 1
        self._move_action = 2
        self._vigor_points = 1
        self._speed = 6
        self._other = 0
        self._armor = 0
        self._base_attack_bonus = 0
        self._dodge = 0
        self._wound_points = self.constitution
        self._wound_threshold = self.constitution // 2
        self._position_col = 0
        self._position_row = 0
        self._position = (0, 0)
        self._possible_move_col = 0
        self._possible_move_row = 0
        self._possible_move = [0, 0]
        self._action_count = 2
        self._inventory = list()
        self._target = None
        self._prepare_attack = False
        self._prepare_attack_move = False
        self._prepare_move = False
        self._hide = False
        self._width = 0
        self._height = 0
        self._lineofsight = 500
        self.distance = Distance()
        self._hidden = list()

    @property
    def hidden(self):
        return self._hidden

    def add_hidden(self, creature):
        if creature not in self._hidden:
            self._hidden.append(creature)

    def remove_hidden(self, creature):
        if creature in self._hidden:
            self._hidden.remove(creature)

    @property
    def hide(self):
        return self._hide

    @hide.setter
    def hide(self, hide):
        self._hide = hide

    @property
    def lineofsight(self):
        return self._lineofsight

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name    

    @property
    def creature_type(self):
        return self._creature_type

    @creature_type.setter
    def creature_type(self, creature_type):
        self._creature_type = creature_type

    @property
    def prepare_move(self):
        return self._prepare_move

    @prepare_move.setter
    def prepare_move(self, value):
        self._prepare_move = value

    @property
    def prepare_attack(self):
        return self._prepare_attack

    @prepare_attack.setter
    def prepare_attack(self, value):
        self._prepare_attack = value

    @property
    def prepare_attack_move(self):
        return self._prepare_attack_move

    @prepare_attack_move.setter
    def prepare_attack_move(self, value):
        self._prepare_attack_move = value

    @property
    def str_mod(self):
        return self._str_mod

    @property
    def dex_mod(self):
        return self._dex_mod

    @property
    def con_mod(self):
        return self._con_mod

    @property
    def int_mod(self):
        return self._int_mod

    @property
    def wis_mod(self):
        return self._wis_mod

    @property
    def height(self):
        return self._height

    @height.setter
    def height(self, height):
        self._height = height

    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, width):
        self._width = width

    @property
    def move_action(self):
        return self._move_action

    @move_action.setter
    def move_action(self, move_action):
        self._move_action = move_action

    @property
    def standard_action(self):
        return self._standard_action

    @standard_action.setter
    def standard_action(self, standard_action):
        self._standard_action = standard_action

    @property
    def dodge(self):
        return self._dodge

    @dodge.setter
    def dodge(self, dodge):
        self._dodge = dodge

    @property
    def base_attack_bonus(self):
        return self._base_attack_bonus

    @base_attack_bonus.setter
    def base_attack_bonus(self, base_attack_bonus):
        self._base_attack_bonus = base_attack_bonus

    @property
    def armor(self):
        return self._armor

    @armor.setter
    def armor(self, armor):
        self._armor = armor

    @property
    def other(self):
        return self._other

    @other.setter
    def other(self, other):
        self._other = other

    @property
    def speed(self):
        return self._speed

    @speed.setter   
    def speed(self, speed):
        self._speed = speed

    @property
    def base_speed(self):
        return self._base_speed

    @base_speed.setter
    def base_speed(self, base_speed):
        self._base_speed = base_speed

    @property
    def hunger_points(self):
        return self._hunger_points

    @hunger_points.setter
    def hunger_points(self, hunger_points):
        self._hunger_points = hunger_points
    
    @property
    def action_count(self):
        return self._action_count
    
    @action_count.setter
    def action_count(self, action_count):
        self._action_count = action_count

    @property
    def vigor_points(self):
        return self._vigor_points

    @vigor_points.setter
    def vigor_points(self, vigor_points):
        self._vigor_points = vigor_points
        
    @property
    def wound_threshold(self):
        return self._wound_threshold

    @property
    def wound_points(self):
        return self._wound_points

    @wound_points.setter
    def wound_points(self, wound_points):
        self._wound_points = wound_points

    @property
    def position(self):
        return self._position
    
    @position.setter
    def position(self, position):
        self._position = position

    @property
    def possible_move(self):
        return self._possible_move

    @possible_move.setter
    def possible_move(self, possible_move):
        self._possible_move = possible_move
        self._possible_move_col = possible_move[0]
        self._possible_move_row = possible_move[1]
        
    @property
    def position_col(self):
        return self._position_col
    
    @position_col.setter
    def position_col(self, position_col):
        self._position_col = position_col

    @property
    def position_row(self):
        return self._position_row

    @position_row.setter
    def position_row(self, position_row):
        self._position_row = position_row

    @property
    def possible_move_col(self):
        return self._possible_move_col

    @possible_move_col.setter
    def possible_move_col(self, possible_move_col):
        self._possible_move_col = possible_move_col

    @property
    def possible_move_row(self):
        return self._possible_move_row

    @possible_move_row.setter
    def possible_move_row(self, possible_move_row):
        self._possible_move_row = possible_move_row

    @property
    def target(self):
        return self._target

    @target.setter
    def target(self, target):
        self._target = target

    def set_state(self, state):  # Change state to condition?
        self.current_state = state

    def get_normal_state(self):
        return self.normal_state

    def get_staggered_state(self):
        return self.staggered_state

    def get_dead_state(self):
        return self.dead_state

    def get_unconscious_dying_state(self):
        return self.unconscious_dying_state

    def get_unconscious_stable_state(self):
        return self.unconscious_stable_state

    def set_move(self, move):
        self.move = move
        self.move.speed(self)

    def set_attack(self, attack):
        self.attack = attack

    def set_combat_maneuver(self, combat_maneuver):
        self.combat_maneuver = combat_maneuver

    def set_skill(self, skill):
        self.skill = skill

    def set_posture(self, posture):
        self.posture = posture
        self.posture.execute(self)

    def execute_move(self, actor):
        self.move.execute(actor)

    def execute_attack(self, actor, target, world):
        self.attack.execute(actor, target, world)

    def execute_combat_maneuver(self, actor, target):
        self.combat_maneuver.execute(actor, target)

    def execute_skill(self, actor, target):
        self.skill.execute(actor, target)

    def eat(self):
        print("I eat.")

    def sleep(self):
        print("I sleep.")

    def add_inventory(self, item):
        self._inventory.append(item)

    def remove_inventory(self, item):
        self._inventory.remove(item)

    def change_move(self, key_press):
        """Change Move

        Changes the current move to the move associated with each key below.

        """
        if key_press == "w":
            self.set_move(Walk())
        if key_press == "r":
            self.set_move(Run())
        if key_press == "s":
            self.set_move(Sneak())
        if key_press == "h":
            self.set_move(Hustle())
        if key_press == "o":
            self.set_move(OneSquareStep())

    def initiative_check(self):
        initiative_roll = random.randint(1, 20)
        return initiative_roll + self.dex_mod

    def staggered_action(self):
        self.wound_points -= 1
        print("The " + self._name + " is feeling weak and loses a wound.")
        print("The " + self._name + " has " + str(self.vigor_points) + " vigor and "
              + str(self.wound_points) + " wounds remaining.")
        if self.wound_points <= 0:
            self.set_state(self.get_dead_state())
            print("The " + self._name + " dies.")
        con_check = random.randint(1, 20) + self.con_mod
        if con_check < 10:
            self.set_state(self.get_dead_state())
            print("The " + self._name + " looses consciousness and dies.")

    def stealth_update(self, world, creature):
        if self.distance.compute(self.position, creature.position) > 500:
            creature.set_skill(Stealth())
            creature.skill.execute(world, creature, self)

    def perception_update(self, world, creature):
        name = self.move.name
        if name is "sneak" and self.distance.compute(self.position, creature.position) <= creature.lineofsight:
            # creature.target = self
            creature.set_skill(Perception())
            creature.skill.execute(world, creature, self)

    def move_update(self, creature):
        possible_move_col = int(creature.possible_move_col)
        possible_move_row = int(creature.possible_move_row)
        position_col = int(self.position_col)
        position_row = int(self.position_row)
        position = (self.position_col, self.position_row)
        creature_position = (creature.position_col, creature.position_row)

        if (possible_move_col in range(position_col - self.width, position_col + self.width + 1) and
                possible_move_row in range(position_row - self.height, position_row + self.height + 1)):
            if creature is not self:
                creature.prepare_move = False
            if (creature is not self and
                    self.distance.compute(position, creature_position) <= creature.attack.attack_range):
                creature.prepare_attack = True
                creature.target = self

    def attack_range_update(self, creature):
        position = (self.position_col, self.position_row)
        creature_position = (creature.position_col, creature.position_row)
        if (creature is not self and
                self.distance.compute(position, creature_position) <= creature.attack.attack_range and
                self not in creature.hidden):
            creature.prepare_attack = True
            creature.target = self

    def attack_move_update(self, creature):
        position = (self.position_col, self.position_row)
        creature_position = (creature.position_col, creature.position_row)
        attack_range = creature.attack.attack_range
        if (creature is not self and self not in creature.hidden and
                self.distance.compute(position, creature_position) <= ((creature.speed * 64) + attack_range)):
            creature.prepare_attack_move = True
            creature.target = self

    def death_update(self, actor):
        self.remove_observer(actor)

    def display(self):
        pass
Example #3
0
class Creature(Observable, GameDrawable):
    def __init__(self, **kwargs):
        super(Creature, self).__init__(**kwargs)
        self._name = ""
        self._creature_type = ""

        # States
        self.current_state = NormalState(self)
        self.normal_state = NormalState(self)
        self.staggered_state = StaggeredState(self)
        self.unconscious_stable_state = UnconsciousStableState(self)
        self.unconscious_dying_state = UnconsciousDyingState(self)
        self.dead_state = DeadState(self)

        # Behaviors
        self.attack = Attack()
        self.combat_maneuver = CombatManeuver()
        self.move = Move()
        self.posture = Posture()
        self.skill = Skill()

        # Abilities
        self.strength = 10
        self.dexterity = 10
        self.constitution = 10
        self.intelligence = 10
        self.wisdom = 10

        # Ability Modifiers
        self._str_mod = (self.strength // 2) - 5
        self._dex_mod = (self.dexterity // 2) - 5
        self._con_mod = (self.constitution // 2) - 5
        self._int_mod = (self.intelligence // 2) - 5
        self._wis_mod = (self.wisdom // 2) - 5

        # Other
        self._standard_action = 1
        self._move_action = 2
        self._vigor_points = 1
        self._speed = 6
        self._other = 0
        self._armor = 0
        self._base_attack_bonus = 0
        self._dodge = 0
        self._wound_points = self.constitution
        self._wound_threshold = self.constitution // 2
        self._position_col = 0
        self._position_row = 0
        self._position = (0, 0)
        self._possible_move_col = 0
        self._possible_move_row = 0
        self._possible_move = [0, 0]
        self._action_count = 2
        self._inventory = list()
        self._target = None
        self._prepare_attack = False
        self._prepare_attack_move = False
        self._prepare_move = False
        self._hide = False
        self._width = 0
        self._height = 0
        self._lineofsight = 500
        self.distance = Distance()
        self._hidden = list()

    @property
    def hidden(self):
        return self._hidden

    def add_hidden(self, creature):
        if creature not in self._hidden:
            self._hidden.append(creature)

    def remove_hidden(self, creature):
        if creature in self._hidden:
            self._hidden.remove(creature)

    @property
    def hide(self):
        return self._hide

    @hide.setter
    def hide(self, hide):
        self._hide = hide

    @property
    def lineofsight(self):
        return self._lineofsight

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

    @property
    def creature_type(self):
        return self._creature_type

    @creature_type.setter
    def creature_type(self, creature_type):
        self._creature_type = creature_type

    @property
    def prepare_move(self):
        return self._prepare_move

    @prepare_move.setter
    def prepare_move(self, value):
        self._prepare_move = value

    @property
    def prepare_attack(self):
        return self._prepare_attack

    @prepare_attack.setter
    def prepare_attack(self, value):
        self._prepare_attack = value

    @property
    def prepare_attack_move(self):
        return self._prepare_attack_move

    @prepare_attack_move.setter
    def prepare_attack_move(self, value):
        self._prepare_attack_move = value

    @property
    def str_mod(self):
        return self._str_mod

    @property
    def dex_mod(self):
        return self._dex_mod

    @property
    def con_mod(self):
        return self._con_mod

    @property
    def int_mod(self):
        return self._int_mod

    @property
    def wis_mod(self):
        return self._wis_mod

    @property
    def height(self):
        return self._height

    @height.setter
    def height(self, height):
        self._height = height

    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, width):
        self._width = width

    @property
    def move_action(self):
        return self._move_action

    @move_action.setter
    def move_action(self, move_action):
        self._move_action = move_action

    @property
    def standard_action(self):
        return self._standard_action

    @standard_action.setter
    def standard_action(self, standard_action):
        self._standard_action = standard_action

    @property
    def dodge(self):
        return self._dodge

    @dodge.setter
    def dodge(self, dodge):
        self._dodge = dodge

    @property
    def base_attack_bonus(self):
        return self._base_attack_bonus

    @base_attack_bonus.setter
    def base_attack_bonus(self, base_attack_bonus):
        self._base_attack_bonus = base_attack_bonus

    @property
    def armor(self):
        return self._armor

    @armor.setter
    def armor(self, armor):
        self._armor = armor

    @property
    def other(self):
        return self._other

    @other.setter
    def other(self, other):
        self._other = other

    @property
    def speed(self):
        return self._speed

    @speed.setter
    def speed(self, speed):
        self._speed = speed

    @property
    def base_speed(self):
        return self._base_speed

    @base_speed.setter
    def base_speed(self, base_speed):
        self._base_speed = base_speed

    @property
    def hunger_points(self):
        return self._hunger_points

    @hunger_points.setter
    def hunger_points(self, hunger_points):
        self._hunger_points = hunger_points

    @property
    def action_count(self):
        return self._action_count

    @action_count.setter
    def action_count(self, action_count):
        self._action_count = action_count

    @property
    def vigor_points(self):
        return self._vigor_points

    @vigor_points.setter
    def vigor_points(self, vigor_points):
        self._vigor_points = vigor_points

    @property
    def wound_threshold(self):
        return self._wound_threshold

    @property
    def wound_points(self):
        return self._wound_points

    @wound_points.setter
    def wound_points(self, wound_points):
        self._wound_points = wound_points

    @property
    def position(self):
        return self._position

    @position.setter
    def position(self, position):
        self._position = position

    @property
    def possible_move(self):
        return self._possible_move

    @possible_move.setter
    def possible_move(self, possible_move):
        self._possible_move = possible_move
        self._possible_move_col = possible_move[0]
        self._possible_move_row = possible_move[1]

    @property
    def position_col(self):
        return self._position_col

    @position_col.setter
    def position_col(self, position_col):
        self._position_col = position_col

    @property
    def position_row(self):
        return self._position_row

    @position_row.setter
    def position_row(self, position_row):
        self._position_row = position_row

    @property
    def possible_move_col(self):
        return self._possible_move_col

    @possible_move_col.setter
    def possible_move_col(self, possible_move_col):
        self._possible_move_col = possible_move_col

    @property
    def possible_move_row(self):
        return self._possible_move_row

    @possible_move_row.setter
    def possible_move_row(self, possible_move_row):
        self._possible_move_row = possible_move_row

    @property
    def target(self):
        return self._target

    @target.setter
    def target(self, target):
        self._target = target

    def set_state(self, state):  # Change state to condition?
        self.current_state = state

    def get_normal_state(self):
        return self.normal_state

    def get_staggered_state(self):
        return self.staggered_state

    def get_dead_state(self):
        return self.dead_state

    def get_unconscious_dying_state(self):
        return self.unconscious_dying_state

    def get_unconscious_stable_state(self):
        return self.unconscious_stable_state

    def set_move(self, move):
        self.move = move
        self.move.speed(self)

    def set_attack(self, attack):
        self.attack = attack

    def set_combat_maneuver(self, combat_maneuver):
        self.combat_maneuver = combat_maneuver

    def set_skill(self, skill):
        self.skill = skill

    def set_posture(self, posture):
        self.posture = posture
        self.posture.execute(self)

    def execute_move(self, actor):
        self.move.execute(actor)

    def execute_attack(self, actor, target, world):
        self.attack.execute(actor, target, world)

    def execute_combat_maneuver(self, actor, target):
        self.combat_maneuver.execute(actor, target)

    def execute_skill(self, actor, target):
        self.skill.execute(actor, target)

    def eat(self):
        print("I eat.")

    def sleep(self):
        print("I sleep.")

    def add_inventory(self, item):
        self._inventory.append(item)

    def remove_inventory(self, item):
        self._inventory.remove(item)

    def change_move(self, key_press):
        """Change Move

        Changes the current move to the move associated with each key below.

        """
        if key_press == "w":
            self.set_move(Walk())
        if key_press == "r":
            self.set_move(Run())
        if key_press == "s":
            self.set_move(Sneak())
        if key_press == "h":
            self.set_move(Hustle())
        if key_press == "o":
            self.set_move(OneSquareStep())

    def initiative_check(self):
        initiative_roll = random.randint(1, 20)
        return initiative_roll + self.dex_mod

    def staggered_action(self):
        self.wound_points -= 1
        print("The " + self._name + " is feeling weak and loses a wound.")
        print("The " + self._name + " has " + str(self.vigor_points) +
              " vigor and " + str(self.wound_points) + " wounds remaining.")
        if self.wound_points <= 0:
            self.set_state(self.get_dead_state())
            print("The " + self._name + " dies.")
        con_check = random.randint(1, 20) + self.con_mod
        if con_check < 10:
            self.set_state(self.get_dead_state())
            print("The " + self._name + " looses consciousness and dies.")

    def stealth_update(self, world, creature):
        if self.distance.compute(self.position, creature.position) > 500:
            creature.set_skill(Stealth())
            creature.skill.execute(world, creature, self)

    def perception_update(self, world, creature):
        name = self.move.name
        if name is "sneak" and self.distance.compute(
                self.position, creature.position) <= creature.lineofsight:
            # creature.target = self
            creature.set_skill(Perception())
            creature.skill.execute(world, creature, self)

    def move_update(self, creature):
        possible_move_col = int(creature.possible_move_col)
        possible_move_row = int(creature.possible_move_row)
        position_col = int(self.position_col)
        position_row = int(self.position_row)
        position = (self.position_col, self.position_row)
        creature_position = (creature.position_col, creature.position_row)

        if (possible_move_col in range(position_col - self.width,
                                       position_col + self.width + 1) and
                possible_move_row in range(position_row - self.height,
                                           position_row + self.height + 1)):
            if creature is not self:
                creature.prepare_move = False
            if (creature is not self
                    and self.distance.compute(position, creature_position) <=
                    creature.attack.attack_range):
                creature.prepare_attack = True
                creature.target = self

    def attack_range_update(self, creature):
        position = (self.position_col, self.position_row)
        creature_position = (creature.position_col, creature.position_row)
        if (creature is not self and self.distance.compute(
                position, creature_position) <= creature.attack.attack_range
                and self not in creature.hidden):
            creature.prepare_attack = True
            creature.target = self

    def attack_move_update(self, creature):
        position = (self.position_col, self.position_row)
        creature_position = (creature.position_col, creature.position_row)
        attack_range = creature.attack.attack_range
        if (creature is not self and self not in creature.hidden
                and self.distance.compute(position, creature_position) <=
            ((creature.speed * 64) + attack_range)):
            creature.prepare_attack_move = True
            creature.target = self

    def death_update(self, actor):
        self.remove_observer(actor)

    def display(self):
        pass