Um coach é um módulo especial no NeonFC. O ```coach``` é tratado no sistema como uma entidade. Um coach é instanciado no objeto match (ver [```def start```](https://github.com/project-neon/NeonFC/blob/8b3c4aa5e14c7541d53f081011d13e9937eb170b/match/match_real_life.py#L38C8-L38C8)). Durante a sua inicialização, ele verifica pela chave ```match.coach_name``` para instanciar a classe certa. Para isso, é necessario adicionar a relação chave/valor na variável ```AVAILABLE_COACHES```, dentro de ```entities/coach/__init__.py```. O coach é executado durante toda iteração do loop principal, no update do ```match```. Ele é encarregado por escolher qual comportamento ([estratégia](conceitos---o-que-e-uma-estrategia.md)) cada um dos robôs da equipe vai seguir. Existem 3 maneiras que normalmente usamos para fazer isso: estático, cada estratégia é passada sempre para o mesmo robô; dinâmico, o coach escolhe qual estratégia cada robô seguirá, baseado na função das suas posições; ou ainda o coach playbook, do qual mais informações podem ser encontradas [aqui](conceitos---coach-playbook.md). Uma instância de ```Coach``` precisa ter apenas dois métodos: * ```__init__``` (construtor): No método construtor, deverá ser passada a referência da ```match```. Aqui, você poderá instanciar as estratégias contidas no seu coach, assim como objetos auxiliares para a tomada de decisão. * ```decide```: Esse método deverá atribuir para cada robô uma nova estratégia. É importante que após a execução desse método cada robô tenha uma estratégia válida, caso contrário o NeonFC irá quebrar. ### Exemplo 1: Atribuidor simples Nesse exmplo, usamos as estratégias da LARC 2020 de forma que, sempre os robôs de id 0, 1 e 2 recebem as estratégias ```Goalkeeper```, ```Attacker``` e ```Midfielder``` consecutivamente. ```python import algorithms import strategy import math from commons.math import angular_speed, speed, rotate_via_numpy, unit_vector class Coach(object): def __init__(self, match): self.match = match self.constraints = [ strategy.larc2020.GoalKeeper(self.match), strategy.larc2020.Attacker(self.match), strategy.larc2020.MidFielder(self.match) ] def decide (self): robots = [r.robot_id for r in self.match.robots] for robot_id in robots: self.match.robots[robot_id].strategy = self.constraints[robot_id] ``` Nesse caso, nada é necessário além de uma simples iteração, sabemos através da criação da lista ```match.robots``` que ela sempre será ordenada. Então a atribuição funcionará sempre. ### Exemplo 2: larc2020.py Esse exemplo é o coach utilizado pela equipe Project Neon na LARC 2020. ```python import algorithms import strategy import math from commons.math import angular_speed, speed, rotate_via_numpy, unit_vector class Coach(object): def __init__(self, match): self.match = match self.constraints = [ #estratégia - função eleitora - prioridade (strategy.larc2020.GoalKeeper(self.match), self.elect_goalkeeper, 0), (strategy.larc2020.Attacker(self.match), self.elect_attacker, 0), (strategy.larc2020.MidFielder(self.match), self.elect_midfielder, 0) ] def decide (self): robots = [r.robot_id for r in self.match.robots] for strategy, fit_fuction, priority in self.constraints: elected = -1 best_fit = -99999 for robot_id in robots: robot_fit = fit_fuction(self.match.robots[robot_id]) if (robot_fit > best_fit): best_fit = robot_fit elected = robot_id if self.match.robots[elected].strategy is None: self.match.robots[elected].strategy = strategy elif self.match.robots[elected].strategy.name != strategy.name: self.match.robots[elected].strategy = strategy self.match.robots[elected].start() robots.remove(elected) def elect_attacker(self, robot): dist_to_ball = math.sqrt( (robot.x - self.match.ball.x)**2 + (robot.y - self.match.ball.y)**2 ) return 1000 - dist_to_ball def elect_goalkeeper(self, robot): dist_to_goal = math.sqrt( (robot.x - 0)**2 + (robot.y - 0.65)**2 ) return 1000 - dist_to_goal def elect_midfielder(self, robot): return 1 ``` Assim que estiver familiarizado com a funçao do objeto ```coach``` você pode experimentar a criação através do [Playbook](conceitos---coach-playbook).