11""" Nome do módulo : ComportamentoGoleiro
22 Ano de criação : 2019/10
33 Descrição do módulo : Comportamento de Goleiro para Jogadores
4- Versão : 1 .0
4+ Versão : 2 .0
55 Pré-requisitos : IComportamento
6+ Geometria
7+ Mundo, Arena, Lado
8+ Ball
9+ Jogador
10+ math
611 Membros : Lorena Bassani
712"""
813from .IComportamento import IComportamento
14+ from ..Geometria import Ponto
15+ from ..Mundo import Mundo , Arena , Lado
16+ from ..Ball import Ball
17+ from ..Jogador import Jogador
18+ import math as m
919
1020class ComportamentoGoleiro (IComportamento ):
1121 def __init__ (self ):
12- IComportamento .__init__ (self )
22+ IComportamento .__init__ (self )
23+
24+ def definirObjetivo (self , jogador : Jogador , mundo : Mundo ):
25+ """ Ideia da implementação :
26+ Posicionar o robô de forma que ele impessa a trajetória da bola
27+ Como : Calcular o angulo de abertura entre a bola e o gol
28+ Posicionar o robô onde o "triangulo" tenha base de 7,5 (tamanho do robô)
29+ """
30+ resp = Ponto ()
31+ ball = mundo .ball
32+ bx , _ = ball .posicao
33+ bt = ball .theta
34+ """ a² = b² + c² - 2bc*cos α
35+ a² - b² - c² = -2bc* cos α
36+ (b² + c² - a²)/2bc = cos α
37+ α = acos(((b² + c² - a²)/2bc))
38+ Onde :
39+ a <- lado oposto (tamanho do gol)
40+ b e c <- lados adjascentes (distancia da bola até um dos limites do gol)
41+ α <- angulo desejado
42+ """
43+ gol = Arena .golDireito if mundo .lado == Lado .DIREITO else Arena .golEsquerdo
44+ a = Arena .metricas ["Gol" ][1 ]
45+ b = ball .ponto .distancia (gol ["Superior" ])
46+ c = ball .ponto .distancia (gol ["Inferior" ])
47+ alpha = (b ** 2 + c ** 2 - a ** 2 )/ 2 * b * c
48+ if alpha > 1 :
49+ alpha = 1.0
50+ elif alpha < - 1 :
51+ alpha = - 1.0
52+ alpha = m .acos (alpha )
53+
54+ dx = 3.75 / m .tan (alpha ) if m .tan (alpha ) != 0 else 0 # 3.75 é metade da largura do robô de 7.5x7.5
55+ resp .x = bx + dx if mundo .lado == Lado .DIREITO else bx - dx
56+
57+ theta = m .fabs (bt - jogador .theta )
58+ resp .y = (resp .x / m .tan (theta ))
59+
60+ resp .y = 100 if resp .y > 100 else 30 if resp .y < 30 else resp .y
61+ resp .posicao = (10 , 65 ) if mundo .lado == Lado .ESQUERDO and resp .x > 37.5 else (150 , 65 ) if mundo .lado == Lado .DIREITO and resp .x < 112.5 else resp .posicao
62+
63+ return resp
0 commit comments