# Path: oscar/agent/commander/base_commander.py
# class BaseCommander(ABC, CustomAgent):
#     """
#     A base class for commander agents.
#     These are specialized agents that capable of delegating tasks to subordinates
#     """
# 
#     def __init__(self, subordinates: list):
#         """
#         :param subordinates: a list of agents. These must be initialized already !
#         """
#         super().__init__()
#         self._subordinates = subordinates
#         self._locked_choice = False
#         self._playing_subordinate = None
# 
#     def step(self, obs, locked_choice=None):
#         """
#         Does some work and choose a subordinate that will play
#         :param obs: observations from the game
#         :return: an action chosen by a subordinate
#         """
# 
#         """if not self._locked_choice:
#             self._playing_subordinate = self.choose_subordinate(obs)
#         play = self._playing_subordinate.step(obs)
#         try:
#             self._locked_choice = play["locked_choice"]
#         except KeyError:
#             self._locked_choice = False
#         return play"""
# 
#         if locked_choice is None:
#             locked_choice = self._locked_choice
# 
#         self._playing_subordinate = self.choose_subordinate(obs, locked_choice)
#         play = self._playing_subordinate.step(obs, locked_choice)
#         if "locked_choice" in play:
#             self._locked_choice = play["locked_choice"]
#         else:
#             self._locked_choice = False
#         return play
# 
#     def add_subordinate(self, agent):
#         """
#         Hires a subordinate
#         :param agent: to add
#         :return:
#         """
#         self._subordinates.append(agent)
# 
#     def remove_subordinate(self, agent):
#         """
#         Fires a subordinate
#         :param agent: to remove
#         :return:
#         """
#         self._subordinates.remove(agent)
# 
#     @abstractmethod
#     def choose_subordinate(self, obs, locked_choice):
#         """
#         Choose a subordinate among the list of subordinates, and make it play.
#         :return: A subordinate among the list of subordinates.
#         """
# 
#     def play_locked_choice(self):
#         return self._playing_subordinate
# 
#     def unlock_choice(self):
#         if self._locked_choice:
#             self._locked_choice = False
#             try:
#                 self._playing_subordinate.unlock_choice()
#             # Method does not exist = not a commander
#             except AttributeError:
#                 pass
# 
#     def setup(self, obs_spec, action_spec):
#         super().setup(obs_spec, action_spec)
#         for subordinate in self._subordinates:
#             subordinate.setup(obs_spec, action_spec)
# 
#     def reset(self):
#         super().reset()
#         for subordinate in self._subordinates:
#             subordinate.reset()
# 
#     def __str__(self):
#         """
#         See print_tree
#         :return:
#         """
#         return self.print_tree(0)
# 
#     def print_tree(self, depth):
#         """
#         Recursively builds the hierarchy tree of the agent
#         :param depth: current depth in the general tree (used for indentation in the string)
#         :return: hierarchy tree (string)
#         """
#         depth += 1
#         ret = "I am a {} and I have {} subordinates :\n".format(type(self).__name__, len(self._subordinates))
#         for subordinate in self._subordinates:
#             ret += "\t" * depth
#             try:
#                 ret += subordinate.print_tree(depth + 1)
#             except AttributeError:
#                 ret += str(subordinate) + "\n"
#         return ret
# 
# Path: oscar/util/location.py
# class Location:
# 
#     def __init__(self, minimap_loc=None, screen_loc=None, camera_loc=None):
#         self.minimap = minimap_loc
#         self.screen = screen_loc
#         self.camera = camera_loc
# 
#     def compute_minimap_loc(self, obs, shared):
#         scale_x = shared['camera'].width(obs) / shared['screen'].width(obs)
#         scale_y = shared['camera'].height(obs) / shared['screen'].height(obs)
# 
#         self.minimap = shared['minimap'].bound(obs, Point(
#             int(round(self.camera.x - 0.5*shared['camera'].width(obs) + self.screen.x * scale_x)),
#             int(round(self.camera.y - 0.5*shared['camera'].height(obs) + self.screen.y * scale_y))))
# 
#     def squarred_distance(self, other):
#         if not self.minimap or not other.minimap:
#             raise Exception("Can't compute distance")
#         return self.minimap.distance(other.minimap)
# 
#     def distance(self, other):
#         return math.sqrt(self.squarred_distance(other))
# 
#     def equals(self, other):
#         def equals_minimap():
#             return (not self.minimap and not other.minimap) \
#                 or (self.minimap and other.minimap and self.minimap.equals(other.minimap))
# 
#         def equals_screen():
#             return (not self.screen and not other.screen) \
#                 or (self.screen and other.screen and self.screen.equals(other.screen))
# 
#         def equals_camera():
#             return (not self.camera and not other.camera) \
#                 or (self.camera and other.camera and self.camera.equals(other.camera))
# 
#         return equals_minimap() and equals_screen() and equals_camera()
# 
#     def __str__(self):
#         return "Location {\n" \
#                + "  minimap: " + str(self.minimap) + "\n" \
#                + "  screen: " + str(self.screen) + "\n" \
#                + "  camera: " + str(self.camera) + "\n" \
#                + "}"


from oscar.agent.commander.base_commander import BaseCommander
from oscar.constants import *
from oscar.util.location import Location


class StrategyManager(BaseCommander):
    _ECONOMY_MANAGER = 0
    _COMBAT_MANAGER = 1
    _SCOUT = 2


