예제 #1
0
def head_to_food_to_tail_direction(data, aStar, walls, nearest_food,
                                   survival_directions):

    you_x = data['you']['body'][0]['x']
    you_y = data['you']['body'][0]['y']
    aStar.reset_grid_and_start((you_x, you_y),
                               (nearest_food[0], nearest_food[1]))

    to_food_path = aStar.solve()

    single_lane = check_if_path_in_between_walls(data, aStar, to_food_path,
                                                 walls)
    if (single_lane):
        #print("Attack Path is between walls, ignore it: " + str(path))
        to_food_path = None
        return None

    #can get to food
    if (to_food_path != None):
        tail_x = data['you']['body'][len(data['you']['body']) - 1]['x']
        tail_y = data['you']['body'][len(data['you']['body']) - 1]['y']

        head_blocking_aStar, new_walls = init_astar(data, True)

        head_blocking_aStar.reset_grid_and_start(
            (nearest_food[0], nearest_food[1]), (tail_x, tail_y))

        to_tail_path = head_blocking_aStar.solve()

        if (to_tail_path != None):

            single_lane = check_if_path_in_between_walls(
                data, head_blocking_aStar, to_tail_path, new_walls)
            if (single_lane):
                #print("Attack Path is between walls, ignore it: " + str(path))
                to_tail_path = None
                return None

            path_directions = get_directions(you_x, you_y, to_food_path[1][0],
                                             to_food_path[1][1])

            #if direction of food not in viable direction, remove option
            revised_path_directions = []
            for direction in path_directions:
                if (direction in survival_directions):
                    revised_path_directions.append(direction)

            if (DEBUG_LOGS):
                print("To Food to Tail direction : ", revised_path_directions)
            if (len(revised_path_directions) > 0):
                return revised_path_directions

    return None
예제 #2
0
def find_own_tail_path(aStar, walls, data, growing, valid_move_tiles):
    #reset grid to have tail space as goal
    tail_x = data['you']['body'][len(data['you']['body']) - 1]['x']
    tail_y = data['you']['body'][len(data['you']['body']) - 1]['y']

    #if head and tail are the same space, ie starting turn
    if ((tail_x == data['you']['body'][0]['x'])
            and (tail_y == data['you']['body'][0]['y'])):
        directions = []
        if (DEBUG_LOGS):
            print("Tail and head are on the same tile: " + str(tail_x) + " " +
                  str(tail_y))
        return directions

    #if growing, need to find path to space before tail and solid tail
    if (growing):
        new_aStar, new_walls = init_astar(data, False, True)
        new_aStar.set_ending_for_init_grid((tail_x, tail_y))
        path = new_aStar.solve()
    else:
        aStar.reset_grid((tail_x, tail_y))
        path = aStar.solve()

    if (DEBUG_LOGS):
        print("Path to tail = " + str(path))

    if (path != None and check_if_path_goes_through_valid_survival_tiles(
            path, valid_move_tiles)):
        directions = get_directions(data['you']['body'][0]['x'],
                                    data['you']['body'][0]['y'], path[1][0],
                                    path[1][1])

        if (growing):
            single_lane = path_single_lane_check(data, aStar, new_walls, path)
        else:
            single_lane = path_single_lane_check(data, aStar, walls, path)

        for i in range(len(directions)):
            directions[i] = (directions[i], single_lane)

        if (DEBUG_LOGS):
            print("Path to tail direction = " + str(directions))

        return directions

    if (DEBUG_LOGS):
        print("No path to tail")

    return [(None, False)]
