def simple_dijkstra(board: HexBoard, source, is_max):

    Q = set()
    V_set = board.get_all_vertices()
    dist = {}
    dist_clone = {}  # I made a clone of dist to retain the information in dist
    prev = {}
    for v in V_set:
        dist[v] = np.inf
        dist_clone[v] = np.inf  # clone
        prev[v] = None
        Q.add(v)
    dist[source] = 0
    dist_clone[source] = dist[source]  # clone

    while len(Q) != 0:
        u = min(dist, key=dist.get)
        Q.remove(u)

        color = board.BLUE if is_max else board.RED

        ## IGNORE THE CODE BELOW, IT DOESN'T WORK PROPERLY AT THE MOMENT
        # begin reverse iteration step
        # this happens when we get to a border of the corresponding color (i.e. we connect the sides)
        # if board.border(color, u):
        #     S = []
        #     path_length = 0
        #     if prev[u] or u == source:
        #         while u:
        #             if not board.is_color(u, color):
        #                 path_length += 1
        #             S.insert(0, u)
        #             u = prev[u]
        #     print(f"S for color {color} IS: {S}")
        #     print(f"Path length when accounting for already marked hexagons: {path_length}")
        #     return path_length, S # You can also optionally return "S" if you also want to store the path
        # # end reverse iteration step

        neighbors = board.get_neighbors(u)

        for v in neighbors:
            if v in Q:  # Only check neighbours that are also in "Q"
                len_u_v = 0 if board.is_color(
                    v,
                    color) else 1  # this isn't working as intended i think...
                alt = dist[u] + len_u_v
                if alt < dist[v]:
                    dist[v] = alt
                    dist_clone[v] = dist[v]
                    prev[v] = u
        # We pop "u" from the distance dict to ensure that the keys match the ones in "Q"
        dist.pop(
            u
        )  # This is also why we need the clone, or else we'll return an empty dict

    return dist_clone, prev
def simple_dijkstra(board: HexBoard, source, is_max):

    Q = set()
    V_set = board.get_all_vertices()
    dist = {}
    dist_clone = {}  # I made a clone of dist to retain the information in dist
    prev = {}
    for v in V_set:
        dist[v] = np.inf
        dist_clone[v] = np.inf  # clone
        prev[v] = None
        Q.add(v)
    dist[source] = 0
    dist_clone[source] = dist[source]  # clone

    while len(Q) != 0:
        u = min(dist, key=dist.get)
        Q.remove(u)

        color = board.BLUE if is_max else board.RED

        neighbors = board.get_neighbors(u)

        for v in neighbors:
            if v in Q:  # Only check neighbours that are also in "Q"
                len_u_v = -1 if board.is_color(
                    v,
                    color) else 1  # this isn't working as intended i think...
                ### BLOCK TO MAKE AI MORE AGGRESSIVE ###
                if board.border(
                        color, v
                ):  # If there is a move that reaches the border in the simulation
                    if board.check_win(color):  # And it results in a win
                        len_u_v = -2  # Make that move more valuable
                ### END OF AGGRO BLOCK ###
                alt = dist[u] + len_u_v
                if alt < dist[v]:
                    dist[v] = alt
                    dist_clone[v] = dist[v]
                    prev[v] = u
        # We pop "u" from the distance dict to ensure that the keys match the ones in "Q"
        dist.pop(
            u
        )  # This is also why we need the clone, or else we'll return an empty dict

    return dist_clone, prev