def act_defender(self, me: Robot, rules: Rules, game: Game, action: Action): self.defender = me gate_center = rules.arena.width / 2.0 gate_z_target = rules.arena.depth + game.ball.radius * 2 ball_curr_x = game.ball.x ball_curr_z = game.ball.z gate_center_direction = Vector2D(gate_center - ball_curr_x, gate_z_target - ball_curr_z).normalize() tiks_pass = 0 for point in self.last_prediction[:40]: if point.z < -20 and me.z < point.z: ball_to_center_point = Vector3D( point.x - gate_center_direction.x * game.ball.radius, point.z - gate_center_direction.z * game.ball.radius, point.y) delta_pos = ball_to_center_point - me need_speed = ROBOT_MAX_GROUND_SPEED target_velocity = delta_pos.normalize() * need_speed poses = self.predict_move(me, target_velocity, tiks=tiks_pass + 1) if (poses[tiks_pass] - point).len() <= self.game.ball.radius + me.radius: jump_predict = self.predict_jump( me, tiks=min(tiks_pass + 1, 15), target_vel=target_velocity) jump = False for i in range(0, min(tiks_pass + 1, 15)): jp = jump_predict[i] bp = self.last_prediction[i] dist_to_ball = ((jp.x - bp.x)**2 + (jp.y - bp.y)**2 + (jp.z - bp.z)**2)**0.5 jump = (dist_to_ball <= BALL_RADIUS + ROBOT_MAX_RADIUS and jp.z < game.ball.z - game.ball.radius) if jump: break action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False return tiks_pass += 1 target_pos = Vector2D(0.0, -(rules.arena.depth / 2.0)) target_velocity = Vector2D( target_pos.x - me.x, target_pos.z - me.z) * ROBOT_MAX_GROUND_SPEED action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z
def act(self, me: Robot, rules: Rules, game: Game, action: Action): # Наша стратегия умеет играть только на земле # Поэтому, если мы не касаемся земли, будет использовать нитро # чтобы как можно быстрее попасть обратно на землю if not me.touch: action.target_velocity_x = 0.0 action.target_velocity_y = -MAX_ENTITY_SPEED action.target_velocity_z = 0.0 action.jump_speed = 0.0 action.use_nitro = True return dist_to_ball = ((me.x - game.ball.x)**2 + (me.y - game.ball.y)**2 + (me.z - game.ball.z)**2)**0.5 # Если при прыжке произойдет столкновение с мячом, и мы находимся # с той же стороны от мяча, что и наши ворота, прыгнем, тем самым # ударив по мячу сильнее в сторону противника jump = (dist_to_ball < BALL_RADIUS + ROBOT_MAX_RADIUS and me.z < game.ball.z) # Так как роботов несколько, определим нашу роль - защитник, или нападающий # Нападающим будем в том случае, если есть дружественный робот, # находящийся ближе к нашим воротам is_attacker = len(game.robots) == 2 for robot in game.robots: robot: Robot = robot if robot.is_teammate and robot.id != me.id: if robot.z < me.z: is_attacker = True if is_attacker: # Стратегия нападающего: # Просимулирем примерное положение мяча в следующие 10 секунд, с точностью 0.1 секунда for i in range(1, 101): t = i * 0.1 ball_x = game.ball.x ball_z = game.ball.z ball_vel_x = game.ball.velocity_x ball_vel_z = game.ball.velocity_z ball_pos = Vector2D(ball_x, ball_z) + \ Vector2D(ball_vel_x, ball_vel_z) * t # Если мяч не вылетит за пределы арены # (произойдет столкновение со стеной, которое мы не рассматриваем), # и при этом мяч будет находится ближе к вражеским воротам, чем робот, if ball_pos.z > me.z \ and abs(ball_pos.x) < (rules.arena.width / 2.0) \ and abs(ball_pos.z) < (rules.arena.depth / 2.0): # Посчитаем, с какой скоростью робот должен бежать, # Чтобы прийти туда же, где будет мяч, в то же самое время delta_pos = Vector2D(ball_pos.x, ball_pos.z) - Vector2D( me.x, me.z) need_speed = delta_pos.len() / t # Если эта скорость лежит в допустимом отрезке if 0.5 * ROBOT_MAX_GROUND_SPEED < need_speed \ and need_speed < ROBOT_MAX_GROUND_SPEED: # То это и будет наше текущее действие target_velocity = delta_pos.normalize() * need_speed action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False return # Стратегия защитника (или атакующего, не нашедшего хорошего момента для удара): # Будем стоять посередине наших ворот target_pos = Vector2D( 0.0, -(rules.arena.depth / 2.0) + rules.arena.bottom_radius) # Причем, если мяч движется в сторону наших ворот if game.ball.velocity_z < -EPS: # Найдем время и место, в котором мяч пересечет линию ворот t = (target_pos.z - game.ball.z) / game.ball.velocity_z x = game.ball.x + game.ball.velocity_x * t # Если это место - внутри ворот if abs(x) < rules.arena.goal_width / 2.0: # То пойдем защищать его target_pos.x = x # Установка нужных полей для желаемого действия target_velocity = Vector2D( target_pos.x - me.x, target_pos.z - me.z) * ROBOT_MAX_GROUND_SPEED action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False
def act(self, me: Robot, rules: Rules, game: Game, action: Action): GOAL = rules.arena.goal_width / 2.0 - rules.arena.goal_side_radius if not me.touch: action.target_velocity_x = 0.0 action.target_velocity_y = -MAX_ENTITY_SPEED action.target_velocity_z = 0.0 action.jump_speed = 0.0 action.use_nitro = True return #dist = me to ball dist = ((me.x - game.ball.x)**2 + (me.z - game.ball.z)**2)**0.5 #jump to ball jump = (dist <= BALL_RADIUS + ROBOT_MAX_RADIUS + JUMP_DIST) and (me.z < game.ball.z) #set robot for attacker is_attacker = len(game.robots) == 2 for robot in game.robots: robot: Robot = robot if robot.is_teammate and (robot.id != me.id): dist2 = ((robot.x - game.ball.x)**2 + (robot.z - game.ball.z)**2)**0.5 if dist2 > dist: is_attacker = True elif robot.z < me.z: is_attacker = True #ATTACK if is_attacker: for i in range(1,101): t = i * 0.1 ball_x = game.ball.x ball_z = game.ball.z ball_vel_x = game.ball.velocity_x ball_vel_z = game.ball.velocity_z ball_pos = Vector2D(ball_x, ball_z) + Vector2D(ball_vel_x, ball_vel_z) * t if (ball_z > me.z) and (abs(ball_pos.x) < rules.arena.width / 2.0) and (abs(ball_pos.z) <= rules.arena.depth / 2.0): to_ball = Vector2D(ball_pos.x, ball_pos.z) - Vector2D(me.x, me.z) speed = to_ball.len() / t if (0.5 * ROBOT_MAX_GROUND_SPEED < speed) and (speed < ROBOT_MAX_GROUND_SPEED): target_velocity = to_ball.normalize() * speed action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False return #DEFEND jump = 0.0 t = 1 def_pos = Vector2D(0.0, -rules.arena.depth / 2.0) if game.ball.velocity_z < -EPS: t = (def_pos.z - game.ball.z) / game.ball.velocity_z def_pos.x = game.ball.x + game.ball.velocity_x * t if def_pos.x < -GOAL: def_pos.x = -GOAL elif GOAL < def_pos.x: def_pos.x = GOAL to_pos = Vector2D(def_pos.x - me.x, def_pos.z - me.z) speed = min(to_pos.len() / t, ROBOT_MAX_GROUND_SPEED) def_velocity = to_pos.normalize() * speed if (game.ball.z + game.ball.velocity_z * t <= -rules.arena.depth / 2.0) and (me.z == def_pos.z): if game.ball.y + game.ball.velocity_y * t > 0: jump = ROBOT_MAX_JUMP_SPEED if game.ball.z <= -rules.arena.depth / 4.0: for i in range(1,101): t = i * 0.1 ball_x = game.ball.x ball_z = game.ball.z ball_vel_x = game.ball.velocity_x ball_vel_z = game.ball.velocity_z ball_pos = Vector2D(ball_x, ball_z) + Vector2D(ball_vel_x, ball_vel_z) * t to_ball = Vector2D(ball_pos.x, ball_pos.z) - Vector2D(me.x, me.z) speed = to_ball.len() / t target_velocity = to_ball.normalize() * speed action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.jump_speed = 0.0 action.use_nitro = False return action.target_velocity_x = def_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = def_velocity.z action.jump_speed = jump action.use_nitro = False
def act(self, me: Robot, rules: Rules, game: Game, action: Action): # Наша стратегия умеет играть только на земле # Поэтому, если мы не касаемся земли, будет использовать нитро # чтобы как можно быстрее попасть обратно на землю if not me.touch: action.target_velocity_x = 0.0 action.target_velocity_y = -MAX_ENTITY_SPEED action.target_velocity_z = 0.0 action.jump_speed = 0.0 action.use_nitro = True return # Найдем расстояние между мячом и роботом dist_to_ball = ((me.x - game.ball.x) ** 2 + (me.y - game.ball.y) ** 2 + (me.z - game.ball.z) ** 2 ) ** 0.5 # Найдем расстояние в плоскости xz (горизонтальной) dist_to_ball_xz = ((me.x-game.ball.x)**2 + (me.z-game.ball.z)**2)**0.5 # Если при прыжке произойдет столкновение с мячом, и мы находимся # с той же стороны от мяча, что и наши ворота, прыгнем, тем самым # ударив по мячу сильнее в сторону противника jump = (dist_to_ball < BALL_RADIUS +ROBOT_MAX_RADIUS and me.z < game.ball.z) # Далее описываются действия нападающего, который может иметь id либо 2, либо 4 if me.id==2 or me.id==4: # Если роботы вылетают за пределы горизонтального участка, # придаем скорость, которая вернет их назад if me.z < -rules.arena.depth/2.0+rules.arena.bottom_radius: action.target_velocity_z = ROBOT_MAX_GROUND_SPEED return if me.x > rules.arena.width/2.0: action.target_velocity_x = -ROBOT_MAX_GROUND_SPEED return if me.x < -rules.arena.width/2.0: action.target_velocity_x = ROBOT_MAX_GROUND_SPEED return e = 0.001 # Если мяч не вылетит за пределы арены # (произойдет столкновение со стеной, которое мы не рассматриваем), # и при этом мяч будет находится ближе к вражеским воротам, чем робот, if game.ball.z > me.z and abs(game.ball.x) < (rules.arena.width / 2.0) \ and abs(game.ball.z) < (rules.arena.depth / 2.0): # Посчитаем, с какой скоростью робот должен бежать, # Чтобы прийти туда же, где будет мяч, в то же самое время target_pos = Vector2D(0.0, (rules.arena.depth / 2.0) + rules.arena.bottom_radius) ball_pos = Vector2D(game.ball.x,game.ball.z) a = target_pos - ball_pos b = target_pos - Vector2D(me.x,me.z) c = ball_pos - Vector2D(me.x,me.z) cosine_a_b = cosine(a,b) cos_y = cosine(a,c) delta_pos = Vector2D(ball_pos.x, ball_pos.z) - Vector2D(me.x, me.z) # Если вектор скорости робота не сонаправлен с вектором, по которому требуется # ударить, чтобы мяч попал в центр ворот, то стремимся двигаться в сторону # увеличения cosine_a_b if abs(cosine_a_b) < 1 - e: #print(cos_y) sin_y = (1-cos_y**2)**0.5 #print(cos_y,a.x,a.z,a.len(),c.x,c.z,c.len()) if cos_y > 1: time.sleep(30) assert(cos_y < 1) if c.x > 0: x_d = c.x*cos_y+sin_y*c.z z_d = -c.x*sin_y+cos_y*c.z else: x_d = c.x*cos_y-sin_y*c.z z_d = c.x*sin_y+cos_y*c.z d = Vector2D(x_d,z_d) # print(d.x,d.z) # d.z = d.z if game.ball.y < 3 * BALL_RADIUS else -d.z target_velocity = d.normalize()*ROBOT_MAX_GROUND_SPEED # В противном случае бежим на мяч else: ball_pos = Vector2D(game.ball.x,game.ball.z) me_pos = Vector2D(me.x,me.z) delta_to_ball = ball_pos - me_pos target_velocity = delta_to_ball.normalize()*ROBOT_MAX_GROUND_SPEED # Если мяч летит в воздухе, надо научиться прыгать ровно в место встречи if game.ball.y > 2 * BALL_RADIUS and dist_to_ball_xz < 2 * BALL_RADIUS: # Для этого надо понять, через какое время мяч вернется на землю v0 = game.ball.velocity_y R = 2 * BALL_RADIUS h = game.ball.y g = 30 D = 4 * v0 * v0 - 4 * g * (2 * R - 2 * h) t = v0 / g + (D**0.5) / (2 * g) ball_pos_z = game.ball.z + game.ball.velocity_z*t*60 ball_pos_x = game.ball.x + game.ball.velocity_x*t*60 ball_pos = Vector2D(ball_pos_x,ball_pos_z) delta_dist_z = ball_pos_z - me.z velocity_z = delta_dist_z / (0.5*t+0.01) delta_dist_x = ball_pos_x - me.x velocity_x = delta_dist_x / (0.5*t+0.01) target_velocity = Vector2D(velocity_x,velocity_z) # Установим итоговую скорость action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 # Теперь разберемся, нужно ли прыгать, если при текущих скоростях, шар и робот # встретятся в воздухе ball_pos_x = game.ball.x ball_pos_y = game.ball.y ball_pos_z = game.ball.z speed_y_ball = game.ball.velocity_y delta_time = 2 / 60 / 100 speed_y = ROBOT_MAX_JUMP_SPEED me_y = 1 me_x = me.x me_z = me.z # Произведем небольшое моделирование ситуации for i in range(40*50): if game.ball.z < me.z: break ball_pos_x += game.ball.velocity_x*delta_time ball_pos_y += speed_y_ball*delta_time ball_pos_z += game.ball.velocity_z*delta_time ball_pos_y -= 15*delta_time*delta_time speed_y_ball -= 30*delta_time me_y += speed_y*delta_time me_y -= 15*delta_time*delta_time speed_y -= 30*delta_time if ball_pos_y < 2: speed_y_ball -= (1.7)*speed_y_ball me_x += me.velocity_x*delta_time me_z += me.velocity_z*delta_time dist_ball = ((me_x - ball_pos_x) ** 2 + (me_y - ball_pos_y) ** 2 + (me_z - ball_pos_z) ** 2 ) ** 0.5 gen_velocity = (speed_y ** 2+ me.velocity_x ** 2 + me.velocity_z ** 2) **0.5 # Если робот и шар пересекаются if dist_ball < (0.5*BALL_RADIUS +ROBOT_MAX_RADIUS) and abs(me_y-ball_pos_y) < 1 and i < 7000 and\ speed_y / gen_velocity < 0.5 and cos_y >0.81 or jump: # Тогда надо прыгать прямо сейчас # В полете робот неуправляем, поэтому решение о прыжке - довольно ответственно action.jump_speed = ROBOT_MAX_JUMP_SPEED break if jump: action.jump_speed = ROBOT_MAX_JUMP_SPEED action.use_nitro = False return # Если ничего не реализовалось, просто бежим на стартовую позицию target_pos = Vector2D(0.0, -(rules.arena.depth / 2.0) + rules.arena.bottom_radius) target_velocity = Vector2D( target_pos.x - me.x, target_pos.z - me.z) * ROBOT_MAX_GROUND_SPEED action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z return # Стратегия защитника: # Будем стоять посередине наших ворот radius = rules.arena.bottom_radius target_pos= Vector2D(0.0, -(rules.arena.depth / 2.0)) target_velocity = Vector2D((target_pos.x - me.x), (target_pos.z - me.z))*\ ROBOT_MAX_GROUND_SPEED t = 1 ball_pos_x = game.ball.x ball_pos_y = game.ball.y ball_pos_z = game.ball.z speed_y_ball = game.ball.velocity_y delta_time = 1 / 60 / 100 speed_y = ROBOT_MAX_JUMP_SPEED me_y = 1 me_x = me.x me_z = me.z # Произведем моделирование ситуации i = 0 for i in range(70*100): # Чтобы не тратить драгоценное время, если шар на чужой половине поля # не будем моделировать. На практике это не приводит к пропущенным мячам if game.ball.z > 0: break ball_pos_x += game.ball.velocity_x*delta_time ball_pos_y += speed_y_ball*delta_time ball_pos_z += game.ball.velocity_z*delta_time ball_pos_y -= 15*delta_time*delta_time speed_y_ball -= 30*delta_time target_z = -(rules.arena.depth / 2.0) + rules.arena.bottom_radius me_y += speed_y * delta_time me_y -= 15 * delta_time*delta_time speed_y -= 30 * delta_time me_x += me.velocity_x*delta_time me_z += me.velocity_z*delta_time dist_ball = ((me_x - ball_pos_x)**2+(me_y-ball_pos_y)**2+ (me_z-ball_pos_z)**2)**0.5 gen_velocity = (speed_y ** 2+ me.velocity_x ** 2 + me.velocity_z ** 2) **0.5 t = int(i/100) delta_dist_z = ball_pos_z - me.z velocity_z = delta_dist_z / (t+0.01) delta_dist_x = ball_pos_x - me.x velocity_x = delta_dist_x / (t+0.01) h = ball_pos_y - me_y # Если ожидаем столкновение с мячом в воздухе - прыгаем if dist_ball <(BALL_RADIUS+ROBOT_MAX_RADIUS) and (ball_pos_y > me_y): action.jump_speed = ROBOT_MAX_JUMP_SPEED # Если мяч должен прилететь в зону ворот, бежим на мяч if (ball_pos_z < -(rules.arena.depth / 2.0) + rules.arena.bottom_radius+10) and \ (abs(ball_pos_x) < rules.arena.goal_width / 2.0) and ball_pos_y < 2*BALL_RADIUS and\ me_z < ball_pos_z and h / dist_ball < 0.5: target_velocity = Vector2D(velocity_x,velocity_z)*60 self.x = target_velocity.x self.z = target_velocity.z break # Выставляем команды action.target_velocity_x = target_velocity.x action.target_velocity_y = 0 action.target_velocity_z = target_velocity.z action.use_nitro = False if jump: action.jump_speed = ROBOT_MAX_JUMP_SPEED
def act(self, me: Robot, rules: Rules, game: Game, action: Action): if not me.touch: action.target_velocity_x = 0.0 action.target_velocity_y = -MAX_ENTITY_SPEED action.target_velocity_z = 0.0 action.jump_speed = 0.0 action.use_nitro = True return #dist = me to ball dist = ((me.x - game.ball.x)**2 + (me.y - game.ball.y)**2 + (me.z - game.ball.z)**2)**0.5 #jump to ball jump = (dist <= BALL_RADIUS + ROBOT_MAX_RADIUS + JUMP_DIST) and ( me.z < game.ball.z) #set robot for attacker is_attacker = True for robot in game.robots: robot: Robot = robot if robot.is_teammate and (robot.id != me.id): if robot.z >= me.z: is_attacker = False #ATTACK if is_attacker: for i in range(1, 21): t = i * 0.1 ball_x = game.ball.x ball_z = game.ball.z ball_vel_x = game.ball.velocity_x ball_vel_z = game.ball.velocity_z ball_pos = Vector2D( ball_x, ball_z) + Vector2D(ball_vel_x, ball_vel_z) * t to_ball = Vector2D(ball_pos.x, ball_pos.z) - Vector2D( me.x, me.z) speed = to_ball.len() / t target_velocity = to_ball.normalize() * speed action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False return #DEFEND if game.ball.z <= -5: for i in range(1, 101): t = i * 0.1 ball_x = game.ball.x ball_z = game.ball.z ball_vel_x = game.ball.velocity_x ball_vel_z = game.ball.velocity_z ball_pos = Vector2D( ball_x, ball_z) + Vector2D(ball_vel_x, ball_vel_z) * t if (ball_z > me.z) and (abs( ball_pos.x) < rules.arena.width / 2.0) and (abs( ball_pos.z) <= rules.arena.depth / 2.0): to_ball = Vector2D(ball_pos.x, ball_pos.z) - Vector2D( me.x, me.z) speed = to_ball.len() / t if (0.5 * ROBOT_MAX_GROUND_SPEED < speed) and (speed < ROBOT_MAX_GROUND_SPEED): target_velocity = to_ball.normalize() * speed action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False return #defender stand in the mid of goal target_pos = Vector2D(game.ball.x, -rules.arena.depth / 2.0) if (game.ball.x < -14): target_pos = Vector2D(-14, -rules.arena.depth / 2.0) elif (14 < game.ball.x): target_pos = Vector2D(14, -rules.arena.depth / 2.0) target_velocity = Vector2D( target_pos.x - me.x, target_pos.z - me.z) * ROBOT_MAX_GROUND_SPEED action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False
def act_attacker(self, me: Robot, rules: Rules, game: Game, action: Action): self.attacker = me gate_center = rules.arena.width / 2.0 gate_z_target = rules.arena.depth + game.ball.radius * 2 if game.ball.z - self.game.ball.radius * 3 > me.z: self.should_hit = True elif game.ball.z < me.z: self.should_hit = False if self.should_hit: if (Vector2D(game.ball.x, game.ball.z) - Vector2D( me.x, me.z)).len() < ROBOT_MAX_GROUND_SPEED * 0.75: tiks_pass = 0 for point in self.last_prediction[:45]: gate_center_direction = Vector2D(gate_center - point.x, gate_z_target - point.z).normalize() ball_to_center_point = Vector3D( point.x - gate_center_direction.x * game.ball.radius, point.z - gate_center_direction.z * game.ball.radius, 1) delta_pos = ball_to_center_point - me target_velocity = delta_pos.normalize( ) * ROBOT_MAX_GROUND_SPEED poses = self.predict_move(me, target_velocity, tiks=tiks_pass + 1) if (poses[tiks_pass].D2() - point.D2() ).len() <= self.game.ball.radius + me.radius: jump_predict = self.predict_jump( me, tiks=min(tiks_pass + 1, 10), target_vel=target_velocity) jump = False for i in range(0, min(tiks_pass + 1, 10)): jp = jump_predict[i] bp = self.last_prediction[i] dist_to_ball = (jp - bp).len() jump = ( dist_to_ball <= BALL_RADIUS + ROBOT_MAX_RADIUS and jp.z < game.ball.z - game.ball.radius) if jump: break action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False #print('predicted') return tiks_pass += 1 point = self.last_prediction[0] gate_center_direction = Vector2D( gate_center - point.x, gate_z_target - point.z).normalize() ball_to_center_point = Vector3D( point.x - gate_center_direction.x * game.ball.radius, point.z - gate_center_direction.z * game.ball.radius, 1) delta_pos = ball_to_center_point - me target_velocity = delta_pos.normalize() * ROBOT_MAX_GROUND_SPEED action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z jump_predict = self.predict_jump(me) jump = False for i in range(1, 15): jp = jump_predict[i] bp = self.last_prediction[i] dist_to_ball = ((jp.x - bp.x)**2 + (jp.y - bp.y)**2 + (jp.z - bp.z)**2)**0.5 jump = (dist_to_ball <= BALL_RADIUS + ROBOT_MAX_RADIUS and jp.z < game.ball.z - game.ball.radius) if jump: break action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 action.use_nitro = False #print('blind') return else: # Run to take place between our gate and ball tiks_pass = 0 for point in self.last_prediction: tiks_pass += 1 if point.y > self.game.ball.radius * 5: continue target_x = point.x #if target_x - me.x < 0: # target_x += game.ball.radius * 2 #else: # target_x -= game.ball.radius * 2 jump_predict = self.predict_jump(me) jump = False for i in range(1, 15): jp = jump_predict[i] bp = self.last_prediction[i] dist_to_ball = ((jp.x - bp.x)**2 + (jp.y - bp.y)**2 + (jp.z - bp.z)**2)**0.5 jump = (dist_to_ball <= BALL_RADIUS + ROBOT_MAX_RADIUS and jp.z < game.ball.z - game.ball.radius) if jump: break target_z = point.z - game.ball.radius * 3 target = Vector3D(target_x, target_z, 1) delta_pos = target - Vector3D(me.x, me.z, me.y) need_speed = ROBOT_MAX_GROUND_SPEED target_velocity = delta_pos.normalize() * need_speed action.target_velocity_x = target_velocity.x action.target_velocity_y = 0.0 action.target_velocity_z = target_velocity.z action.jump_speed = ROBOT_MAX_JUMP_SPEED if jump else 0.0 self.ataker_target = target return return