def take_control()

in agent/decision_modules/navigator.py [0:0]


    def take_control(self):
        """
        Takes a navigational action and records the resulting transition.

        """
        obs = yield
        curr_loc = kg.player_location
        action = self.get_action()
        response = yield action
        p_valid = self._valid_detector.action_valid(action, response)

        # Check if we've tried this action before
        tried_before = False
        if curr_loc.has_action_record(action):
            prev_valid, result = curr_loc.action_records[action]
            if result.startswith(response):
                tried_before = True

        curr_loc.add_action_record(action, p_valid, response)
        self._suggested_directions = self.get_mentioned_directions(response)
        if self._suggested_directions:
            dbg("[NAV] Suggested Directions: {}".format(self._suggested_directions))
        if action in self._suggested_directions: # Don't try the same nav action again
            self._suggested_directions.remove(action)

        # If an existing locations matches the response, then we're done
        possible_loc_name = Location.extract_name(response)
        existing_locs = kg.locations_with_name(possible_loc_name)
        if existing_locs:
            # If multiple locations match, we need the most similar
            if len(existing_locs) > 1:
                look = yield Look
                existing_loc = self.find_most_similar_loc(look, existing_locs)
            else:
                existing_loc = existing_locs[0]
            dbg("[NAV](revisited-location) {}".format(existing_loc.name))
            kg.add_connection(Connection(curr_loc, action, existing_loc))
            kg.player_location = existing_loc
            return

        # This is either a new location or a failed action
        if tried_before:
            known_destination = kg.connections.navigate(curr_loc, action)
            if known_destination:
                # We didn't reach the expected destination. Likely mislocalized.
                look = yield Look
                self.relocalize(look)
            else: # This has failed previously
                dbg("[NAV-fail] p={:.2f} Response: {}".format(p_valid, response))
        else:
            # This is a new response: do a look to see if we've moved.
            if p_valid < .1:
                dbg("[NAV](Suspected-Invalid) {}".format(response))
                return

            look = yield Look

            p_stay = fuzz.ratio(look, curr_loc.description) / 100.
            p_move = fuzz.ratio(look, response) / 100.
            moved = p_move > p_stay
            dbg("[NAV]({}) p={} {} --> {}".format(
                'val' if moved else 'inv', p_move, action, response))
            self.record(moved)
            if moved:
                # Check if we've moved to an existing location
                possible_loc_name = Location.extract_name(look)
                existing_locs = kg.locations_with_name(possible_loc_name)
                if existing_locs:
                    if len(existing_locs) > 1:
                        existing_loc = self.find_most_similar_loc(look, existing_locs)
                    else:
                        existing_loc = existing_locs[0]
                    dbg("[NAV](revisited-location) {}".format(existing_loc.name))
                    kg.add_connection(Connection(curr_loc, action, existing_loc))
                    kg.player_location = existing_loc
                    return

                # Finally, create a new location
                new_loc = Location(look)
                to_loc = kg.add_location(new_loc)
                kg.add_connection(Connection(curr_loc, action, new_loc))
                kg.player_location = new_loc