Пример #1
0
    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
Пример #2
0
    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
Пример #4
0
	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
Пример #6
0
    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