def set_phase_orders()

in fairdiplomacy/data/build_dataset.py [0:0]


def set_phase_orders(game, phase_orders):
    logging.getLogger("p").info("set_phase_orders start {}".format(game.phase))

    # map of loc -> (power, "A/F")
    unit_at_loc = {}
    for power, unit_list in game.get_state()["units"].items():
        for unit in unit_list:
            unit_type, loc = unit.split()
            unit_at_loc[loc] = (power, unit_type)
            unit_at_loc[loc.split("/")[0]] = (power, unit_type)

    orders_by_power = group_by(phase_orders, lambda tpo: tpo[1])
    for power, tpos in orders_by_power.items():

        # compile orders, adding in missing unit type info for supports/convoys/destroys
        orders = []
        for _, _, order in tpos:
            split = order.split()

            # fill in unit type for supports / convoys
            if split[2] in ("S", "C"):
                loc = split[3]
                _, unit_type = unit_at_loc[loc]
                split = split[:3] + [unit_type] + split[3:]

            # fill in unit type for destroys
            elif split[0] == "X":
                loc = split[1]
                _, unit_type = unit_at_loc[loc]
                split = [unit_type, loc, "D"]

            possible_orders = set(game.get_all_possible_orders()[split[1]])
            if " ".join(split) in possible_orders:
                orders.append(" ".join(split))
            else:
                # if order is not valid, try location coastal variants, since
                # some orders are coming out of the db without the proper
                # coast.
                variant_split = get_valid_coastal_variant(split, possible_orders)
                if variant_split is not None:
                    orders.append(" ".join(variant_split))
                else:
                    # if there are no valid coastal variants, check if this is
                    # a disband that has already been processed. This sometimes
                    # happens when a unit is dislodged and has nowhere to
                    # retreat -- there will be a disband in the db, but the
                    # Game object disbands it automatically.
                    if split[2] == "D" and unit_at_loc.get(split[1], (None, None))[0] != power:
                        logging.getLogger("p").warning(
                            'Skipping disband: {} "{}"'.format(power, order)
                        )
                    else:
                        error_msg = 'Bad order: {} "{}", possible_orders={}'.format(
                            power, order, possible_orders
                        )
                        logging.getLogger("p").error(error_msg)
                        err = ValueError(error_msg)
                        err.partial_game = game
                        raise err

        # ensure that each order is valid
        for order in orders:
            loc = order.split()[1]
            assert order in game.get_all_possible_orders()[loc], (
                game.phase,
                (power, loc, order),
                game.get_all_possible_orders()[loc],
            )

        logging.getLogger("p").info('set_phase_orders -> {} "{}"'.format(power, orders))
        game.set_orders(power, orders)