<gh_stars>1-10
"""Classes for modeling combat missions."""

import logging
from random import randrange, shuffle, choice
from itertools import cycle

import flags
from actor import Actor, Player

# "Constants" for combat result
WIN = 0
LOSE = 1
RETREAT = 2

class Mission():
    """A representation of a combat mission."""

    def __init__(self, title='Title', enemy_name='Enemy'):
        """Initialize mission attributes."""
        # Set the title.
        self.title = title

        # Create an enemy.
        self.enemy = Actor(enemy_name)
        self.enemy.log_properties()

        # Default result is None.
        self.result = None

    def resolve_combat(self, player):
        """Resolve combat.
        
        Args:
            player: The player character.
            
        Returns:
            (int) "Constants" WIN, RETREAT, or LOSE
        """
        # Randomize whether player or enemy hits first.
        actors = [player, self.enemy]
        shuffle(actors)

        # Perform combat
        for i in cycle(range(2)):
            # End combat if actor has hp less than retreat ratio
            if actors[i].hp <= actors[i].max_hp * actors[i].retreat_ratio:
                break
            damage = randrange(
                    actors[i].min_damage, actors[i].max_damage + 1)
            actors[i-1].hp -= damage
            logging.debug(
                    actors[i].name + " hits for " + str(damage) + ". "
                    + actors[i-1].name + " " + str(actors[i-1].hp)
                    + " HP remaining.")

        logging.debug(player.name + ": " + str(player.hp) + "HP")
        logging.debug(self.enemy.name + ":  " + str(self.enemy.hp) + "HP")

        # Report results.
        if self.enemy.hp <= 0:
            logging.info(player.name + " won.")
            self.result = WIN
        elif player.hp > 0:
            logging.info(player.name + " withdrew.")
            self.result = RETREAT
        else:
            player.hp = 0
            logging.info(player.name + " defeated.")
            self.result = LOSE

        return self.result


class MissionList():
    """A set of runnable missions."""

    def __init__(self):
        """Initialize mission list attributes."""
        self.active_mission = None
        self.build_mission_list()

    def build_mission_list(self):
        """Populate mission list."""
        self.missions = []
        self.missions.append(Mission('Slay the Rat', 'Rat'))

        titles = ['Storm the Castle']
        enemies = ['Goblin']
        self.missions.append(Mission(choice(titles), choice(enemies)))

    def get_active_mission(self):
        """Return the active mission."""
        return self.active_mission

    def set_active_mission(self, mission):
        """Set the active mission."""
        self.active_mission = mission


# Execute this only if running as a standalone
if __name__ == "__main__":
    flags.init_flags("Combat mission test module.")
    player = Player()
    mission = Mission()
    logging.debug(mission.resolve_combat(player))


"""Classes for modeling combat missions."""

import logging
from random import randrange, shuffle, choice
from itertools import cycle

import flags
from actor import Actor, Player

# "Constants" for combat result
WIN = 0
LOSE = 1
RETREAT = 2

class Mission():
    """A representation of a combat mission."""

    def __init__(self, title='Title', enemy_name='Enemy'):
        """Initialize mission attributes."""
        # Set the title.
        self.title = title

        # Create an enemy.
        self.enemy = Actor(enemy_name)
        self.enemy.log_properties()

        # Default result is None.
        self.result = None

    def resolve_combat(self, player):
        """Resolve combat.
        
        Args:
            player: The player character.
            
        Returns:
            (int) "Constants" WIN, RETREAT, or LOSE
        """
        # Randomize whether player or enemy hits first.
        actors = [player, self.enemy]
        shuffle(actors)

        # Perform combat
        for i in cycle(range(2)):
            # End combat if actor has hp less than retreat ratio
            if actors[i].hp <= actors[i].max_hp * actors[i].retreat_ratio:
                break
            damage = randrange(
                    actors[i].min_damage, actors[i].max_damage + 1)
            actors[i-1].hp -= damage
            logging.debug(
                    actors[i].name + " hits for " + str(damage) + ". "
                    + actors[i-1].name + " " + str(actors[i-1].hp)
                    + " HP remaining.")

        logging.debug(player.name + ": " + str(player.hp) + "HP")
        logging.debug(self.enemy.name + ":  " + str(self.enemy.hp) + "HP")

        # Report results.
        if self.enemy.hp <= 0:
            logging.info(player.name + " won.")
            self.result = WIN
        elif player.hp > 0:
            logging.info(player.name + " withdrew.")
            self.result = RETREAT
        else:
            player.hp = 0
            logging.info(player.name + " defeated.")
            self.result = LOSE

        return self.result


class MissionList():
    """A set of runnable missions."""

    def __init__(self):
        """Initialize mission list attributes."""
        self.active_mission = None
        self.build_mission_list()

    def build_mission_list(self):
        """Populate mission list."""
        self.missions = []
        self.missions.append(Mission('Slay the Rat', 'Rat'))

        titles = ['Storm the Castle']
        enemies = ['Goblin']
        self.missions.append(Mission(choice(titles), choice(enemies)))

    def get_active_mission(self):
        """Return the active mission."""
        return self.active_mission

    def set_active_mission(self, mission):
        """Set the active mission."""
        self.active_mission = mission


# Execute this only if running as a standalone
if __name__ == "__main__":
    flags.init_flags("Combat mission test module.")
    player = Player()
    mission = Mission()
    logging.debug(mission.resolve_combat(player))
Classes for modeling combat missions. # "Constants" for combat result A representation of a combat mission. Initialize mission attributes. # Set the title. # Create an enemy. # Default result is None. Resolve combat.                  Args:             player: The player character.                      Returns:             (int) "Constants" WIN, RETREAT, or LOSE # Randomize whether player or enemy hits first. # Perform combat # End combat if actor has hp less than retreat ratio # Report results. A set of runnable missions. Initialize mission list attributes. Populate mission list. Return the active mission. Set the active mission. # Execute this only if running as a standalone