def estimate_time_to_position(self, x, y, tank): dist = tank.get_distance_to(x, y) vt = Vector(tank.speedX, tank.speedY) tank_v = Vector(tank.x, tank.y) pt_v = Vector(x, y) d = pt_v - tank_v if d.is_zero(): return 0 tank_d_v = Vector(1, 0).rotate(tank.angle) if vt.is_zero() or d.is_zero(): vd_angle = 0 else: vd_angle = vt.angle(d) if tank_d_v.is_zero() or d.is_zero(): d_angle = 0 else: d_angle = tank_d_v.angle(d) # Short distances fix if dist < 100: if fabs(d_angle) < LOW_ANGLE: v0 = vt.projection(d) return solve_quadratic(FICTIVE_ACCELERATION/2, v0, -dist) #return dist/6 elif PI - fabs(d_angle) < LOW_ANGLE: v0 = vt.projection(d) return solve_quadratic(FICTIVE_ACCELERATION/2 * 0.75, v0, -dist) #return dist/6 /0.75 if d.is_zero(): values = (0, 0, 0, 0, 0, 0, 0, 1) else: values = ( d_angle, dist, vd_angle, vt.length(), tank.angular_speed, tank.crew_health/tank.crew_max_health, d_angle ** 2, 1 ) return sum([x * y for (x, y) in zip(values, TIME_ESTIMATION_COEF)])
def save_target_init_values(self, tank, x, y): if not self.enabled: return dist = tank.get_distance_to(x, y) vt = Vector(tank.speedX, tank.speedY) tank_v = Vector(tank.x, tank.y) pt_v = Vector(x, y) d = pt_v - tank_v tank_d_v = Vector(1, 0).rotate(tank.angle) if vt.is_zero(): vd_angle = 0 else: vd_angle = vt.angle(d) if d.is_zero(): self.last_target_time_init_values = (0, 0, 0, 0, 0, 0) self.last_target_time_init_values = (tank_d_v.angle(d), dist, vd_angle, vt.length(), tank.angular_speed, tank.crew_health / tank.crew_max_health)
def save_target_init_values(self, tank, x, y): if not self.enabled: return dist = tank.get_distance_to(x, y) vt = Vector(tank.speedX, tank.speedY) tank_v = Vector(tank.x, tank.y) pt_v = Vector(x, y) d = pt_v - tank_v tank_d_v = Vector(1, 0).rotate(tank.angle) if vt.is_zero(): vd_angle = 0 else: vd_angle = vt.angle(d) if d.is_zero(): self.last_target_time_init_values = (0, 0, 0, 0, 0, 0) self.last_target_time_init_values = ( tank_d_v.angle(d), dist, vd_angle, vt.length(), tank.angular_speed, tank.crew_health/tank.crew_max_health )
def estimate_time_to_position(self, x, y, tank): dist = tank.get_distance_to(x, y) vt = Vector(tank.speedX, tank.speedY) tank_v = Vector(tank.x, tank.y) pt_v = Vector(x, y) d = pt_v - tank_v if d.is_zero(): return 0 tank_d_v = Vector(1, 0).rotate(tank.angle) if vt.is_zero() or d.is_zero(): vd_angle = 0 else: vd_angle = vt.angle(d) if tank_d_v.is_zero() or d.is_zero(): d_angle = 0 else: d_angle = tank_d_v.angle(d) # Short distances fix if dist < 100: if fabs(d_angle) < LOW_ANGLE: v0 = vt.projection(d) return solve_quadratic(FICTIVE_ACCELERATION / 2, v0, -dist) #return dist/6 elif PI - fabs(d_angle) < LOW_ANGLE: v0 = vt.projection(d) return solve_quadratic(FICTIVE_ACCELERATION / 2 * 0.75, v0, -dist) #return dist/6 /0.75 if d.is_zero(): values = (0, 0, 0, 0, 0, 0, 0, 1) else: values = (d_angle, dist, vd_angle, vt.length(), tank.angular_speed, tank.crew_health / tank.crew_max_health, d_angle**2, 1) return sum([x * y for (x, y) in zip(values, TIME_ESTIMATION_COEF)])
def shell_will_hit_tank_going_to(self, shell, tank, x, y, et=None): if et is None: et = self.estimate_time_to_position(x, y, tank) dist = tank.get_distance_to(x, y) v0 = hypot(shell.speedX, shell.speedY) a = SHELL_ACCELERATION d = tank.get_distance_to_unit(shell) #d = shell.get_distance_to(x, y) t = solve_quadratic(a / 2, v0, -d) if self.shell_will_hit(shell, tank, factor=1.05) and (et > t): return 1 #self.max_move_distance(fabs(v0), FICTIVE_ACCELERATION, 3, t) < dist): if dist < 150: # short distance result = self.shell_will_hit(shell, fictive_unit(tank, x, y), factor=1.05) if result: pt_v = Vector(x, y) tank_v = Vector(tank.x, tank.y) dir = pt_v - tank_v shell_speed = Vector(shell.speedX, shell.speedY) if dir.is_zero() or shell_speed.is_zero(): return float(result) if dir.angle(shell_speed) < PI / 8 and shell.get_distance_to( x, y) > d: return 0.6 return result else: # long distance, check if our direction is intersecting segment between shell and shell + v_shell*t pt_v = Vector(x, y) tank_v = Vector(tank.x, tank.y) dir = tank_v - pt_v shell_v = Vector(shell.x, shell.y) shell_speed = Vector(shell.speedX, shell.speedY) next_shell = shell_v + shell_speed * (t + 5) if sign((shell_v - tank_v).cross_product(dir)) == sign( dir.cross_product(next_shell - tank_v)): return True else: return False
def shell_will_hit_tank_going_to(self, shell, tank, x, y, et=None): if et is None: et = self.estimate_time_to_position(x, y, tank) dist = tank.get_distance_to(x, y) v0 = hypot(shell.speedX, shell.speedY) a = SHELL_ACCELERATION d = tank.get_distance_to_unit(shell) #d = shell.get_distance_to(x, y) t = solve_quadratic(a/2, v0, -d) if self.shell_will_hit(shell, tank, factor=1.05) and (et > t): return 1 #self.max_move_distance(fabs(v0), FICTIVE_ACCELERATION, 3, t) < dist): if dist < 150: # short distance result = self.shell_will_hit(shell, fictive_unit(tank, x, y), factor=1.05) if result: pt_v = Vector(x, y) tank_v = Vector(tank.x, tank.y) dir = pt_v - tank_v shell_speed = Vector(shell.speedX, shell.speedY) if dir.is_zero() or shell_speed.is_zero(): return float(result) if dir.angle(shell_speed) < PI/8 and shell.get_distance_to(x, y) > d: return 0.6 return result else: # long distance, check if our direction is intersecting segment between shell and shell + v_shell*t pt_v = Vector(x, y) tank_v = Vector(tank.x, tank.y) dir = tank_v - pt_v shell_v = Vector(shell.x, shell.y) shell_speed = Vector(shell.speedX, shell.speedY) next_shell = shell_v + shell_speed * (t + 5) if sign((shell_v - tank_v).cross_product(dir)) == sign(dir.cross_product(next_shell - tank_v)): return True else: return False