예제 #3
0
def find_other_snake_tail_path(data, aStar, walls, valid_move_tiles):
    shortest_path = None
    snake_following_name = ''
    short_walls = walls
    #reset grid to have tail space as goal
    for i in range(len(data['board']['snakes'])):
        if (data['board']['snakes'][i]['id'] == data['you']['id']):
            continue  #skip self

        tail_x = data['board']['snakes'][i]['body'][
            len(data['board']['snakes'][i]['body']) - 1]['x']
        tail_y = data['board']['snakes'][i]['body'][
            len(data['board']['snakes'][i]['body']) - 1]['y']

        #if head and tail are the same space, ie starting turn
        if ((tail_x == data['board']['snakes'][i]['body'][0]['x'])
                and (tail_y == data['board']['snakes'][i]['body'][0]['y'])):
            directions = []
            #if (DEBUG_LOGS):
            #print("Tail and head of snake " + str(data['board']['snakes'][i]['name']) + " are on the same tile: " + str(tail_x) + " " + str(tail_y))
            return directions

        growing = determine_if_snake_growing(data, i)

        #if growing, need to find path to space before tail and solid tail
        if (growing):
            new_aStar, new_walls = init_astar(data, False, False, i)
            new_aStar.set_ending_for_init_grid((tail_x, tail_y))
            path = new_aStar.solve()
            #if path is just 2, it is current head and tail spot, and since growing that path will not be valid
            #and if not enough valid tiles to rework path, path is none
            if (path != None and len(path) <= 2 and len(valid_move_tiles) < 2):
                path = None

        else:
            aStar.reset_grid((tail_x, tail_y))
            path = aStar.solve()

        #if (DEBUG_LOGS):
        #print("Path to opposing tail = " + str(path))

        if (path != None
                and (shortest_path == None or len(path) < len(shortest_path))
                and check_if_path_goes_through_valid_survival_tiles(
                    path, valid_move_tiles)):
            shortest_path = path
            snake_following_name = str(data['board']['snakes'][i]['name'])

            if (growing):
                short_walls = new_walls
            else:
                short_walls = walls

    if (shortest_path != None):
        directions = get_directions(data['you']['body'][0]['x'],
                                    data['you']['body'][0]['y'],
                                    shortest_path[1][0], shortest_path[1][1])

        single_lane = path_single_lane_check(data, aStar, short_walls,
                                             shortest_path)

        for i in range(len(directions)):
            directions[i] = (directions[i], single_lane)

        if (DEBUG_LOGS):
            print("Path to snake " + snake_following_name +
                  " tail direction = " + str(directions))

        return directions

    if (DEBUG_LOGS):
        print("No path to snake opposing snakes tails")

    return [(None, False)]
예제 #4
0
    def find_closest_tile_to_enemy(self, possible_tiles, possible_directions):

        #grab closest tile and distance for each snake, choose tile closest to the most snakes, not just closest tile to a snake

        closest_tiles = {}
        smallest_distances = {}
        closest_directions = {}

        #determine closest opposing snake
        for i in range(len(self.data['board']['snakes'])):
            if (self.data['board']['snakes'][i]['id'] == self.data['you']['id']
                ):
                continue  #skip self

            temp_data = copy.deepcopy(self.data)

            #if turn 0, body len 3 and all on same tile
            lost_head = temp_data['board']['snakes'][i]['body'].pop(0)

            if (self.data['turn'] == 0):
                for j in range(2):
                    temp_data['board']['snakes'][j]['body'].pop(0)

            temp_data['board']['snakes'][i]['head'] = temp_data['board'][
                'snakes'][i]['body'][0]

            aStar, walls = init_astar(temp_data, False, self.growing)

            closest_tiles[self.data['board']['snakes'][i]['id']] = []
            smallest_distances[self.data['board']['snakes'][i]['id']] = []
            closest_directions[self.data['board']['snakes'][i]['id']] = []

            #print("Snake: " + str(self.data['board']['snakes'][i]['name']))
            j = 0
            while (j < len(possible_tiles)):

                path = None

                aStar.reset_grid_and_start(
                    (possible_tiles[j]),
                    (self.data['board']['snakes'][i]['body'][0]['x'],
                     self.data['board']['snakes'][i]['body'][0]['y']))
                path = aStar.solve()

                if (path == None):
                    j += 1
                    continue

                distance = len(path)

                #if (DEBUG_LOGS):
                #print("Tile: " + str(possible_tiles[j]) + " distance: " + str(distance))

                if (len(smallest_distances[self.data['board']['snakes'][i]
                                           ['id']]) == 0
                        or distance < smallest_distances[
                            self.data['board']['snakes'][i]['id']][0]):
                    closest_tiles[self.data['board']['snakes'][i]['id']] = []
                    smallest_distances[self.data['board']['snakes'][i]
                                       ['id']] = []
                    closest_directions[self.data['board']['snakes'][i]
                                       ['id']] = []

                    smallest_distances[self.data['board']['snakes'][i]
                                       ['id']].append(distance)
                    closest_tiles[self.data['board']['snakes'][i]
                                  ['id']].append(possible_tiles[j])
                    closest_directions[self.data['board']['snakes'][i]
                                       ['id']].append(possible_directions[j])

                elif (distance == smallest_distances[self.data['board']
                                                     ['snakes'][i]['id']][0]):

                    direct_distance_old = math.sqrt((
                        (closest_tiles[self.data['board']['snakes'][i]
                                       ['id']][0][0] -
                         self.data['board']['snakes'][i]['body'][0]['x'])**2
                    ) + ((closest_tiles[self.data['board']['snakes'][i]
                                        ['id']][0][1] -
                          self.data['board']['snakes'][i]['body'][0]['y'])**2))
                    direct_distance_new = math.sqrt((
                        (possible_tiles[j][0] -
                         self.data['board']['snakes'][i]['body'][0]['x'])**2
                    ) + ((possible_tiles[j][1] -
                          self.data['board']['snakes'][i]['body'][0]['y'])**2))

                    if (DEBUG_LOGS):
                        print("Tile: " + str(possible_tiles[j]) +
                              " distance old: " + str(direct_distance_old) +
                              " distance new: " + str(direct_distance_new))

                    if (direct_distance_new < direct_distance_old):
                        closest_tiles[self.data['board']['snakes'][i]
                                      ['id']] = []
                        smallest_distances[self.data['board']['snakes'][i]
                                           ['id']] = []
                        closest_directions[self.data['board']['snakes'][i]
                                           ['id']] = []

                        smallest_distances[self.data['board']['snakes'][i]
                                           ['id']].append(distance)
                        closest_tiles[self.data['board']['snakes'][i]
                                      ['id']].append(possible_tiles[j])
                        closest_directions[self.data['board']['snakes'][i]
                                           ['id']].append(
                                               possible_directions[j])

                    elif (direct_distance_new == direct_distance_old):
                        smallest_distances[self.data['board']['snakes'][i]
                                           ['id']].append(distance)
                        closest_tiles[self.data['board']['snakes'][i]
                                      ['id']].append(possible_tiles[j])
                        closest_directions[self.data['board']['snakes'][i]
                                           ['id']].append(
                                               possible_directions[j])

                j += 1

        if (DEBUG_LOGS):
            print("Closest Directions: " + str(closest_directions))

        average_directions = {}

        #go through possible directions for each snake, and take most commmon direction
        for i in range(len(self.data['board']['snakes'])):
            if (self.data['board']['snakes'][i]['id'] == self.data['you']['id']
                ):
                continue  #skip self

            for direction in closest_directions[self.data['board']['snakes'][i]
                                                ['id']]:
                if direction in average_directions:
                    average_directions[direction] += 1
                else:
                    average_directions[direction] = 1

        most_used_direction_count = 0
        best_directions = []

        for direction in average_directions:
            if (average_directions[direction] > most_used_direction_count):
                best_directions = []
                best_directions.append(direction)
                most_used_direction_count = average_directions[direction]
            elif (average_directions[direction] == most_used_direction_count):
                best_directions.append(direction)

        return best_directions
