def make_capital_county(c_size=5, origin=Cube(), coastal=True, rgb=None):
    '''Makes a county where all provinces neighbor the central province.'''
    rgb = rgb or c_col()
    a = Tile(origin=origin, rgb=rgb)
    cube_list = list(Cube(0, 0, 0).neighbors())
    if coastal and c_size < 7:
        a.water_list.append(cube_list[c_size - 1])
    cube_list = cube_list[:c_size - 1]
    for el in cube_list:
        a.add_hex(el)
    return a
def make_island_kingdom(water_height,
                        origin=None,
                        size_list=[6, 4, 4, 3],
                        banned=[],
                        weighted=True,
                        min_mag=6,
                        min_capital_coast=3,
                        min_coast=2,
                        max_tries=1000,
                        strait_prob=0.5,
                        center_bias=0.5,
                        coast_bias=0.125):
    '''Given a dictionary from cubes to distance from shore, return a tile with duchies whose size are from duchy_size_list,
    and which are connected either directly or by straits (with probability strait_prob), and doesn't have any hexes in banned.
    The probability that a hex is selected as the origin is proportional to np.exp(-el.mag() * center_bias) * np.exp(water_height[el] * coast_bias),
    so high values of center_bias will make it closer to the center and high values of coast_bias will make it further from the shore.
    Tries max_tries times and returns False if it fails.'''
    assert min_capital_coast >= 3
    assert min_coast >= 2
    for _ in range(max_tries):
        island = Tile(hex_list=[],
                      tile_list=[make_capital_duchy(d_size=size_list[0])])
        if origin:
            island.tile_list[0].origin = origin
        else:
            opts = [
                k for k, v in water_height.items()
                if v >= min_capital_coast and k.mag() >= min_mag
            ]  #center-coast-water-land means center has to be at least 3.
            probs = [
                np.exp(-el.mag() * center_bias) *
                np.exp(water_height[el] * coast_bias) for el in opts
            ]
            probs /= sum(probs)
            island.tile_list[0].origin = np.random.choice(opts, p=probs)
        allowable = [
            k for k, v in water_height.items()
            if v >= min_coast and k not in banned
        ]
        if any([el not in allowable for el in island.real_hex_list()]):
            break
        for size in size_list[1:]:
            allocated = island.real_total_list()
            land_nbrs = island.neighbors()
            allowable = [el for el in allowable if el not in allocated]
            if np.random.rand() <= strait_prob:
                opts = [
                    el for el in island.strait_neighbors() if el in allowable
                ]
                new_origin = random.choice(opts)
                water_hexes = set()
                new_origin_nbrs = new_origin.neighbors()
                land = island.real_hex_list()
                for strait_neighbor in new_origin.strait_neighbors():
                    if strait_neighbor in land:
                        water_hexes.update([
                            el for el in strait_neighbor.neighbors()
                            if el in new_origin_nbrs
                        ])
                new_tile = Tile(hex_list=[new_origin],
                                water_list=list(water_hexes))
                while len(new_tile.hex_list) < size:
                    new_neighbors = new_tile.relative_neighbors(weighted)
                    new_neighbors = [
                        x for x in new_neighbors
                        if x not in land_nbrs and x in allowable
                    ]
                    if len(new_neighbors) > 0:
                        new_tile.add_hex(random.choice(new_neighbors))
                    else:
                        break
                if len(new_tile.hex_list) == size:
                    island.add_tile(new_tile)
            else:
                opts = [el for el in island.neighbors() if el in allowable]
                new_origin = random.choice(opts)
                new_tile = Tile(hex_list=[new_origin])
                while len(new_tile.hex_list) < size:
                    new_neighbors = new_tile.relative_neighbors(weighted)
                    new_neighbors = [
                        x for x in new_neighbors
                        if x not in allocated and x in allowable
                    ]
                    if len(new_neighbors) > 0:
                        new_tile.add_hex(random.choice(new_neighbors))
                    else:
                        break
                if len(new_tile.hex_list) == size:
                    island.add_tile(new_tile)
        if len(island.real_hex_list()) == sum(
                size_list) and check_water_access(
                    island.real_hex_list(), island.real_water_list(),
                    max([el.mag() for el in island.real_hex_list()])):
            return island
    return False