def has_intersection_with_tiles(distance): course = tire_speed.normalized() * distance line = Line(begin=get_current_tile(context.position, tile_size), end=get_current_tile(context.position + course, tile_size)) return make_has_intersection_with_lane( position=context.position, course=course, barriers=list(chain(generate_barriers(line))), width=context.game.tire_radius, )(0)
def path_has_tiles(path, tiles, tile_size, tile_type): for p in path: if is_in_world(p, tiles, tile_size): tile = get_current_tile(p, tile_size) if tiles[tile.x][tile.y] == tile_type: return True return False
def first_point_index(path, tiles, tile_size, tile_type): for i, p in enumerate(path): if is_in_world(p, tiles, tile_size): tile = get_current_tile(p, tile_size) if tiles[tile.x][tile.y] == tile_type: return i return len(path)
def generate(): for i, p in islice(enumerate(path), len(path) - 1): middle = (p + path[i + 1]) / 2 yield get_current_tile(middle, 1)
def make_tiles_points(points, tile_size, world_height): return dict((get_point_index(get_current_tile(v, tile_size), world_height), OrderedPoint(index=i, position=v)) for i, v in enumerate(points))
def make_tiles_bonuses(bonuses, tile_size, world_height): result = defaultdict(list) for v in bonuses: index = get_point_index(get_current_tile(v, tile_size), world_height) result[index].append(v) return result
def is_in_empty_tile(position, tiles, tile_size): tile = get_current_tile(position, tile_size) return tiles[tile.x][tile.y] == TileType.EMPTY
def tile(self): return get_current_tile(self.position, self.game.track_tile_size)
def get(self, context: Context, path): if (self.__tiles is None or self.__tile_barriers is None or self.__tiles != context.world.tiles_x_y): self.__tiles = copy(context.world.tiles_x_y) self.__tile_barriers = make_tiles_barriers( tiles=context.world.tiles_x_y, margin=context.game.track_tile_margin, size=context.game.track_tile_size, ) tile_size = context.game.track_tile_size sub_path = [context.position] + path if reduce(mul, generate_cos(path), 1) < 0: target_position = Curve(sub_path).at(tile_size) else: target_position = Polyline(sub_path).at(tile_size) course = target_position - context.position current_tile = context.tile target_tile = get_current_tile(target_position, tile_size) target_tile.x = max(0, min(context.world.width - 1, target_tile.x)) target_tile.y = max(0, min(context.world.height - 1, target_tile.y)) range_x = list(range(current_tile.x, target_tile.x + 1) if current_tile.x <= target_tile.x else range(target_tile.x, current_tile.x + 1)) range_y = list(range(current_tile.y, target_tile.y + 1) if current_tile.y <= target_tile.y else range(target_tile.y, current_tile.y + 1)) def generate_tiles(): for x in range_x: for y in range_y: yield Point(x, y) row_size = context.world.height def generate_tiles_barriers(): def impl(): for tile in generate_tiles(): yield self.__tile_barriers[get_point_index(tile, row_size)] return (v for v in chain.from_iterable(impl())) all_units = list( Unit(Point(v.x, v.y), Point(v.speed_x, v.speed_y)) for v in chain( (v for v in context.world.cars if v.id != context.me.id and (v.speed_x > 0 or v.speed_y > 0)), (x for x in context.world.projectiles), ) ) tiles_barriers = generate_tiles_barriers() projectiles_barriers = generate_projectiles_barriers(context) cars_barriers = generate_cars_barriers(context) oil_slicks_barriers = generate_oil_slicks_barriers(context) all_barriers = list(chain( tiles_barriers, (BarrierLimit(v, 0.9) for v in projectiles_barriers), (BarrierLimit(v, 0.8) for v in cars_barriers), (BarrierLimit(v, 0.7) for v in oil_slicks_barriers), )) width = max(context.me.width, context.me.height) angle = course.rotation(context.direction) static = make_has_intersection_with_lane( position=context.position, course=course * (0.75 + context.speed.norm() / MAX_SPEED), barriers=all_barriers, width=width, ) world_tiles = context.world.tiles_x_y def dynamic(current_angle): if abs(current_angle) > 0.6: return False my_speed = course.rotate(current_angle) * context.speed.norm() my_line = Line(context.position, context.position + my_speed) for unit in all_units: if unit.speed.norm() == 0: continue unit_line = Line(unit.position, unit.position + unit.speed) intersection = my_line.intersection(unit_line) if intersection is None: continue if not is_in_world(intersection, world_tiles, tile_size): continue if is_in_empty_tile(intersection, world_tiles, tile_size): continue unit_dir = intersection - unit.position if unit_dir.norm() == 0 or unit_dir.cos(unit.speed) < 0: continue if unit_dir.norm() > my_speed.norm() * 100: continue my_dir = intersection - context.position if my_dir.norm() == 0 or my_dir.cos(my_speed) < 0: continue unit_time = unit_dir.norm() / unit.speed.norm() my_time = my_dir.norm() / my_speed.norm() if abs(my_time - unit_time) <= MY_INTERVAL: return True return False def adjust(has_intersection, begin, end): return adjust_course(has_intersection, angle, begin, end) if context.speed.norm() > 0: rotation = adjust(lambda x: dynamic(x) or static(x), -1, 1) else: rotation = adjust(static, -1, 1) if rotation is not None: return course.rotate(rotation) return course
def test_at_100_100_with_tile_size_100_returns_1_1(self): result = get_current_tile(point=Point(x=100, y=100), tile_size=100) assert_that(result, equal_to(Point(1, 1)))
def generate(): for i, p in islice(enumerate(path), len(path) - 1): middle = (p + path[i + 1]) / 2 yield get_current_tile(middle, 1)
def make_tiles_points(points, tile_size, world_height): return dict((get_point_index(get_current_tile(v, tile_size), world_height), OrderedPoint(index=i, position=v)) for i, v in enumerate(points))
def make_tiles_bonuses(bonuses, tile_size, world_height): result = defaultdict(list) for v in bonuses: index = get_point_index(get_current_tile(v, tile_size), world_height) result[index].append(v) return result