def __handle_hull_destroyed(hull_destroyed):
     if hull_destroyed.player:
         return PlainResponse("The hull has been destroyed, all is lost.")
     else:
         return PlainResponse(
             "The enemy ship bursts apart, the crew lets out a " +
             "sigh of relief, then a cheer. On to the next challenge.")
Example #2
0
    def __handle_combat(self, slots, game_state):
        unassigned = [
            c for (c, s) in game_state.ship.crew.iteritems()
            if s.station is None
        ]

        if len(unassigned) > 0:
            return (build_speechlet_response_enahnced(
                QPContent.unassigned_crew(
                    [CREW_MEMBERS[c]["name"] for c in unassigned], [
                        STATIONS[station].name
                        for station in game_state.ship.stations.keys()
                        if station not in game_state.ship.crew.values()
                    ]),
                reprompt=PlainResponse("Move your crew to stations or " +
                                       "say engage to continue.")), game_state)

        (game_state, qp_results) = \
            self.__runner.advance_combat(game_state)

        is_end_game = len(
            filter(lambda r: issubclass(type(r), EndGameState),
                   qp_results)) > 0

        return (build_speechlet_response_enahnced(
            QPContent.handle_qp_results_respone(qp_results),
            should_end_session=is_end_game,
            reprompt=PlainResponse("Move your crew to stations or " +
                                   "say engage to continue.")), game_state)
 def __handle_station_fire_state_change(station_fire):
     station_name = STATIONS.get(station_fire.station).name
     if station_fire.extinguished_by is not None:
         crew_name = CREW_MEMBERS.get(station_fire.extinguished_by)["name"]
         if station_fire.start_by is not None:
             return PlainResponse("Enemy fire expanded the fire " +
                                  crew_name + " put out in the " +
                                  station_name)
         else:
             return PlainResponse(crew_name +
                                  " has extinguished the fire in the " +
                                  station_name)
     elif station_fire.start_by == StationStateActor.ATTACK:
         return PlainResponse("The " + station_name +
                              " has started on fire.")
 def new_game_response(crew_members, stations, opponent_name):
     return PlainResponse(" ".join([
         QPContent.NEW_GAME_INTRO,
         QPContent.describe_stage(opponent_name), "As a remminder, ",
         QPContent.list_crew(crew_members), QPContent.STATION_DESCRIPTION,
         QPContent.list_stations(stations), QPContent.MOVE_SUGGESTION_TEXT
     ]))
Example #5
0
 def __get_crew_state_response(self, crew_id, crew):
     if crew_id in CREW_MEMBERS:
         crew_name = CREW_MEMBERS[crew_id]["name"]
         if crew_id in crew:
             crew_state = crew[crew_id]
             if crew_state.station is not None:
                 return PlainResponse(
                     QPContent.cs_crew_crew_manning_station(
                         crew_name, STATIONS[crew_state.station].name))
             else:
                 return PlainResponse(
                     QPContent.cs_crew_not_assigned(crew_name))
         else:
             return QPContent.cs_crew_member_invalid_response(crew_name)
     else:
         return QPContent.cs_crew_member_invalid_response(crew_id)
 def __handle_station_damage_state_change(station_damage):
     station_name = STATIONS.get(station_damage.station).name
     if station_damage.repaired_by is not None:
         crew_name = CREW_MEMBERS.get(station_damage.repaired_by)["name"]
         if station_damage.damaged_by is not None:
             return PlainResponse(
                 crew_name + " is repairing the " + station_name +
                 ", but it was futher damaged by enemy fire.")
         else:
             return PlainResponse(crew_name + " has repaired the " +
                                  station_name)
     elif station_damage.damaged_by == StationStateActor.ATTACK:
         return PlainResponse("The " + station_name +
                              " has been damaged by enemy fire.")
     elif station_damage.damaged_by == StationStateActor.FIRE:
         return PlainResponse("The fire in the " + station_name +
                              " has damaged it.")
 def unassigned_crew(unassigned_names, empty_stations):
     multiple_c = len(unassigned_names) > 1
     multiple_s = len(empty_stations) > 1
     return PlainResponse(
         handle_text_list(unassigned_names) + " " +
         ("have" if multiple_c else "has") +
         " not been assigned to a station." +
         " I suggest you assign them before we engage." +
         " You can say move crew member name to station name." +
         " The empty stations " + ("are" if multiple_s else "is") + " " +
         handle_text_list(empty_stations))
 def report_post_advance_state_response(hull, ls, warp, ehull, stations,
                                        end_game):
     """Ship state, station state, and end_game states."""
     return PlainResponse(" ".join([
         s for s in [
             "The hull has " + str(hull) +
             " points remaining. ", "The life support is charged to " +
             str(ls) + ". ", "The warp is charged to " + str(warp) +
             ". ", "The enemy hull has " + str(ehull) + " points left."
         ] + [
             QPContent.__adv_station_state(STATIONS.get(id).name, state)
             for (id, state) in stations.iteritems()
         ] + [QPContent.__report_end_game(end_game)] if s is not None
     ]))