예제 #5
0
def get_move(data):

    aStar, walls = init_astar(data)

    #directions = ["up", "down", "left", "right"]
    survival_directions = survival_choices(
        data, walls, aStar)  #get bad options, remove them from contention

    growing = determine_if_growing(data)

    #check spacing
    spacing_directions, tail_directions, other_snake_tail_directions, can_follow_tail, can_follow_other_snake_tail, protectable_area = get_spacing_directions(
        data, aStar, walls, survival_directions, growing)

    if (DEBUG_LOGS):
        print("Final spacing directions: " + str(spacing_directions))

    food_directions, nearest_food = consumption_choices(
        data, aStar, walls, protectable_area)

    consumption_directions = directions1_in_directions2(
        food_directions, survival_directions)
    if (DEBUG_LOGS):
        print("Food move after survival direction clear: ",
              consumption_directions)

    #check to see if can attack snake
    attack_directions = get_attack_directions(data, aStar, walls,
                                              survival_directions)

    if (DEBUG_LOGS):
        print("Attack Directions: " + str(attack_directions))
    """priority, survive, avoid_collisions, space, attack, food
    all directions already filtered thorugh survival directions
    need to check if food fits in space,
    than space fits in avoid collisions
    than collision fits in survive

    Downward check in terms of prioity, make sure each less pressing thing fits in more pressing issue
    """

    #if viable path to tail, and a viable path to food, see if viable path from head -> food -> tail
    food_tail_directions = None
    if (can_follow_tail and consumption_directions != None
            and len(consumption_directions) > 0):
        food_tail_directions = head_to_food_to_tail_direction(
            data, aStar, walls, nearest_food, survival_directions)
        if (food_tail_directions != None):
            for direction in food_tail_directions:
                if (direction in survival_directions
                        and not (direction in spacing_directions)):
                    spacing_directions.append(direction)
            if (DEBUG_LOGS):
                print(
                    "Own snake tail follow and spacing after survival direction clear: ",
                    spacing_directions)

    #if viable path to opponent tail, and a viable path to food, see if viable path from head -> food -> opponent tail
    food_opponent_tail_directions = None
    if (can_follow_other_snake_tail and consumption_directions != None
            and len(consumption_directions) > 0):
        food_opponent_tail_directions = head_to_food_to_opponent_tail_direction(
            data, aStar, walls, nearest_food, survival_directions)
        if (food_opponent_tail_directions != None):
            for direction in food_opponent_tail_directions:
                if (direction in survival_directions
                        and not (direction in spacing_directions)):
                    spacing_directions.append(direction)
            if (DEBUG_LOGS):
                print(
                    "Other snake tail follow and spacing after survival direction clear: ",
                    spacing_directions)

    #temp until add collision avoidance
    no_head_collisions_directions = avoid_death_collisions(
        data, walls, survival_directions)

    #if can attack, set as preffered actions
    if (len(attack_directions) > 0):
        preferred_directions = attack_directions

    #if no viable attack, try to eat
    else:
        preferred_directions = get_directions_through_food_space_collision(
            consumption_directions, spacing_directions,
            no_head_collisions_directions, survival_directions,
            food_tail_directions, food_opponent_tail_directions)

    final_directions = get_directions_with_space_and_collision_merge(
        preferred_directions, spacing_directions,
        no_head_collisions_directions, survival_directions)

    #no path availabe that won't kill us, so just return any response
    if (len(final_directions) <= 0 and len(survival_directions) > 0):
        final_directions = survival_directions
    elif (len(final_directions) <= 0):
        final_directions = ["up", "down", "left", "right"]

    if (DEBUG_LOGS):
        print("Final Directions before last reform: " + str(final_directions))

    #multiple good options
    if (len(final_directions) > 1):

        #go around protectable area if possible
        if (DEBUG_LOGS):
            print("Protected area len: " + str(len(protectable_area)))
        if (len(protectable_area) >= 1):
            protect_directions = get_direction_to_protect_area(
                protectable_area, data, final_directions, growing)
        else:
            protect_directions = []

        #if multiple options continue with narrowing
        if (len(protect_directions) == 1):
            final_directions = protect_directions
            if (DEBUG_LOGS):
                print("Final Direction after protected area: " +
                      str(final_directions))
            direction = random.choice(final_directions)
            return direction

        #if some directions chosen, use them as next fliter, otherwise ignore
        if (len(protect_directions) > 1):
            final_directions = protect_directions

        if (DEBUG_LOGS):
            print("Final diretions before tail check: " +
                  str(final_directions))
            print("Tail diretions before tail check: " + str(tail_directions))

        #follow tail if possible
        pos_tail_directions = directions1_in_directions2(
            tail_directions, final_directions)

        if (pos_tail_directions != None and len(pos_tail_directions) > 0):
            final_directions = pos_tail_directions
            if (DEBUG_LOGS):
                print("Final Directions after tail: " + str(final_directions))
            direction = random.choice(final_directions)
            return direction

        #follow opponent tail if possible
        pos_tail_directions = directions1_in_directions2(
            other_snake_tail_directions, final_directions)

        if (pos_tail_directions != None and len(pos_tail_directions) > 0):
            final_directions = pos_tail_directions
            if (DEBUG_LOGS):
                print("Final Directions after opponent tail: " +
                      str(final_directions))
            direction = random.choice(final_directions)
            return direction

        #go straight if possible
        prev_directions = get_directions(data['you']['body'][0]['x'],
                                         data['you']['body'][0]['y'],
                                         data['you']['body'][1]['x'],
                                         data['you']['body'][1]['y'])

        if (prev_directions != None):
            inverse_directions = []
            for direction in prev_directions:
                if (direction == "left"):
                    inverse_directions.append("right")
                elif (direction == "right"):
                    inverse_directions.append("left")
                elif (direction == "down"):
                    inverse_directions.append("up")
                elif (direction == "up"):
                    inverse_directions.append("down")

            forward_directions = directions1_in_directions2(
                inverse_directions, final_directions)

            if (forward_directions != None and len(forward_directions) > 0):
                final_directions = forward_directions
                if (DEBUG_LOGS):
                    print("Final Directions after straight: " +
                          str(final_directions))
                direction = random.choice(final_directions)
                return direction

    if (DEBUG_LOGS):
        print("Just choosing random choice: " + str(final_directions))

    direction = random.choice(final_directions)
    return direction