# Path: oscar/agent/commander/base_commander.py
# class BaseCommander(ABC, CustomAgent):
#     """
#     A base class for commander agents.
#     These are specialized agents that capable of delegating tasks to subordinates
#     """
# 
#     def __init__(self, subordinates: list):
#         """
#         :param subordinates: a list of agents. These must be initialized already !
#         """
#         super().__init__()
#         self._subordinates = subordinates
#         self._locked_choice = False
#         self._playing_subordinate = None
# 
#     def step(self, obs, locked_choice=None):
#         """
#         Does some work and choose a subordinate that will play
#         :param obs: observations from the game
#         :return: an action chosen by a subordinate
#         """
# 
#         """if not self._locked_choice:
#             self._playing_subordinate = self.choose_subordinate(obs)
#         play = self._playing_subordinate.step(obs)
#         try:
#             self._locked_choice = play["locked_choice"]
#         except KeyError:
#             self._locked_choice = False
#         return play"""
# 
#         if locked_choice is None:
#             locked_choice = self._locked_choice
# 
#         self._playing_subordinate = self.choose_subordinate(obs, locked_choice)
#         play = self._playing_subordinate.step(obs, locked_choice)
#         if "locked_choice" in play:
#             self._locked_choice = play["locked_choice"]
#         else:
#             self._locked_choice = False
#         return play
# 
#     def add_subordinate(self, agent):
#         """
#         Hires a subordinate
#         :param agent: to add
#         :return:
#         """
#         self._subordinates.append(agent)
# 
#     def remove_subordinate(self, agent):
#         """
#         Fires a subordinate
#         :param agent: to remove
#         :return:
#         """
#         self._subordinates.remove(agent)
# 
#     @abstractmethod
#     def choose_subordinate(self, obs, locked_choice):
#         """
#         Choose a subordinate among the list of subordinates, and make it play.
#         :return: A subordinate among the list of subordinates.
#         """
# 
#     def play_locked_choice(self):
#         return self._playing_subordinate
# 
#     def unlock_choice(self):
#         if self._locked_choice:
#             self._locked_choice = False
#             try:
#                 self._playing_subordinate.unlock_choice()
#             # Method does not exist = not a commander
#             except AttributeError:
#                 pass
# 
#     def setup(self, obs_spec, action_spec):
#         super().setup(obs_spec, action_spec)
#         for subordinate in self._subordinates:
#             subordinate.setup(obs_spec, action_spec)
# 
#     def reset(self):
#         super().reset()
#         for subordinate in self._subordinates:
#             subordinate.reset()
# 
#     def __str__(self):
#         """
#         See print_tree
#         :return:
#         """
#         return self.print_tree(0)
# 
#     def print_tree(self, depth):
#         """
#         Recursively builds the hierarchy tree of the agent
#         :param depth: current depth in the general tree (used for indentation in the string)
#         :return: hierarchy tree (string)
#         """
#         depth += 1
#         ret = "I am a {} and I have {} subordinates :\n".format(type(self).__name__, len(self._subordinates))
#         for subordinate in self._subordinates:
#             ret += "\t" * depth
#             try:
#                 ret += subordinate.print_tree(depth + 1)
#             except AttributeError:
#                 ret += str(subordinate) + "\n"
#         return ret
# 
# Path: oscar/util/location.py
# class Location:
# 
#     def __init__(self, minimap_loc=None, screen_loc=None, camera_loc=None):
#         self.minimap = minimap_loc
#         self.screen = screen_loc
#         self.camera = camera_loc
# 
#     def compute_minimap_loc(self, obs, shared):
#         scale_x = shared['camera'].width(obs) / shared['screen'].width(obs)
#         scale_y = shared['camera'].height(obs) / shared['screen'].height(obs)
# 
#         self.minimap = shared['minimap'].bound(obs, Point(
#             int(round(self.camera.x - 0.5*shared['camera'].width(obs) + self.screen.x * scale_x)),
#             int(round(self.camera.y - 0.5*shared['camera'].height(obs) + self.screen.y * scale_y))))
# 
#     def squarred_distance(self, other):
#         if not self.minimap or not other.minimap:
#             raise Exception("Can't compute distance")
#         return self.minimap.distance(other.minimap)
# 
#     def distance(self, other):
#         return math.sqrt(self.squarred_distance(other))
# 
#     def equals(self, other):
#         def equals_minimap():
#             return (not self.minimap and not other.minimap) \
#                 or (self.minimap and other.minimap and self.minimap.equals(other.minimap))
# 
#         def equals_screen():
#             return (not self.screen and not other.screen) \
#                 or (self.screen and other.screen and self.screen.equals(other.screen))
# 
#         def equals_camera():
#             return (not self.camera and not other.camera) \
#                 or (self.camera and other.camera and self.camera.equals(other.camera))
# 
#         return equals_minimap() and equals_screen() and equals_camera()
# 
#     def __str__(self):
#         return "Location {\n" \
#                + "  minimap: " + str(self.minimap) + "\n" \
#                + "  screen: " + str(self.screen) + "\n" \
#                + "  camera: " + str(self.camera) + "\n" \
#                + "}"


# Path: oscar/agent/scripted/strategy_manager.py
from oscar.agent.commander.base_commander import BaseCommander
from oscar.constants import *
from oscar.util.location import Location



class StrategyManager(BaseCommander):
    _ECONOMY_MANAGER = 0
    _COMBAT_MANAGER = 1
    _SCOUT = 2


    def __init__(self, subordinates):