Example #9
0
    def __handle_instruct_crew(self, slots, game_state):
        crew_id = self.__extract_id_from_slot(slots.get("crewSlot"))
        station_id = self.__extract_id_from_slot(slots.get("stationSlot"))

        try:
            (state, crew, station) = \
                self.__runner.instruct_crew(game_state, crew_id, station_id)

            response = build_speechlet_response_enahnced(
                QPContent.instruct_crew_response(crew["name"], station.name),
                reprompt=QPContent.INSTRUCT_CREW_REPROMPT,
                card=QPContent.INSTRUCT_CREW_CARD)
            return (response, state)
        except (CrewMemberInvalidException, StationInvalidException), e:
            response = build_speechlet_response_enahnced(
                PlainResponse(str(e)),
                QPContent.INSTRUCT_CREW_REPROMPT,
                card=QPContent.INVALID_INSTRUCTION_CARD)
            return (response, game_state)
 def __handle_life_support_threshold_breach(ls_breach):
     if not ls_breach.up:
         if ls_breach.threshold == "HIGH":
             return PlainResponse("We are losing life support charge!")
         elif ls_breach.threshold == "MID":
             return PlainResponse(
                 "Life Support state continues to worsen, " +
                 "consider repairing the Life Support station.")
         elif ls_breach.threshold == "LOW":
             return PlainResponse("Life support is critical, " +
                                  "repair or we will die, captain!")
     else:
         if ls_breach.threshold == "FULL":
             return PlainResponse("Life support is full restored.")
         elif ls_breach.threshold == "HIGH":
             return PlainResponse("Life Support is improving.")
         elif ls_breach.threshold == "MID":
             return PlainResponse("Life Support out of a critical state.")
 def __handle_health_threshold_breach(health_breach):
     if not health_breach.up:
         if health_breach.player:
             if health_breach.threshold == ResultThresholds["HIGH"]:
                 return PlainResponse("The hull is holding, captain.")
             elif health_breach.threshold == ResultThresholds["MID"]:
                 return PlainResponse("The hull is weakening, captain.")
         elif health_breach.threshold == ResultThresholds["LOW"]:
             return PlainResponse(
                 "The hull is critically damaged, captain.")
         else:
             if health_breach.threshold == ResultThresholds["HIGH"]:
                 return PlainResponse(
                     "The enemy hull is withstnding our impacts, captain.")
             elif health_breach.threshold == ResultThresholds["MID"]:
                 return PlainResponse(
                     "The enemy hull is showing weakness, captain.")
             elif health_breach.threshold == ResultThresholds["LOW"]:
                 return PlainResponse(
                     "The enemy is critically damaged, let's finish them!")
     else:
         pass  # TODO handle up phrases
 def cs_station_unmanned_response(station_name):
     return PlainResponse(station_name + " is unmanned.")
 def instruct_crew_response(crew_name, station_name):
     return PlainResponse(crew_name + " has been moved to " + station_name)
 def __handle_life_support_depleted(life_support_depleted):
     return PlainResponse("Life support reserves is empty. " +
                          "The crew breaths its last breath " +
                          "as cold overtakes the ship.")
 def cs_crew_stations_reponse(crew_station_names_tuples):
     return PlainResponse(" ".join([
         QPContent.cs_crew_crew_manning_station(c, s)
         if s is not None else QPContent.cs_crew_not_assigned(c)
         for (c, s) in crew_station_names_tuples
     ]))
