Example #1
0
def create_bot_summary(ld: LeagueDir):
    """
    Create a json file with all information about the bots. Useful for casters.
    """

    bots = load_all_bots(ld)
    rankings = RankingSystem.load(ld).ensure_all(list(bots.keys()))
    rank_list = rankings.as_sorted_list()

    def bot_data(bot_id):
        config = bots[bot_id]
        rank, mmr = [(i + 1, mrr)
                     for i, (id, mrr, sigma) in enumerate(rank_list)
                     if id == bot_id][0]
        return {
            "name": config.name,
            "developer": config.base_agent_config.get("Details", "developer"),
            "description":
            config.base_agent_config.get("Details", "description"),
            "fun_fact": config.base_agent_config.get("Details", "fun_fact"),
            "github": config.base_agent_config.get("Details", "github"),
            "language": config.base_agent_config.get("Details", "language"),
            "rank": rank,
            "mmr": mmr,
        }

    bot_summary = {
        defmt_bot_name(bot_id): bot_data(bot_id)
        for bot_id in bots.keys()
    }

    with open(ld.bot_summary, 'w') as f:
        json.dump(bot_summary, f, indent=4)
Example #2
0
def make_overlay(ld: LeagueDir, match: MatchDetails, bots: Mapping[BotID, BotConfigBundle]):
    """
    Make a `current_match.json` file which contains the details about the current
    match and its participants.
    """

    retired = load_retired_bots(ld)
    rankings = RankingSystem.load(ld).ensure_all(list(bots.keys()))
    rank_list = rankings.as_sorted_list(exclude=retired)

    def bot_data(bot_id):
        config = bots[bot_id]
        rank, mmr = [(i + 1, mrr) for i, (id, mrr, sigma) in enumerate(rank_list) if id == bot_id][0]
        return {
            "name": config.name,
            "config_path": str(config.config_path),
            "logo_path": try_copy_logo(config),
            "developer": config.base_agent_config.get("Details", "developer"),
            "description": config.base_agent_config.get("Details", "description"),
            "fun_fact": config.base_agent_config.get("Details", "fun_fact"),
            "github": config.base_agent_config.get("Details", "github"),
            "language": config.base_agent_config.get("Details", "language"),
            "rank": rank,
            "mmr": mmr,
        }

    overlay = {
        "blue": [bot_data(bot_id) for bot_id in match.blue],
        "orange": [bot_data(bot_id) for bot_id in match.orange],
        "map": match.map
    }

    with open(PackageFiles.overlay_current_match, 'w') as f:
        json.dump(overlay, f, indent=4)
Example #3
0
def parse_subcommand_rank(args: List[str]):
    assert args[0] == "rank"
    help_msg = """Usage:
        autoleague rank list                Print list of the current leaderboard"""

    ld = require_league_dir()

    if len(args) == 1 or args[1] == "help":
        print(help_msg)

    elif args[1] == "list" and len(args) == 2:

        bots = load_all_bots(ld)

        rank_sys = RankingSystem.load(ld)
        rank_sys.ensure_all(list(bots.keys()))
        rank_sys.print_ranks_and_mmr()

    else:
        print(help_msg)
Example #4
0
def parse_subcommand_rank(args: List[str]):
    assert args[0] == "rank"
    help_msg = """Usage:
        autoleague rank list [showRetired]  Print list of the current leaderboard"""

    ld = require_league_dir()

    if len(args) == 1 or args[1] == "help":
        print(help_msg)

    elif args[1] == "list" and (len(args) == 2 or len(args) == 3):

        show_retired = len(args) == 3 and bool(args[2])
        exclude = [] if show_retired else load_retired_bots(ld)

        bots = load_all_bots(ld)

        rank_sys = RankingSystem.load(ld)
        rank_sys.ensure_all(list(bots.keys()))
        rank_sys.print_ranks_and_mmr(exclude)

    else:
        print(help_msg)
