# Path: diplomacy/engine/digest.py
# def find_convoys(units, fleets):
#     """
#     Generates pairs consisting of a cluster of adjacent non-coastal
#     fleets, and the coastal territories that are reachable via convoy
#     from that cluster.  This is necessary to determine legal orders.
# 
#     """
#     fleets = [f for f in fleets if not has_land(f)]
#     index = {f: {f} for f in fleets}
# 
#     # Calculate the connected sets of fleets
#     for f1, f2 in combinations(fleets, 2):
#         # If this pair is not adjacent, ignore it
#         if f2 not in borders(f1):
#             continue
# 
#         # If the sets for each of these fleets are not already the same set,
#         # merge them and update the index
#         if index[f1] != index[f2]:
#             index[f1] |= index[f2]
#             index.update((x, index[f1]) for x in index[f2])
# 
#     groups = {frozenset(S) for S in index.values()}
# 
#     armies = {u['subregion'] for u in units if u['u_type'] == 'A'}
# 
#     convoyable = []
#     for gset in groups:
#         coasts = {
#             sr for f in gset
#             for b in borders(f)
#             for sr in territory_parts(get_territory(b))
#             if is_land(sr)
#         }
#         if coasts & armies:
#             convoyable.append((set(gset), coasts))
# 
#     return convoyable
# 
# def builds_available(units, owns):
#     builds = defaultdict(int)
#     builds.update(supplycenters(owns))
# 
#     for u in units:
#         builds[u['government']] -= 1
# 
#     return builds
# 
# Path: diplomacy/engine/utils.py
# def get_territory(sr_token):
# def territory_parts(t_token):
# def borders(sr_token):
# def unit_in(sr_token, units):
# def territory_display(t_token):
# def subregion_display(sr_token):
# def unit_display(sr_token):
# def power_token(p_str):
# def territory_token(t_str):
# def subregion_token(sr_tuple):
# def is_supply(sr_token):
# def is_land(sr_token):
# def is_sea(sr_token):
# def has_land(sr_token):
# def has_sea(sr_token):


from . import standard
from .digest import find_convoys, builds_available
from .utils import unit_in, get_territory, borders, territory_parts, has_land, is_fleet
        if u['u_type'] == 'F'
        and not has_land(u['subregion'])
    ]

    for fset, lset in find_convoys(units, fleets):
        if actor in fset:
            attackers = {
                u['subregion'] for u in units
                if u['u_type'] == 'A'
                and u['subregion'] in lset
            }
            return {a: {x: False for x in lset - {a}}
                    for a in attackers}
    return {}


def valid_build(actor, units, owns, season):
    if not season == 'FA':
        return {}

    owns_index = {o['territory']: o for o in owns}
    current_government = owns_index.get(get_territory(actor), {}).get('government')
    home_government, is_supply = '', False
    if get_territory(actor) in standard.starting_state:
        home_government, is_supply, _ = standard.starting_state[get_territory(actor)]

    # It has to be a supply center and the current government has to have builds available.
    if not (is_supply and builds_available(units, owns).get(current_government, 0) > 0):
        return {}
    # Only can build if the territory is currently unoccupied.

# Path: diplomacy/engine/digest.py
# def find_convoys(units, fleets):
#     """
#     Generates pairs consisting of a cluster of adjacent non-coastal
#     fleets, and the coastal territories that are reachable via convoy
#     from that cluster.  This is necessary to determine legal orders.
# 
#     """
#     fleets = [f for f in fleets if not has_land(f)]
#     index = {f: {f} for f in fleets}
# 
#     # Calculate the connected sets of fleets
#     for f1, f2 in combinations(fleets, 2):
#         # If this pair is not adjacent, ignore it
#         if f2 not in borders(f1):
#             continue
# 
#         # If the sets for each of these fleets are not already the same set,
#         # merge them and update the index
#         if index[f1] != index[f2]:
#             index[f1] |= index[f2]
#             index.update((x, index[f1]) for x in index[f2])
# 
#     groups = {frozenset(S) for S in index.values()}
# 
#     armies = {u['subregion'] for u in units if u['u_type'] == 'A'}
# 
#     convoyable = []
#     for gset in groups:
#         coasts = {
#             sr for f in gset
#             for b in borders(f)
#             for sr in territory_parts(get_territory(b))
#             if is_land(sr)
#         }
#         if coasts & armies:
#             convoyable.append((set(gset), coasts))
# 
#     return convoyable
# 
# def builds_available(units, owns):
#     builds = defaultdict(int)
#     builds.update(supplycenters(owns))
# 
#     for u in units:
#         builds[u['government']] -= 1
# 
#     return builds
# 
# Path: diplomacy/engine/utils.py
# def get_territory(sr_token):
# def territory_parts(t_token):
# def borders(sr_token):
# def unit_in(sr_token, units):
# def territory_display(t_token):
# def subregion_display(sr_token):
# def unit_display(sr_token):
# def power_token(p_str):
# def territory_token(t_str):
# def subregion_token(sr_tuple):
# def is_supply(sr_token):
# def is_land(sr_token):
# def is_sea(sr_token):
# def has_land(sr_token):
# def has_sea(sr_token):


# Path: diplomacy/engine/check.py
from . import standard
from .digest import find_convoys, builds_available
from .utils import unit_in, get_territory, borders, territory_parts, has_land, is_fleet

        if u['u_type'] == 'F'
        and not has_land(u['subregion'])
    ]

    for fset, lset in find_convoys(units, fleets):
        if actor in fset:
            attackers = {
                u['subregion'] for u in units
                if u['u_type'] == 'A'
                and u['subregion'] in lset
            }
            return {a: {x: False for x in lset - {a}}
                    for a in attackers}
    return {}


def valid_build(actor, units, owns, season):
    if not season == 'FA':
        return {}

    owns_index = {o['territory']: o for o in owns}
    current_government = owns_index.get(get_territory(actor), {}).get('government')
    home_government, is_supply = '', False
    if get_territory(actor) in standard.starting_state:
        home_government, is_supply, _ = standard.starting_state[get_territory(actor)]

    # It has to be a supply center and the current government has to have builds available.
    if not (is_supply and builds_available(units, owns).get(current_government, 0) > 0):
        return {}
    # Only can build if the territory is currently unoccupied.

    if any(get_territory(u['subregion']) == get_territory(actor) for u in units):