class QPContent(object):
    """Common Strings and Text output functions."""

    QUICK_PARTICLE_STRING = "Quick Particle"
    DEFAULT_OUTPUT = "Captain, I am not sure what you meant by that. " +\
        "Try asking the crew to move to stations " + \
        "or say engage to continue the battle."
    DEFAULT_RESPONSE = \
        PlainResponse(DEFAULT_OUTPUT)
    DEFAULT_CARD = SimpleCard(QUICK_PARTICLE_STRING, DEFAULT_OUTPUT)
    """
    New Game
    """

    NEW_GAME_INTRO = \
        "Captain, are you ok? Our core is damaged, our " + \
        "shields and warp drive are unusable. " + \
        "We should find another ship to scrap a core from, then we " + \
        "could get moving again."
    NEW_GAME_CARD_TITLE = "Quick Particle Ship Acquisition"
    STATION_DESCRIPTION = "You can assign crew members to our stations. " + \
        "Manned stations will operate more effectively. " + \
        "A crew member can also repair damaged stations or put out fires."
    MOVE_SUGGESTION_TEXT = \
        "You can assign your crew to stations by saying move " \
        + "crew name to station name. Say engage once you are ready " \
        + "to fight the enemy ship."

    @staticmethod
    def list_crew(crew_names):
        return "Our small crew is " + handle_text_list(crew_names) + "."

    @staticmethod
    def list_stations(station_names):
        return "Our functioning stations are " + \
            handle_text_list(station_names) + "."

    @staticmethod
    def describe_stage(opponent_name):
        # TODO Note, this is temporarily specific
        return "Luckily, There is an enemy ship called " + \
            opponent_name + \
            " off the port. It has begun firing on us."

    # TODO separate new game, stage, and instructions
    @staticmethod
    def new_game_response(crew_members, stations, opponent_name):
        return PlainResponse(" ".join([
            QPContent.NEW_GAME_INTRO,
            QPContent.describe_stage(opponent_name), "As a remminder, ",
            QPContent.list_crew(crew_members), QPContent.STATION_DESCRIPTION,
            QPContent.list_stations(stations), QPContent.MOVE_SUGGESTION_TEXT
        ]))

    """
    Instruct Crew
    """

    INSTRUCT_CREW_CARD = SimpleCard("Instruct crew member", "")
    INSTRUCT_CREW_REPROMPT = \
        PlainResponse("anymore to move? otherwise say GO when ready.")
    INVALID_INSTRUCTION_CARD = SimpleCard("Invalid Instruction", "")

    @staticmethod
    def instruct_crew_response(crew_name, station_name):
        return PlainResponse(crew_name + " has been moved to " + station_name)

    """
    Crew State
    """
    CREW_STATE_CARD = SimpleCard("Crew State", "")

    @staticmethod
    def cs_station_unmanned_response(station_name):
        return PlainResponse(station_name + " is unmanned.")

    @staticmethod
    def cs_station_not_avaliable_response(station_name):
        return PlainResponse("your ship does not have the " + station_name +
                             " station yet")

    @staticmethod
    def cs_station_is_invalid_response(station_name):
        return PlainResponse(station_name + " is not a valid station")

    @staticmethod
    def cs_crew_not_assigned(crew_name):
        return crew_name + " has not been assigned."

    @staticmethod
    def cs_crew_crew_manning_station(crew_name, station_name):
        return crew_name + " is manning the " + station_name + ". "

    @staticmethod
    def cs_crew_stations_reponse(crew_station_names_tuples):
        return PlainResponse(" ".join([
            QPContent.cs_crew_crew_manning_station(c, s)
            if s is not None else QPContent.cs_crew_not_assigned(c)
            for (c, s) in crew_station_names_tuples
        ]))

    @staticmethod
    def cs_crew_member_invalid_response(crew_name):
        return PlainResponse(crew_name + " is not in the crew")

    """
    Advance
    """

    @staticmethod
    def unassigned_crew(unassigned_names, empty_stations):
        multiple_c = len(unassigned_names) > 1
        multiple_s = len(empty_stations) > 1
        return PlainResponse(
            handle_text_list(unassigned_names) + " " +
            ("have" if multiple_c else "has") +
            " not been assigned to a station." +
            " I suggest you assign them before we engage." +
            " You can say move crew member name to station name." +
            " The empty stations " + ("are" if multiple_s else "is") + " " +
            handle_text_list(empty_stations))

    @staticmethod
    def report_post_advance_state_response(hull, ls, warp, ehull, stations,
                                           end_game):
        """Ship state, station state, and end_game states."""
        return PlainResponse(" ".join([
            s for s in [
                "The hull has " + str(hull) +
                " points remaining. ", "The life support is charged to " +
                str(ls) + ". ", "The warp is charged to " + str(warp) +
                ". ", "The enemy hull has " + str(ehull) + " points left."
            ] + [
                QPContent.__adv_station_state(STATIONS.get(id).name, state)
                for (id, state) in stations.iteritems()
            ] + [QPContent.__report_end_game(end_game)] if s is not None
        ]))

    @staticmethod
    def __adv_station_state(station_name, station):
        if station.fire > 0:
            if station.damaged:
                return "Our " + station_name + " is damaged and on fire. "
            else:
                return "Our " + station_name + " is on fire. "
        if station.damaged:
            return "Our " + station_name + " is damaged."
        return None

    """QP Results"""

    @staticmethod
    def handle_qp_results_respone(qp_results):
        return [
            resp
            for resp in [QPContent.handle_qp_result(r) for r in qp_results]
            if resp is not None
        ]

    @staticmethod
    def handle_qp_result(result):
        if isinstance(result, AttackMissed):
            return QPContent.__handle_attack_miss(result)
        elif isinstance(result, AttackHit):
            return QPContent.__handle_attack_hit(result)
        elif isinstance(result, StationDamageStateChange):
            return QPContent.__handle_station_damage_state_change(result)
        elif isinstance(result, StationFireStateChange):
            return QPContent.__handle_station_fire_state_change(result)
        elif isinstance(result, HealthThresholdBreached):
            return QPContent.__handle_health_threshold_breach(result)
        elif isinstance(result, LifeSupportThresholdBreached):
            return QPContent.__handle_life_support_threshold_breach(result)
        elif isinstance(result, LifeSupportDepleted):
            return QPContent.__handle_life_support_depleted(result)
        elif isinstance(result, HullDestroyed):
            return QPContent.__handle_hull_destroyed(result)

    @staticmethod
    def __handle_attack_miss(attack_miss):
        if attack_miss.player:
            return SSMLResponse(
                "<say-as interpret-as=\"interjection\">bah!</say-as> " +
                "we missed their ship.")
        else:
            return SSMLResponse(
                "<say-as interpret-as=\"interjection\">hooray</say-as> " +
                "they missed us.")

    @staticmethod
    def __handle_attack_hit(attack_hit):
        # TODO base result on damage done
        if attack_hit.player:
            return SSMLResponse(
                "<say-as interpret-as=\"interjection\">bam!</say-as> " +
                "we hit them!")
        else:
            return SSMLResponse(
                "<say-as interpret-as=\"interjection\">wham!</say-as> " +
                "they hit us captain.")

    @staticmethod
    def __handle_station_damage_state_change(station_damage):
        station_name = STATIONS.get(station_damage.station).name
        if station_damage.repaired_by is not None:
            crew_name = CREW_MEMBERS.get(station_damage.repaired_by)["name"]
            if station_damage.damaged_by is not None:
                return PlainResponse(
                    crew_name + " is repairing the " + station_name +
                    ", but it was futher damaged by enemy fire.")
            else:
                return PlainResponse(crew_name + " has repaired the " +
                                     station_name)
        elif station_damage.damaged_by == StationStateActor.ATTACK:
            return PlainResponse("The " + station_name +
                                 " has been damaged by enemy fire.")
        elif station_damage.damaged_by == StationStateActor.FIRE:
            return PlainResponse("The fire in the " + station_name +
                                 " has damaged it.")

    @staticmethod
    def __handle_station_fire_state_change(station_fire):
        station_name = STATIONS.get(station_fire.station).name
        if station_fire.extinguished_by is not None:
            crew_name = CREW_MEMBERS.get(station_fire.extinguished_by)["name"]
            if station_fire.start_by is not None:
                return PlainResponse("Enemy fire expanded the fire " +
                                     crew_name + " put out in the " +
                                     station_name)
            else:
                return PlainResponse(crew_name +
                                     " has extinguished the fire in the " +
                                     station_name)
        elif station_fire.start_by == StationStateActor.ATTACK:
            return PlainResponse("The " + station_name +
                                 " has started on fire.")

    @staticmethod
    def __handle_health_threshold_breach(health_breach):
        if not health_breach.up:
            if health_breach.player:
                if health_breach.threshold == ResultThresholds["HIGH"]:
                    return PlainResponse("The hull is holding, captain.")
                elif health_breach.threshold == ResultThresholds["MID"]:
                    return PlainResponse("The hull is weakening, captain.")
            elif health_breach.threshold == ResultThresholds["LOW"]:
                return PlainResponse(
                    "The hull is critically damaged, captain.")
            else:
                if health_breach.threshold == ResultThresholds["HIGH"]:
                    return PlainResponse(
                        "The enemy hull is withstnding our impacts, captain.")
                elif health_breach.threshold == ResultThresholds["MID"]:
                    return PlainResponse(
                        "The enemy hull is showing weakness, captain.")
                elif health_breach.threshold == ResultThresholds["LOW"]:
                    return PlainResponse(
                        "The enemy is critically damaged, let's finish them!")
        else:
            pass  # TODO handle up phrases

    @staticmethod
    def __handle_life_support_threshold_breach(ls_breach):
        if not ls_breach.up:
            if ls_breach.threshold == "HIGH":
                return PlainResponse("We are losing life support charge!")
            elif ls_breach.threshold == "MID":
                return PlainResponse(
                    "Life Support state continues to worsen, " +
                    "consider repairing the Life Support station.")
            elif ls_breach.threshold == "LOW":
                return PlainResponse("Life support is critical, " +
                                     "repair or we will die, captain!")
        else:
            if ls_breach.threshold == "FULL":
                return PlainResponse("Life support is full restored.")
            elif ls_breach.threshold == "HIGH":
                return PlainResponse("Life Support is improving.")
            elif ls_breach.threshold == "MID":
                return PlainResponse("Life Support out of a critical state.")

    @staticmethod
    def __handle_hull_destroyed(hull_destroyed):
        if hull_destroyed.player:
            return PlainResponse("The hull has been destroyed, all is lost.")
        else:
            return PlainResponse(
                "The enemy ship bursts apart, the crew lets out a " +
                "sigh of relief, then a cheer. On to the next challenge.")

    @staticmethod
    def __handle_life_support_depleted(life_support_depleted):
        return PlainResponse("Life support reserves is empty. " +
                             "The crew breaths its last breath " +
                             "as cold overtakes the ship.")
 def cs_station_not_avaliable_response(station_name):
     return PlainResponse("your ship does not have the " + station_name +
                          " station yet")
 def cs_crew_member_invalid_response(crew_name):
     return PlainResponse(crew_name + " is not in the crew")
 def cs_station_is_invalid_response(station_name):
     return PlainResponse(station_name + " is not a valid station")