Example #5
0
def make_summary(ld: LeagueDir, count: int):
    """
    Make a summary of the N latest matches and the resulting ranks and tickets.
    If N is 0 the summary will just contain the current ratings.
    """
    summary = {}

    tickets = TicketSystem.load(ld)

    # ========== Matches ==========

    matches = []
    bot_wins = defaultdict(list)  # Maps bots to list of booleans, where true=win and false=loss

    if count > 0:
        latest_matches = MatchDetails.latest(ld, count)
        for i, match in enumerate(latest_matches):
            matches.append({
                "index": i,
                "blue_names": [defmt_bot_name(bot_id) for bot_id in match.blue],
                "orange_names": [defmt_bot_name(bot_id) for bot_id in match.orange],
                "blue_goals": match.result.blue_goals,
                "orange_goals": match.result.orange_goals,
            })
            for bot in match.blue:
                bot_wins[bot].append(match.result.blue_goals > match.result.orange_goals)
            for bot in match.orange:
                bot_wins[bot].append(match.result.blue_goals < match.result.orange_goals)

    summary["matches"] = matches

    # ========= Ranks/Ratings =========

    bots = load_all_unretired_bots(ld)
    retired = load_retired_bots(ld)
    bots_by_rank = []

    if count <= 0:
        # Old rankings and current rankings is the same, but make sure all bots have a rank currently
        old_rankings = RankingSystem.load(ld).as_sorted_list(exclude=retired)
        cur_rankings = RankingSystem.load(ld).ensure_all(list(bots.keys())).as_sorted_list(exclude=retired)
    else:
        # Determine current rank and their to N matches ago
        n_rankings = RankingSystem.latest(ld, count + 1)
        old_rankings = n_rankings[0].as_sorted_list(exclude=retired)
        cur_rankings = n_rankings[-1].ensure_all(list(bots.keys())).as_sorted_list(exclude=retired)

    for i, (bot, mrr, sigma) in enumerate(cur_rankings):
        cur_rank = i + 1
        old_rank = None
        old_mmr = None
        for j, (other_bot, other_mrr, _) in enumerate(old_rankings):
            if bot == other_bot:
                old_rank = j + 1
                old_mmr = other_mrr
                break
        bots_by_rank.append({
            "bot_id": defmt_bot_name(bot),
            "mmr": mrr,
            "old_mmr": old_mmr,
            "sigma": sigma,
            "cur_rank": cur_rank,
            "old_rank": old_rank,
            "tickets": tickets.get(bot) or tickets.new_bot_ticket_count,
            "wins": bot_wins[bot],
        })

    summary["bots_by_rank"] = bots_by_rank

    # =========== Write =============

    with open(PackageFiles.overlay_summary, 'w') as f:
        json.dump(summary, f, indent=4)

    league_settings = LeagueSettings.load(ld)
    league_settings.last_summary = count
    league_settings.save(ld)
Example #6
0
def parse_subcommand_bot(args: List[str]):
    assert args[0] == "bot"
    help_msg = """Usage:
    autoleague bot list                       Print list of all known bots
    autoleague bot test <bot_id>              Run test match using a specific bot
    autoleague bot details <bot_id>           Print details about the given bot
    autoleague bot unzip                      Unzip all bots in the bot directory
    autoleague bot summary                    Create json file with bot descriptions"""

    ld = require_league_dir()

    if len(args) == 1 or args[1] == "help":
        print(help_msg)

    elif args[1] == "list" and len(args) == 2:

        bot_configs = load_all_bots(ld)
        rank_sys = RankingSystem.load(ld)
        ticket_sys = TicketSystem.load(ld)

        bot_ids = list(
            set(bot_configs.keys()).union(set(rank_sys.ratings.keys())).union(
                set(ticket_sys.tickets.keys())))

        print(f"{'': <22} c r t")
        for bot in sorted(bot_ids):
            c = "x" if bot in bot_configs else " "
            r = "x" if bot in rank_sys.ratings else " "
            t = "x" if bot in ticket_sys.tickets else " "
            print(f"{bot + ' ':.<22} {c} {r} {t}")

    elif args[1] == "test" and len(args) == 3:

        # Load
        bots = load_all_bots(ld)
        bot = args[2]
        if bot not in bots:
            print(f"Could not find the config file of '{bot}'")
            return

        # Run
        match = MatchMaker.make_test_match(bot)
        run_match(ld, match, bots, ReplayPreference.NONE)
        print(f"Test of '{bot}' complete")

    elif args[1] == "details" and len(args) == 3:

        bots = load_all_bots(ld)
        bot = args[2]

        if bot not in bots:
            print(f"Could not find the config file of '{bot}'")
            return

        print_details(bots[bot])

    elif args[1] == "unzip" and len(args) == 2:

        print("Unzipping all bots:")
        unzip_all_bots(ld)

    elif args[1] == "summary" and len(args) == 2:

        create_bot_summary(ld)
        print("Bot summary created")

    else:
        print(help_msg)
