예제 #1
0
def direction_of_crawl(start: hexutil.Point, end: hexutil.Point, tiles: List[board.Tile]):
    # find neighbors of start
    start_neighbors = hexutil.touching_hexagons(start)
    # find neighbors of end
    end_neighbors = hexutil.touching_hexagons(end)
    # find union
    intersecting_neighbors = list(set(start_neighbors) & set(end_neighbors))
    static_piece = None
    # find one of those that is a piece
    for p in intersecting_neighbors:
        match = next((i for i in range(0, len(tiles)) if tiles[i].x == p.x and tiles[i].y == p.y), None)
        if match is not None:
            static_piece = p
            break

    if static_piece is None:
        return 0  # not valid move
    # calculate angle of start and angle of end in relation to that piece
    x_start = hexutil.relative_distance_x(static_piece, start)
    y_start = hexutil.relative_distance_y(static_piece, start)
    x_end = hexutil.relative_distance_x(static_piece, end)
    y_end = hexutil.relative_distance_y(static_piece, end)
    # find angle of start
    t_start = angle_of_vector(x_start, y_start)
    t_end = angle_of_vector(x_end, y_end)
    return (1, -1)[t_end > t_start]  # if increasing, then counter clockwise then -1
예제 #2
0
def is_one_hive(tiles: List[board.Tile]):
    tiles_count = len(tiles)
    main_hive = []
    if len(tiles) <= 1:
        return True

    main_tile = tiles.pop(0)
    main_hive.append(main_tile)
    stop = False
    actual_tiles = []
    while not stop:
        possible_tiles = hexutil.touching_hexagons(hexutil.Point(main_tile.x, main_tile.y))
        # check for above piece
        possible_tiles.append(hexutil.Point(main_tile.x, main_tile.y))
        for tile in possible_tiles:
            match = next((i for i in range(0, len(tiles)) if tiles[i].x == tile.x and tiles[i].y == tile.y), None)
            if match is not None:
                touching_tile = tiles.pop(match)
                actual_tiles.append(touching_tile)
                main_hive.append(touching_tile)
        if len(actual_tiles) != 0:
            main_tile = actual_tiles.pop(0)
        else:
            stop = True

    return tiles_count == len(main_hive)
예제 #3
0
def space_crawable(start: board.Tile, end: hexutil.Point, tiles: List[board.Tile], movement_cloud):
    # todo: need to be able to work in 3d space
    possible_paths = [deque()]
    # todo: add z axis to Move object
    possible_paths[0].append(Move(hexutil.Point(start.x, start.y), 0))

    temp = tiles[:]
    if start in temp:
        temp.remove(start)

    current_path = possible_paths[0]
    spots = start.piece.crawl_spaces or 20
    for i in range(1, spots + 1):
        paths_to_extend = possible_paths[:]
        p: deque[Move]
        for p in paths_to_extend:
            path_to_be_removed = p
            neighbors = hexutil.touching_hexagons(p[-1].position)
            for n in neighbors:
                # todo: add z axis in can_slide check
                if n in movement_cloud and can_slide_to(p[-1].position, n, temp, start.z):
                    # not (dir != p[-1]dir and not p[-2].hex == n)
                    if len(p) >= 2 and p[-2].position == n:
                        continue
                    elif n == end and start.piece.crawl_spaces is None:
                        return True
                    # todo: add in z axis when adding new move (axis of start z, cannot change)
                    possible_paths.append(p + deque([Move(n, direction_of_crawl(p[-1].position, n, temp))]))
                    # at end and cannot be moved to
                elif n == end:
                    return False

            possible_paths.remove(path_to_be_removed)

    return any(move[-1].position == end for move in possible_paths)
예제 #4
0
 def test_valid_moves_single_ant(self):
     t = [
         board.Tile(0, 0, 0, piece.create_ant('W')),
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
     ]
     moves = hexutil.touching_hexagons(hexutil.Point(1, 0))
     self.assertCountEqual(hiveutil.generate_valid_moves(t[0], t), moves)
예제 #5
0
def generate_hive_movement_cloud(tiles: List[board.Tile], mover):
    possible_spots = []
    for tile in tiles:
        neighbors = hexutil.touching_hexagons(hexutil.Point(tile.x, tile.y))
        for n in neighbors:
            if n in possible_spots:
                continue
            match = next((i for i in range(0, len(tiles)) if tiles[i].x == n.x and tiles[i].y == n.y
                          and tiles[i].z == mover.z), None)
            # if tile not occupied
            if match is None:
                possible_spots.append(n)
    return possible_spots
예제 #6
0
def space_hopable(start: board.Tile, end: hexutil.Point, tiles: List[board.Tile], movement_cloud):
    # determine if start and end are in the same line
    x_dist = hexutil.relative_distance_x(hexutil.Point(start.x, start.y), end)
    y_dist = hexutil.relative_distance_y(hexutil.Point(start.x, start.y), end)
    angle = angle_of_vector(x_dist, y_dist)
    if angle % 60 != 0:
        return False
    # determine if there are spaces open in that line
    match = -1
    space = start
    while end != space:
        n = hexutil.touching_hexagons(space)[int(angle / 60)]
        match = next((i for i in range(0, len(tiles)) if tiles[i].x == n.x and tiles[i].y == n.y), None)
        if match is None and end != n:
            return False
        space = n
    return True
예제 #7
0
def can_start_hop(start: hexutil.Point, tiles: List[board.Tile], z):
    neighbors = hexutil.touching_hexagons(hexutil.Point(start.x, start.y))
    touches = 0
    max_continuous_touches = 0
    continuous_touches = 0
    for n in neighbors:
        match = next((i for i in range(0, len(tiles)) if tiles[i].x == n.x and tiles[i].y == n.y
                      and tiles[i].z == z), None)
        if match is not None:
            touches += 1
            continuous_touches += 1
            max_continuous_touches = max(max_continuous_touches, continuous_touches)
        else:
            continuous_touches = 0

    if touches == max_continuous_touches:
        return True
    else:
        return False
예제 #8
0
def can_slide_to(start, end: hexutil.Point, tiles: List[board.Tile], z):
    """Assumes start is next to end, remove start before calling
    can slide if end has 2 continuous spaces AND start is in one of those spaces"""
    # todo, add in z axis for match checking
    match = next((i for i in range(0, len(tiles)) if tiles[i].x == end.x and tiles[i].y == end.y
                  and tiles[i].z == z), None)
    # todo, needs to be removed if on top of hive
    # cant slide there if something is already there
    if match is not None:
        return False

    # if it is a layer up, it NEEDS to have something there to be able to crawl there
    if z != 0:
        match = next((i for i in range(0, len(tiles)) if tiles[i].x == end.x and tiles[i].y == end.y
                      and tiles[i].z == z - 1), None)
        if match is None:
            return False

    if direction_of_crawl(start, end, tiles) == 0 and z == 0:
        return False

    neighbors = hexutil.touching_hexagons(end)
    continuous_spaces = 0
    start_in_continuous = False
    for j in range(-1, len(neighbors)):
        n = neighbors[j]
        # todo, again add in z axis of start tiles
        match = next((i for i in range(0, len(tiles)) if tiles[i].x == n.x and tiles[i].y == n.y
                      and tiles[i].z == z), None)
        if match is not None:
            continuous_spaces = 0
            start_in_continuous = False
        else:
            continuous_spaces += 1
            if start == n:
                start_in_continuous = True
            if continuous_spaces >= 2 and start_in_continuous:
                return True
    return False