Example #20
0
class QPSkillAdaptor(object):
    """Translates skill logic into QP game logic."""
    def __init__(self):
        """Build QP Skill Adaptor."""
        self.__runner = QPRunner()

    def on_intent(self, intent_data, session):
        """Route intents within qp."""
        meta = session.get("meta", {}) if session is not None else {}
        game_state = meta.get("game_state", {})
        new_game_state = game_state
        response = build_speechlet_response_enahnced(
            QPContent.DEFAULT_RESPONSE,
            card=QPContent.DEFAULT_CARD,
            should_end_session=False)
        intent_name = intent_data.get("name")

        # New Game
        if game_state is None or game_state == {}:
            (response, new_game_state) = self.__handle_new_game()
        else:
            state = self.__runner.transform_game_state(game_state)
            slots = intent_data.get("slots")
            if intent_name == "instructCrewIntent":  # Instruct Crew
                (response, new_game_state) = \
                    self.__handle_instruct_crew(slots, state)
            if intent_name == "crewStateIntent":
                response = self.__handle_crew_state(slots, state)
            elif intent_name == "goIntent":  # Advance Combat
                (response, new_game_state) = \
                    self.__handle_combat(slots, state)

        # TODO this is gross, use immutable objects
        meta["game_state"] = self.__runner.to_json_friendly(new_game_state)
        session["meta"] = meta

        # TODO do more with game end
        # TODO keep session alive when not lost
        return build_response(session, response)

    def __handle_new_game(self):
        """Create a new game.

        NOTE: In the future, creating and priming a stage will be separate
        from creating a new ship.

        Create new ship
        Create the a new stage
        Prime the ship's stage persistent status.
        """
        game_state = self.__runner.new_game(CONSTANTS.STARTING_CREW_MEMBERS,
                                            STARTING_STATIONS)

        # Create a new stage/opponent
        new_stage = self.__runner.start_stage(
            "Destroyer", {
                STATS.HULL_HEALTH: 50,
                STATS.ATTACK_POWER: 5,
                STATS.DODGE: 2,
                STATS.SHIELD: 0,
                STATS.ACCURACY: 4,
                STATS.MAX_HULL_HEALTH: 50
            })
        # Set the stage
        game_state.stage = new_stage

        # TODO Prime based on ship calculated ship stats,
        # for now MH and MLS canonot be upgraded
        game_state.ship.stats = \
            self.__runner.prime_ship_for_combat(BASE_STATS)

        # Welcome message, introduce the crew, introduce the stations
        crew = [
            CREW_MEMBERS.get(c).get("name")
            for c in game_state.ship.crew.keys()
        ]

        stations = [
            STATIONS.get(s).name for s in game_state.ship.stations.keys()
        ]

        text = QPContent.new_game_response(crew, stations,
                                           new_stage.opponent.name)

        response = build_speechlet_response_enahnced(text)

        return (response, game_state)

    def __handle_instruct_crew(self, slots, game_state):
        crew_id = self.__extract_id_from_slot(slots.get("crewSlot"))
        station_id = self.__extract_id_from_slot(slots.get("stationSlot"))

        try:
            (state, crew, station) = \
                self.__runner.instruct_crew(game_state, crew_id, station_id)

            response = build_speechlet_response_enahnced(
                QPContent.instruct_crew_response(crew["name"], station.name),
                reprompt=QPContent.INSTRUCT_CREW_REPROMPT,
                card=QPContent.INSTRUCT_CREW_CARD)
            return (response, state)
        except (CrewMemberInvalidException, StationInvalidException), e:
            response = build_speechlet_response_enahnced(
                PlainResponse(str(e)),
                QPContent.INSTRUCT_CREW_REPROMPT,
                card=QPContent.INVALID_INSTRUCTION_CARD)
            return (response, game_state)
        except MemberAlreadyInStationException, e:
            response = build_speechlet_response_enahnced(
                PlainResponse(str(e)),
                QPContent.INSTRUCT_CREW_REPROMPT,
                card=QPContent.INVALID_INSTRUCTION_CARD)
            return (response, game_state)