Example #7
0
def parse_subcommand_match(args: List[str]):
    assert args[0] == "match"
    help_msg = """Usage:
    autoleague match run                        Run a standard 3v3 soccer match
    autoleague match undo                       Undo the last match
    autoleague match list [n]                   Show the latest matches"""

    ld = require_league_dir()

    if len(args) == 1 or args[1] == "help":
        print(help_msg)

    elif args[1] == "run" and len(args) == 2:

        # Load
        bots = load_all_bots(ld)
        rank_sys = RankingSystem.load(ld)
        ticket_sys = TicketSystem.load(ld)

        # Run
        match = MatchMaker.make_next(bots, rank_sys, ticket_sys)
        result, replay = run_match(ld, match, bots, ReplayPreference.SAVE)
        rank_sys.update(match, result)
        match.result = result
        match.replay_id = replay.replay_id

        # Save
        match.save(ld)
        rank_sys.save(ld, match.time_stamp)
        ticket_sys.save(ld, match.time_stamp)

        # Print new ranks
        rank_sys.print_ranks_and_mmr()

        # Make summary
        league_settings = LeagueSettings.load(ld)
        make_summary(ld, league_settings.last_summary + 1)
        print(
            f"Created summary of the last {league_settings.last_summary + 1} matches."
        )

    elif args[1] == "undo" and len(args) == 2:

        # Undo latest match
        ld = require_league_dir()
        latest_matches = MatchDetails.latest(ld, 1)
        if len(latest_matches) == 0:
            print("No matches to undo")
        else:
            latest_match = latest_matches[0]

            # Prompt user
            print(f"Latest match was {latest_match.name}")
            if prompt_yes_no(
                    "Are you sure you want to undo the latest match?"):

                # Undo latest update to all systems
                RankingSystem.undo(ld)
                TicketSystem.undo(ld)
                MatchDetails.undo(ld)

                # New latest match
                new_latest_match = MatchDetails.latest(ld, 1)
                if new_latest_match:
                    print(f"Reverted to {new_latest_match[0].name}")
                else:
                    print("Reverted to beginning of league (no matches left)")

    elif args[1] == "list" and len(args) <= 3:

        count = 999999
        if len(args) == 3:
            count = int(args[2])

        # Show list of latest n matches played
        latest_matches = MatchDetails.latest(ld, count)
        if len(latest_matches) == 0:
            print("No matches have been played yet.")
        else:
            print(f"Match history (latest {len(latest_matches)} matches):")
            for match in latest_matches:
                print(
                    f"{match.time_stamp}: {', '.join(match.blue) + ' ':.<46} {match.result.blue_goals} VS {match.result.orange_goals} {' ' + ', '.join(match.orange):.>46}"
                )

    else:
        print(help_msg)
Example #8
0
def parse_subcommand_retirement(args: List[str]):
    assert args[0] == "retirement"
    help_msg = """Usage:
        autoleague retirement list                  Print all bots in retirement
        autoleague retirement retire <bot>          Retire a bot, removing it from play and the leaderboard
        autoleague retirement unretire <bot>        Unretire a bot
        autoleague retirement retireall             Retire all bots"""

    ld = require_league_dir()

    if len(args) == 1 or args[1] == "help":
        print(help_msg)

    elif args[1] == "list" and len(args) == 2:

        retired = load_retired_bots(ld)

        if len(retired) == 0:
            print("There are no bots in retirement")
        else:
            print("Retired bots:")
            for bot_id in sorted(retired):
                print(bot_id)

    elif args[1] == "retire" and len(args) == 3:

        bot = args[2]
        retired = load_retired_bots(ld)

        retired.add(bot)
        save_retired_bots(ld, retired)

        print(f"Retired {bot}")

    elif args[1] == "unretire" and len(args) == 3:

        bot = args[2]
        retired = load_retired_bots(ld)

        try:
            retired.remove(bot)
            save_retired_bots(ld, retired)
            print(f"Unretired {bot}")
        except KeyError:
            print(f"The bot {bot} is not in retirement")

    elif args[1] == "retireall" and len(args) == 2:

        bot_configs = load_all_bots(ld)
        rank_sys = RankingSystem.load(ld)
        ticket_sys = TicketSystem.load(ld)
        retired = load_retired_bots(ld)

        all_bots = set(
            bot_configs.keys()).union(set(rank_sys.ratings.keys())).union(
                set(ticket_sys.tickets.keys())).union(retired)

        save_retired_bots(ld, all_bots)

        count = len(all_bots) - len(retired)
        print(f"Retired {count} bots")

    else:
        print(help_msg)