def execute(self, *args, **kwargs): if 'delete' in kwargs and kwargs['delete']: self.clean_database() max = -1 if 'max' in kwargs: max = kwargs['max'] replay_paths = self.get_replay_paths() count = 0 total = len(replay_paths) for replay in sc2reader.load_replays( replay_paths ): if max > 0: if count == max: break count += 1 print 'Importing replay %d/%d' % (count, total if max < 0 else max) try: self.import_replay( replay ) except Exception as e: print '%s: %s' % (type(e), e) print self.import_count
def __init__(self, username, path): """ The processed replays object represents the collection of replays loaded by the user, and the processed data associated with it. self.apm is a dictionary keyed by date (yyyy-mm-dd hh:mm:ss) containing the average APM on that datetime Self.wr is a dictionary ordered by the race played by the active player, then subdictionaries of the race played by the opponent, which each have a two-item list: wins and total games. (This is not a tuple because tuples are immutable) >>> p = ProcessedReplays('bonywonix', 'replays/') >>> p.me 'bonywonix' >>> type(p.replays) is list True >>> type(p.wr) is dict True >>> p.replays[0].real_type != '1v1' False """ self.me = username self.apm = {} self.wr = {'Zerg': {'Zerg': [0,0], 'Protoss': [0,0], 'Terran': [0,0]}, 'Protoss': {'Zerg': [0, 0], 'Protoss': [0, 0], 'Terran': [0, 0]}, 'Terran': {'Zerg': [0,0], 'Protoss': [0,0], 'Terran': [0,0]} } self.processedWR = False self.replays = list() for replay in sc2reader.load_replays(path): if replay.real_type == '1v1': self.replays.append(replay)
def main(): dir_filepath = 'replay_files/' # filepath to directory where all of the files are output_filepath = 'output.csv' # filepath to output csv file replay_generator = sc2reader.load_replays( sc2reader.utils.get_files( path=dir_filepath, # look in this directory depth=-1, # infinite depth extension='SC2Replay' # get all files with this extension ), load_level=4 # load with this level of detail ) # assumes that there is at least one replay replay = next(replay_generator) replayObj_to_csv(replay, output_filepath, False) # overwrite for the first replay. for r in replay_generator: replayObj_to_csv(r, output_filepath, True) # append for all other replays return
def main(): args = get_args() # TODO: Find out why the debug option must be here. for replay in sc2reader.load_replays(args.FILE, options={"load_map":args.map, "debug":True}): print "Release {0}".format(replay.release_string) if args.map: print "{0} on {1}".format(replay.type, replay.map.name) else: print replay.type for player in replay.players: print player print "\n--------------------------\n\n" # Allow picking of the player to 'watch' if args.player: events = replay.player[args.player].events else: events = replay.events # Loop through the events #data = sc2reader.data.create_build(replay.build) for event in events: try: event.apply(data) except ValueError as e: if str(e) == "Using invalid abilitiy matchup.": myGetch() else: raise e except Exception as e: pass # Use their options to filter the event stream if isinstance(event,AbilityEvent) or\ isinstance(event,SelectionEvent) or\ isinstance(event,PlayerJoinEvent) or\ isinstance(event, PlayerLeaveEvent) or\ isinstance(event,GameStartEvent) or\ (args.hotkeys and isinstance(event,HotkeyEvent)) or\ (args.cameras and isinstance(event,CameraEvent)): if args.frame: print "{:>6} {}".format(event.frame, event) else: print event if isinstance(event, SelectionEvent): print event.bank print event.objects if args.step: if myGetch() == 'q': print "Quitting..." break if args.bytes: print "\t"+event.bytes.encode('hex') if re.search('UNKNOWN|ERROR', str(event)): myGetch()
def parse_matchup(directory, tags, meta_options): replays = sc2reader.load_replays(directory, depth=0) best_of = meta_options['best_of'] if 'best_of' in meta_options else 3 games = [] match = resources.Matchup(list(tags), best_of) for replay in replays: games.append(parse_game(replay)) match.set_games(games, meta_options) return match
def main(): dir = '../../../data/' rgen = sc2reader.load_replays(sc2reader.utils.get_files( path=dir, depth=-1, extension='SC2Replay'), load_level=4) dic = {} id = 0 for replay in rgen: dic[str(id)] = parseReplay(replay) id += 1 with open('output.json', 'w') as outfile: json.dump(dic, outfile)
def sc2Script(input_path): # Allow this script to take a filepath, and per match stats as an input print(input_path ) # This input_path should be populated - if not, there's a bug match_replays = os.listdir(input_path) full_paths = [] f = open('sc2.txt', 'w') # Build a list of full filepaths to replays for item in match_replays: full_paths.append(os.path.join(input_path, item)) replays = sc2reader.load_replays(full_paths, load_level=4) length_sum = 0 # Iterate through the replay files using date,time,length,and team methods # Enumerated replays for indexing for the file_counter # Using try except to avoid corrupt/<4 byte files breaking script for i, replayfile in enumerate(replays): try: replay_length = replayfile.length.seconds replay_map = replayfile.map_name replay_date = replayfile.date replay_teams = replayfile.teams length_sum += replay_length file_counter = i + 1 # f.write results to console if -a if listall: f.write("MAP: {0}".format(replay_map)) f.write("LENGTH: {0}".format(replay_length)) f.write("TEAMS: {0}".format(replay_teams)) f.write("DATE: {0}".format(replay_date)) f.write("-----------------------------------------") else: continue except Exception as e: f.write("Exception occurred at {0}".format(e)) f.write( "========================================================================" ) average_length = length_sum / file_counter f.write("AVERAGE GAME TIME: {0} Minutes".format( round(average_length / 60, 0)))
def main(): dir = 'replays/' rgen = sc2reader.load_replays( sc2reader.utils.get_files( path=dir, depth=-1, extension='SC2Replay' ), load_level=4 ) dic = {} id = 0 for replay in rgen: dic[str(id)] = parseReplay(replay) id += 1 print(json.dumps(dic))
def load_replays(self, glob_path, limit=None, verbose=True): ''' Loads SC2 replays found in the provided path. If the argument 'amount' is passed, then only that amount will be loaded. Parameters ---------- glob_path : str Path to .SC2Replay files as a glob string limit : int, optional Number of replays to be loaded (default is All) verbose : bool, optional Show verbose information (default is True) Returns ------- None ''' paths = [path for path in glob(glob_path, recursive=True)] loader_amount = len( paths) if limit is None or limit > len(paths) else limit n_replays = len(paths) register_plugin(APMTracker()) register_plugin(SelectionTracker()) register_plugin(ContextLoader()) replays = load_replays(paths[:limit]) if verbose: print('Loaded {} replays out of {}.'.format( loader_amount, n_replays)) self.paths = paths[:limit] self.replays = replays self.n_replays = n_replays self.loader_amount = loader_amount
def do_stuff(args): replays = sc2reader.load_replays(args.FILES, options={"load_map": True, "debug": True}) data = {} for replay in replays: log("New replay") terrans = [{"player": p, "selected": None, "scans": []} for p in replay.players if p.play_race == "Terran"] zergs = [{"player": p, "selected": None} for p in replay.players if p.play_race == "Zerg"] for event in replay.events: if args.seconds != 0 and event.time.total_seconds() > args.seconds: break for t in terrans: if t["player"].pid != event.pid: continue if isinstance(event, SelectionEvent): t["selected"] = event.objects elif isinstance(event, LocationAbilityEvent): if event.ability_name == "CalldownScannerSweep": log(event) log(event.location) t["scans"].append((event.frame,) + event.location) if not replay.map_hash in data: data[replay.map_hash] = { "map": replay.map.name, "minimap": replay.map.minimap, "bounds": load_bounds(replay.map.archive), "zerg": [], "terran": [], } log("Map added") log(data[replay.map_hash]["bounds"]) for t in terrans: data[replay.map_hash]["terran"].extend(t["scans"]) return data
#path = "C:/Users/iplea/Desktop/HSC19" #os.chdir(path) unit_data = json.loads(data.unit_data) unit_map = {} df = [] Matchup = [] map_list=[] map_frequency=[] for replay in sc2reader.load_replays(glob.glob('C:/Users/iplea/Desktop/Replays/**/*.SC2Replay', recursive=True)): if counter > 10: break if replay.map_hash not in map_list: map_list.append(replay.map_hash) mapnumb = map_list.index(replay.map_hash) Matchup.append([counter, replay.game_length, replay.players[0].result, replay.players[1].result, replay.players[0].pick_race[0], replay.players[1].pick_race[1], mapnumb, len(map_frequency)]) map_frequency.append(mapnumb) counts = Counter(map_frequency) counts.most_common() counter += 1
def load_1v1_ranked(paths, my_name, analyze_units=True): # TODO maybe just use load_players or something else to just get the data i # want, rather than load_level=2, which also loads other stuff # (though idk if any of other stuff totals to significant time loading...) # Technically possible to load all at load_level=1 first and check # .type == '1v1', but 1) most of my games are 1v1 anyway and # 2) loading all at load_level=1 or load_level=2 seems to take about the # same amount of time, so unlikely that any such strategy would help much, # as far as total load time is concerned. if analyze_units: load_level = 3 else: load_level = 2 before = time.time() print(f'Loading {len(paths)} replays at load_level={load_level} ...') replays = sc2reader.load_replays(paths, load_level=load_level) shortcircuit = True n_with_computers = 0 n_ladder = 0 n_1v1 = 0 n_competitive = 0 # If the value for a key is `None` here, the variable is assumed to be # accessible as an attribute of the replay object. game_vars2getters = { 'filename': None, 'start_time': None, # TODO matter whether i use this .real_length over just .length? 'duration_s': lambda r: r.real_length.total_seconds(), 'map_name': None, # The list of players indexed here is the winning team, which should # always just have one person given the restrictions earlier in this # function. # TODO elsewhere assert name is unique in 1v1 'won': lambda r: r.winner.players[0] == my_name, 'expansion': None, # TODO could also get maybe build / base_build, though not sure if they # map to the balance patches i might care about or how to do that # mapping } # TODO TODO get variable representing the season my_prefix = 'my_' opponent_prefix = 'opponent_' # If the value for a key is `None` here, the variable is assumed to be # accessible as an attribute of the player (`sc2reader.objects.Participant`) # object. my_vars2getters = { 'pick_race': None, 'play_race': None, # this is just to see if variation in this for my opponents is maybe # just b/c the mapping changed and thus my subregion also changed 'subregion': None, # MMR before match. Not sure if "scaled" actually has any meaning here. 'scaled_rating': lambda p: p.init_data['scaled_rating'], } opponent_vars2getters = { 'pick_race': None, 'play_race': None, 'name': None, 'clan_tag': None, # TODO get which sub league they are in? that vary, or do i always play # people within mine? # TODO does subregion actually vary for my opponents? drop if not. 'subregion': None, # TODO are other IDs (like battle tag) avaible directly from replay? # Can be used to generate URL to their BNet profile # (directly accessible w/ player.url) 'bnet_uid': lambda o: o.detail_data['bnet']['uid'], 'highest_league': lambda p: highest_league_num2str[ getattr(p, 'highest_league') ], 'scaled_rating': lambda p: p.init_data['scaled_rating'], # Chat will be handled separately. } # Has one key for each in the three dicts above (though player variables # will be prefixed), and the values for each should be same-length lists # of length equal to the number of replays analyzed. var2value_lists = {v: [] for v in ( list(game_vars2getters.keys()) + [my_prefix + k for k in my_vars2getters.keys()] + [opponent_prefix + k for k in opponent_vars2getters.keys()] + [p + 'chat' for p in (my_prefix, opponent_prefix)] )} if analyze_units: var2value_lists[my_prefix + 'mode_army_unit'] = [] var2value_lists[opponent_prefix + 'mode_army_unit'] = [] var2value_lists[my_prefix + 'army_summary'] = [] var2value_lists[opponent_prefix + 'army_summary'] = [] # TODO need to separately filter out custom 1v1 games against humans, # or do is_ladder / competitive already effectively filter that? # (look at whats get filtered and check for my recent games w/ brian for # instance...) for replay in tqdm(replays, total=len(paths)): if len(replay.computers) > 0: n_with_computers += 1 if shortcircuit: continue # TODO seems ladder might already only select 1v1s? if not replay.is_ladder: if shortcircuit: continue else: assert replay.competitive n_ladder += 1 # TODO players include AI? (if not, this might catch non-1v1 games...) if len(replay.players) != 2: if shortcircuit: continue else: assert replay.type == '1v1' n_1v1 += 1 # TODO i have definitely played *some* 1v1 unranked games, so it seems # this must be True in those cases as well... assert replay.competitive n_competitive += 1 # TODO why is this always None? what is this for? # TODO check it when fully loaded assert replay.ranked is None assert replay.players[0].name != replay.players[1].name if replay.players[0].name == my_name: my_idx = 0 opponent_idx = 1 elif replay.players[1].name == my_name: my_idx = 1 opponent_idx = 0 else: raise ValueError('no player with name matching my_name={my_name}') me = replay.players[my_idx] opponent = replay.players[opponent_idx] for var, getter in game_vars2getters.items(): if getter is None: value = getattr(replay, var) else: value = getter(replay) var2value_lists[var].append(value) for var, getter in my_vars2getters.items(): if getter is None: value = getattr(me, var) else: value = getter(me) var2value_lists[my_prefix + var].append(value) for var, getter in opponent_vars2getters.items(): if getter is None: value = getattr(opponent, var) else: value = getter(opponent) var2value_lists[opponent_prefix + var].append(value) # Handling chat separately cause it's not most easily accessible as a fn # of the player objects it seems. my_chat = [] their_chat = [] for m in replay.messages: if not m.to_all: continue # might want to also store m.frame to re-order later # (if i want that) if m.player.name == my_name: my_chat.append(m.text) else: assert m.player.name == opponent.name their_chat.append(m.text) var2value_lists[my_prefix + 'chat'].append(my_chat) var2value_lists[opponent_prefix + 'chat'].append(their_chat) if analyze_units: opponent_army_units = real_army_units(opponent.units) opponent_mode_army_unit = most_common_army_unit(opponent_army_units) opponent_army_summary = army_summary_str(opponent_army_units) var2value_lists[opponent_prefix + 'mode_army_unit'].append( opponent_mode_army_unit ) var2value_lists[opponent_prefix + 'army_summary'].append( opponent_army_summary ) my_army_units = real_army_units(me.units) my_mode_army_unit = most_common_army_unit(my_army_units) my_army_summary = army_summary_str(my_army_units) var2value_lists[my_prefix + 'mode_army_unit'].append( my_mode_army_unit ) var2value_lists[my_prefix + 'army_summary'].append(my_army_summary) ''' print('n_1v1:', n_1v1) print('n_with_computers:', n_with_computers) print('n_ladder:', n_ladder) print('n_competitive:', n_competitive) ''' # TODO why does even load_level=4 seem to not correctly specify # replay.ranked? need to do some other init? is that the flag i want? # TODO how does .ranked differ from .competitive? # TODO compare what i can get out of 3 vs 4. ''' for path in tqdm(paths_to_fully_load, total=len(paths_to_fully_load)): r3 = sc2reader.load_replay(path, load_level=3) r4 = sc2reader.load_replay(path, load_level=4) # player.units something i want here? import ipdb; ipdb.set_trace() ''' # TODO TODO would it take too much memory to store full load_level 3/4 # replay objects to each? store some more compact repr of build orders # in a column too? ''' load_level = 4 print(f'Loading {len(paths)} replays at load_level={load_level} ...') l4_replays = sc2reader.load_replays(paths, load_level=load_level) ''' # TODO TODO maybe derive columns for whether i used hotkeys for various # things (particularly (all/most of) my bases) total_s = time.time() - before print(f'Loading took {total_s:.0f}s') df = pd.DataFrame(var2value_lists) n_replays_before = len(df) df.drop_duplicates(subset=['start_time'], inplace=True) n_dropped = n_replays_before - len(df) if n_dropped > 0: print(f'Dropped {n_dropped} replays with duplicate start_time') df.set_index('start_time', inplace=True) df.sort_index(inplace=True) return df
help="Full Filepath to the starcraft replays") parser.add_argument("-a", action="count", help="Select if you want match specific data per replay") args = parser.parse_args() match_replays = os.listdir(args.path) listall = args.a full_paths = [] # Build a list of full filepaths to replays for item in match_replays: full_paths.append(os.path.join(args.path, item)) replays = sc2reader.load_replays(full_paths, load_level=4) length_sum = 0 # Iterate through the replay files using date,time,length,and team methods # Enumerated replays for indexing for the file_counter # Using try except to avoid corrupt/<4 byte files breaking script for i, replayfile in enumerate(replays): try: replay_length = replayfile.length.seconds replay_map = replayfile.map_name replay_date = replayfile.date replay_teams = replayfile.teams length_sum += replay_length file_counter = i + 1 # Print results to console if -a
import sc2reader import time import threading import os from multiprocessing.dummy import Pool from multiprocessing import Process path = "D:\\thesis\\replays500" replays = sc2reader.load_replays(path, load_level=4, debug=True) replayFiles = [path + '\\' + x for x in os.listdir(path)] def add_path(fileName): fileName = path + '\\' + fileName def read_replay(filePath): replay = sc2reader.load_replay(filePath, load_level=4, debug=True) process_replay(replay) def read_replays(replaysPaths): for filePath in replaysPaths: replay = sc2reader.load_replay(filePath, load_level=4, debug=True) process_replay(replay) print("Processed: %s" % filePath) def process_replay(replay): gameEvents = replay.events
import sc2reader, os, shutil, sys import stats from stats import * from sc2reader.utils import Length replay_path = "C:\\Users\\Ersin\\Documents\\StarCraft II\\Accounts\\64589640\\1-S2-1-1526382\\Replays\\Multiplayer" gameTimes = list() gameTimesWins = list() for replay in sc2reader.load_replays(replay_path, load_level = 1): if replay.category == "Ladder" and replay.type == "1v1": # load extra resources from the replay file replay.load_details() replay.load_players() gameTimes.append(replay.length.total_seconds()) #print help(replay) #print help(replay.length) print replay.length print replay.date for x in replay.teams: for y in x: print y # if we win this game then add it to the list of victory games if y.name == "Mania" and y.result == "Win": gameTimesWins.append(replay.length.total_seconds())
return paths def analyze_replay(replay, result_data): for player in replay.players: # bail if this player is not Protoss nydus = [i for i in player.units if 'Nydus' in i.name] if len(nydus) > 0: print("{0} on {1} at {2}".format(replay.type, replay.map_name, replay.start_time)) for team in replay.teams: print(team) print("Winner {0}".format(replay.winner)) print("Time {0}".format(replay.game_length)) print ("Created Nydus") result_data["nydus"] += len(nydus) if __name__ == '__main__': result_data = {} result_data["nydus"] = 0 paths = init_analyzer() for replay in sc2reader.load_replays(paths, debug=True): analyze_replay(replay, result_data) print ("###") print ("Nyduses Created", result_data["nydus"])
import sc2reader from collections import Counter replays = sc2reader.load_replays( '/Users/rodrigocanaan/Dev/SC2ReplayParser/test_replays/2.0.8.25604', load_map=True) d = {} c = Counter() for replay in replays: map = replay.map name = map.name h = replay.map_hash width = map.map_info.width heigth = map.map_info.height key = (name, h) info = (width, heigth) d[key] = info c[key] += 1 for (key, count) in c.most_common(): info = d[key] print('Map: ' + str(key) + ' Count: ' + str(count) + ' Info: ' + str(info))
def load_replays(self, folder_path: Path): """ Loads multiple replays as generator """ folder_path = str(folder_path.resolve()) return sc2reader.load_replays(folder_path, load_level=2, load_map=False)
def extractReplayDir(self, dirname): replays = sc2reader.load_replays("sc2reader/test_replays/2.1.4")
Base.metadata.create_all(engine) def chop_microseconds(delta): return delta - datetime.timedelta(microseconds=delta.microseconds) while response != 'exit': try: response = input( "Input day to calculate replay analysis time from in format \"YYYYmmDD\" (or exit): " ) path = cfg["replay_path"] + response replays = sc2reader.load_replays(path, load_level=4) session = Session() for replay in replays: olarva = {} tlarva = {} print(" Map: {0}".format(replay.map_name)) print(" Length: {0} minutes".format(replay.game_length)) print(" Date: {0}".format(replay.start_time)) lineups = [team.lineup for team in replay.teams] print(" Matchup: {0}".format("v".join(lineups))) for team in replay.teams: print(" Player {0}\t{1}".format(team.number,
from .load_config import * # Cell # Definition of the initial data needed to function CONFIG_PATH = Path( "/Users/david/Documents/phdcode/sc2trainingg") / "config.json" CONFIG = load_configurations(CONFIG_PATH) # Define the client and data base to work with MongoDB DB_Client = pymongo.MongoClient(CONFIG.port_address, CONFIG.port_number) DB = DB_Client[CONFIG.db_name] replays_info = DB['replays_info'] # Define the dependency the default to sc2reader assert Path(CONFIG.replay_path).exists(), "Invalid replay path" REPLAY_GEN = sc2reader.load_replays(CONFIG.replay_path) # Cell @dataclass(frozen=True) class Player_data: """ Immutable dataclass that contains Information that describes a player's attributes in a match. *Attributes:* - name (str): The player's user name. - number (int): Player number in the match. In a 1v1, match there would be a Player 1 and 2. - race (str):
def get_files_to_parse(): replay = sc2reader.load_replays(os.getcwd()) return replay
def main(argv): test_flag = False help_message = """ Available options are: -h help: Help (display this message) -t test: Run a test on a single replay" """ sc2reader.configure(depth=1) replays = sc2reader.load_replays('/home/steve/starcraft_replays', load_level=2) history = { "steve": { "protoss": [], "terran": [], "zerg": [] }, "ryan_s": { "protoss": [], "terran": [], "zerg": [] }, "kevin": { "protoss": [], "terran": [], "zerg": [] }, "stephen": { "protoss": [], "terran": [], "zerg": [] }, "laura": { "protoss": [], "terran": [], "zerg": [] }, "j": { "protoss": [], "terran": [], "zerg": [] }, "colin": { "protoss": [], "terran": [], "zerg": [] }, "bo": { "protoss": [], "terran": [], "zerg": [] }, "george": { "protoss": [], "terran": [], "zerg": [] }, "ryan_k": { "protoss": [], "terran": [], "zerg": [] }, "ai_very_easy": { "protoss": [], "terran": [], "zerg": [] }, "ai_easy": { "protoss": [], "terran": [], "zerg": [] }, "ai_medium": { "protoss": [], "terran": [], "zerg": [] }, "ai_hard": { "protoss": [], "terran": [], "zerg": [] }, "ai_harder": { "protoss": [], "terran": [], "zerg": [] }, "ai_very_hard": { "protoss": [], "terran": [], "zerg": [] }, "ai_elite": { "protoss": [], "terran": [], "zerg": [] }, "ai_insane": { "protoss": [], "terran": [], "zerg": [] } } valid_replay_length = 0 sorted_replays = sorted(replays, key=attrgetter('unix_timestamp')) for replay in sorted_replays: pprint( f"Date: {datetime.utcfromtimestamp(replay.unix_timestamp).strftime('%Y-%m-%d %H:%M:%S')}" ) pprint(f"Teams: {replay.teams}") if replay.winner is None: pprint("No winner found?") continue pprint(f"Winner: {replay.winner.players}") rating_groups = [] if not check_if_valid_teams(replay): continue for team in replay.teams: ratings_group = {} for p in team.players: if p.is_human and p.name in players: ratings_group[p] = getattr( players[p.name], p.play_race.lower()).current_trueskill elif not p.is_human: ratings_group[p] = getattr( players[f"A.I. ({p.difficulty})"], p.play_race.lower()).current_trueskill else: break if team.result == 'Win': rating_groups.insert(0, ratings_group) else: rating_groups.append(ratings_group) if len(ratings_group) > 1: rated_rating_groups = rate(rating_groups) else: continue valid_replay_length += 1 for i, team in enumerate(rated_rating_groups): for player, rating in team.items(): if player.is_human: player_race = getattr(players[player.name], player.play_race.lower()) else: player_race = getattr( players[f"A.I. ({player.difficulty})"], player.play_race.lower()) player_race.current_trueskill = rating history["steve"]["protoss"].append(steve.protoss.current_trueskill.mu) history["steve"]["terran"].append(steve.terran.current_trueskill.mu) history["steve"]["zerg"].append(steve.zerg.current_trueskill.mu) history["ryan_s"]["protoss"].append( ryan_s.protoss.current_trueskill.mu) history["ryan_s"]["terran"].append(ryan_s.terran.current_trueskill.mu) history["ryan_s"]["zerg"].append(ryan_s.zerg.current_trueskill.mu) history["kevin"]["protoss"].append(kevin.protoss.current_trueskill.mu) history["kevin"]["terran"].append(kevin.terran.current_trueskill.mu) history["kevin"]["zerg"].append(kevin.zerg.current_trueskill.mu) history["stephen"]["protoss"].append( stephen.protoss.current_trueskill.mu) history["stephen"]["terran"].append( stephen.terran.current_trueskill.mu) history["stephen"]["zerg"].append(stephen.zerg.current_trueskill.mu) history["laura"]["protoss"].append(laura.protoss.current_trueskill.mu) history["laura"]["terran"].append(laura.terran.current_trueskill.mu) history["laura"]["zerg"].append(laura.zerg.current_trueskill.mu) history["j"]["protoss"].append(j.protoss.current_trueskill.mu) history["j"]["terran"].append(j.terran.current_trueskill.mu) history["j"]["zerg"].append(j.zerg.current_trueskill.mu) history["colin"]["protoss"].append(colin.protoss.current_trueskill.mu) history["colin"]["terran"].append(colin.terran.current_trueskill.mu) history["colin"]["zerg"].append(colin.zerg.current_trueskill.mu) history["bo"]["protoss"].append(bo.protoss.current_trueskill.mu) history["bo"]["terran"].append(bo.terran.current_trueskill.mu) history["bo"]["zerg"].append(bo.zerg.current_trueskill.mu) history["george"]["protoss"].append( george.protoss.current_trueskill.mu) history["george"]["terran"].append(george.terran.current_trueskill.mu) history["george"]["zerg"].append(george.zerg.current_trueskill.mu) history["ryan_k"]["protoss"].append( ryan_k.protoss.current_trueskill.mu) history["ryan_k"]["terran"].append(ryan_k.terran.current_trueskill.mu) history["ryan_k"]["zerg"].append(ryan_k.zerg.current_trueskill.mu) history["ai_very_easy"]["protoss"].append( ai_very_easy.protoss.current_trueskill.mu) history["ai_very_easy"]["terran"].append( ai_very_easy.terran.current_trueskill.mu) history["ai_very_easy"]["zerg"].append( ai_very_easy.zerg.current_trueskill.mu) history["ai_easy"]["protoss"].append( ai_easy.protoss.current_trueskill.mu) history["ai_easy"]["terran"].append( ai_easy.terran.current_trueskill.mu) history["ai_easy"]["zerg"].append(ai_easy.zerg.current_trueskill.mu) history["ai_medium"]["protoss"].append( ai_medium.protoss.current_trueskill.mu) history["ai_medium"]["terran"].append( ai_medium.terran.current_trueskill.mu) history["ai_medium"]["zerg"].append( ai_medium.zerg.current_trueskill.mu) history["ai_hard"]["protoss"].append( ai_hard.protoss.current_trueskill.mu) history["ai_hard"]["terran"].append( ai_hard.terran.current_trueskill.mu) history["ai_hard"]["zerg"].append(ai_hard.zerg.current_trueskill.mu) history["ai_harder"]["protoss"].append( ai_harder.protoss.current_trueskill.mu) history["ai_harder"]["terran"].append( ai_harder.terran.current_trueskill.mu) history["ai_harder"]["zerg"].append( ai_harder.zerg.current_trueskill.mu) history["ai_very_hard"]["protoss"].append( ai_very_hard.protoss.current_trueskill.mu) history["ai_very_hard"]["terran"].append( ai_very_hard.terran.current_trueskill.mu) history["ai_very_hard"]["zerg"].append( ai_very_hard.zerg.current_trueskill.mu) history["ai_elite"]["protoss"].append( ai_elite.protoss.current_trueskill.mu) history["ai_elite"]["terran"].append( ai_elite.terran.current_trueskill.mu) history["ai_elite"]["zerg"].append(ai_elite.zerg.current_trueskill.mu) history["ai_insane"]["protoss"].append( ai_insane.protoss.current_trueskill.mu) history["ai_insane"]["terran"].append( ai_insane.terran.current_trueskill.mu) history["ai_insane"]["zerg"].append( ai_insane.zerg.current_trueskill.mu) for player in history: ax_num = 0 fig = plt.figure(figsize=(12, 12)) for race in ["protoss", "terran", "zerg"]: ax_num += 1 ax = fig.add_subplot(3, 1, ax_num) ax.set(xlim=(1, valid_replay_length + 1), ylim=(0, 50)) ax.set_ylabel('TrueSkill') ax.plot(range(0, valid_replay_length), list( map(lambda x: x.current_trueskill, history[player][race])), label=f"{player} as {race}") ax.set_title(f"{player} as {race}") pprint( f"{player} as {race} TrueSkill mu: {round(history[player][race][-1].current_trueskill.mu, 2)}, sigma: {round(history[player][race][-1].current_trueskill.sigma, 2)}" ) image_file = Path(f"plots/{player.replace(' ', '_')}") fig.savefig(image_file) try: opts, args = getopt.getopt(argv, "", [ "help", "test", "steve=", "ryan_s=", "ryan_k=", "colin=", "bo=", "j=", "laura=", "kevin=", "stephen=", "george=" ]) except getopt.GetoptError: print(help_message) sys.exit(2) players_array = [] for opt, arg in opts: if opt in ("--steve"): player_name = "steve" elif opt in ("--ryan_s"): player_name = "ryan_s" elif opt in ("--ryan_k"): player_name = "ryan_k" elif opt in ("--colin"): player_name = "colin" elif opt in ("--bo"): player_name = "bo" elif opt in ("--j"): player_name = "j" elif opt in ("--laura"): player_name = "laura" elif opt in ("--kevin"): player_name = "kevin" elif opt in ("--stephen"): player_name = "stephen" elif opt in ("--george"): player_name = "george" if arg == "protoss": player_race = "protoss" elif arg == "terran": player_race = "terran" elif arg == "zerg": player_race = "zerg" players_array.append({ "name": player_name, "race": player_race, "rating": getattr(globals()[player_name], player_race).current_trueskill }) total_sum = sum(map(lambda x: x['rating'].mu, players_array)) teams = [] for i in range(1, len(players_array)): combinations = itertools.combinations(players_array, i) for combo in combinations: for player in combo: print(f"{player['name']} {player['race']}", end=", ") team_1_sum = sum(map(lambda x: x['rating'].mu, combo)) print(team_1_sum) team_2_sum = total_sum - team_1_sum difference = team_1_sum - team_2_sum print(f"Difference: {difference}") teams.append({ 'team': (list(map(lambda x: x['name'], combo)), list(map(lambda x: x['race'], combo))), 'difference': abs(difference) }) sorted_teams = sorted(teams, key=lambda x: x['difference']) for i, team in enumerate(sorted_teams): if i % 2 == 0: print( f"Team {int((i / 2) + 1)}: {sorted_teams[i]['team']}, difference: {sorted_teams[i]['difference']}" )