Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # Copyright 2017 DBrickShaw
- # Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- # and associated documentation files (the "Software"), to deal in the Software without restriction,
- # including without limitation the rights to use, copy, modify, merge, publish, distribute,
- # sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- # furnished to do so, subject to the following conditions:
- # The above copyright notice and this permission notice shall be included in all copies or
- # substantial portions of the Software.
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- # NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- import os, re, datetime
- BACKGROUND_COLOR = '000000'
- FOREGROUND_COLOR = 'cccccc'
- COLOR1 = '00e400'
- COLOR2 = '0086b2'
- COL_GRAD = ['d90000', 'b25900', 'd9d900', '00d900', '00a3d9', 'bf00ff']
- TIME_FIELD_WIDTH = 6
- STATS_FIELD_WIDTH = 50
- STATS_INDENT = 16
- class RunStats(object):
- def __init__(self, file):
- self.parse(file)
- def parse(self, file):
- for line in file:
- line_split = line.split()
- if '---[' in line:
- self.ending = line.strip()
- # Performance
- if 'TOTAL SCORE:' in line:
- self.score = int(line_split[-1])
- # Cogmind
- if 'Location' in line:
- self.location = ' '.join(line_split[1:])
- # Parts
- if 'Power (' in line:
- self.power_slots = int(re.sub("[^0-9.]", "", line_split[-1]))
- if 'Propulsion (' in line:
- self.prop_slots = int(re.sub("[^0-9.]", "", line_split[-1]))
- if 'Utility (' in line:
- self.util_slots = int(re.sub("[^0-9.]", "", line_split[-1]))
- if 'Weapon (' in line:
- self.weap_slots = int(re.sub("[^0-9.]", "", line_split[-1]))
- # Peak State
- if '[Rating:' in line:
- self.rating = int(re.sub("[^0-9.]", "", line_split[-1]))
- # Stats
- if 'Damage Inflicted' in line:
- self.damage = int(line_split[-1])
- if 'Damage Taken' in line:
- self.damage_taken = int(line_split[-1])
- if 'Turns Passed' in line:
- self.turns_passed = int(line_split[-1])
- if 'Shots Fired' in line:
- self.shots_fired = int(line_split[-1])
- if 'Melee Attacks' in line:
- self.melee = int(line_split[-1])
- if 'Maximum Alert Level' in line:
- self.max_alert = int(line_split[-1])
- if 'Low Security (%)' in line:
- self.low_sec = int(line_split[-1])
- if 'Total Hacks' in line:
- self.hacks = int(line_split[-1])
- if 'Successful' in line:
- self.success_hacks = int(line_split[-1])
- if 'Actions Taken' in line:
- self.actions = int(line_split[-1])
- # Route
- if 'Regions Visited' in line:
- self.visited = int(line_split[-1])
- if 'Route' in line:
- self.route = []
- for line in file:
- line_split = line.split()
- if not line.strip():
- break
- if '-------' in line:
- continue
- discovered_exits = False
- discovered_i = 0
- for i, token in enumerate(line_split):
- if '(' in token:
- discovered_exits = True
- discovered_i = i
- break
- if discovered_exits:
- self.route.append(' '.join(line_split[0:discovered_i]))
- else:
- self.route.append(line.strip())
- # Game
- if 'Play Time:' in line:
- self.play_time = int(line_split[-2])
- if not hasattr(self, 'actions'):
- self.actions = 0
- if not hasattr(self, 'rating'):
- self.rating = 0
- # Derived Stats
- self.score_per_turn = float(self.score) / self.turns_passed if self.turns_passed > 0 else 0.0
- self.turns_per_min = float(self.turns_passed) / self.play_time if self.play_time > 0 else 0.0
- self.success_hack_perc = (float(self.success_hacks) / self.hacks) * 100 if self.hacks > 0 else 0.0
- self.actions_per_min = float(self.actions) / self.play_time if self.play_time > 0 else 0.0
- def slot_config_plaintext(self):
- return ('[' + str(self.power_slots) + '\\' + str(self.prop_slots) + '\\'
- + str(self.util_slots) + '\\' + str(self.weap_slots) + ']')
- def __str__(self):
- return ('{:<6}'.format(self.score) + ' ' + (' '*((STATS_FIELD_WIDTH-len(self.ending))/2)) + self.ending
- + '\n' + (' '*STATS_INDENT) + '{:<15}'.format(self.slot_config_plaintext())
- + 'Rating: ' + ('%3d' % self.rating) + ' ' + ('{:^19}'.format(self.location))
- + '\n' + (' '*STATS_INDENT) + 'Shots: ' + ('%4d' % self.shots_fired)
- + ' Melee: ' + ('%4d' % self.melee) + ' Visited: ' + ('%2d' % self.visited)
- + '\n' + (' '*STATS_INDENT) + 'Damage Dealt: ' + ('%7d' % self.damage) + ' Taken: ' + ('%7d' % self.damage_taken)
- + '\n' + (' '*STATS_INDENT) + 'Max Alert: ' + str(self.max_alert) + ' Low Sec: ' + ('%3d' % self.low_sec)
- + '%' + ' Hacks: ' + ('%3d' % self.hacks)
- + ' (' + ('%5.1f' % self.success_hack_perc) + '%)'
- + '\n' + (' '*STATS_INDENT) + 'Turns: ' + ('%6d' % self.turns_passed) + ' Time: ' + time_plaintext(self.play_time)
- + ' Actions: ' + ('%9d' % self.actions)
- + '\n' + (' '*STATS_INDENT) + 'SPT: ' + ('%8.2f' % self.score_per_turn) + ' TPM: ' + ('%8.2f' % self.turns_per_min)
- + ' APM: ' + ('%13.2f' % self.actions_per_min))
- def html_str(self, agg_stats):
- return (cstr('{:<6}'.format(self.score), COLOR1) + ' ' + (' '*((STATS_FIELD_WIDTH-len(self.ending))/2)) + cstr(self.ending, COLOR1)
- + '\n' + (' '*STATS_INDENT) + '[' + cstr(self.power_slots, COLOR1) + cstr('\\', COLOR2) + cstr(self.prop_slots, COLOR1) + cstr('\\', COLOR2)
- + cstr(self.util_slots, COLOR1) + cstr('\\', COLOR2) + cstr(self.weap_slots, COLOR1) + ']'
- + (' '*(15-len(self.slot_config_plaintext())))
- + 'Rating: ' + cstr('%3d' % self.rating, grad_color(self.rating, agg_stats.min_rating, agg_stats.max_rating))
- + ' ' + cstr('{:^19}'.format(self.location), location_color(self.location))
- + '\n' + (' '*STATS_INDENT) + 'Shots: ' + cstr('%4d' % self.shots_fired, COLOR1)
- + ' Melee: ' + cstr('%4d' %self.melee, COLOR1) + ' Visited: ' + cstr('%2d' % self.visited, COLOR1)
- + '\n' + (' '*STATS_INDENT) + 'Damage Dealt: ' + cstr('%7d' % self.damage, COLOR1) + ' Taken: ' + cstr('%7d' % self.damage_taken, COLOR1)
- + '\n' + (' '*STATS_INDENT) + 'Max Alert: ' + cstr(self.max_alert, COLOR1) + ' Low Sec: ' + cstr('%3d' % self.low_sec, COLOR1)
- + cstr('%', COLOR2) + ' Hacks: ' + cstr('%3d' % self.hacks, COLOR1)
- + ' (' + cstr(('%5.1f' % self.success_hack_perc), COLOR1) + cstr('%', COLOR2) + ')'
- + '\n' + (' '*STATS_INDENT) + 'Turns: ' + cstr('%6d' % self.turns_passed, COLOR1) + ' Time: ' + time_html(self.play_time)
- + ' Actions: ' + cstr('%9d' % self.actions, COLOR1)
- + '\n' + (' '*STATS_INDENT) + 'SPT: '
- + cstr('%8.2f' % self.score_per_turn, grad_color(self.score_per_turn, agg_stats.min_score_per_turn, agg_stats.max_score_per_turn))
- + ' TPM: ' + cstr('%8.2f' % self.turns_per_min, grad_color(self.turns_per_min, agg_stats.min_turns_per_min, agg_stats.max_turns_per_min))
- + ' APM: '
- + cstr('%13.2f' % self.actions_per_min, grad_color(self.actions_per_min, agg_stats.min_actions_per_min, agg_stats.max_actions_per_min)))
- class AggregateRunStats(object):
- def __init__(self, run_list):
- self.run_list = run_list
- self.max_rating = max(run.rating for run in self.run_list)
- self.max_score_per_turn = max(run.score_per_turn for run in self.run_list)
- self.max_actions_per_min = max(run.actions_per_min for run in self.run_list)
- self.max_turns_per_min = max(run.turns_per_min for run in self.run_list)
- self.max_low_sec = max(run.low_sec for run in self.run_list)
- self.max_hacks = max(run.hacks for run in self.run_list)
- self.max_success_hack_perc = max(run.success_hack_perc for run in self.run_list)
- self.max_damage = max(run.damage for run in self.run_list)
- self.min_rating = min(run.rating for run in self.run_list)
- self.min_score_per_turn = min(run.score_per_turn for run in self.run_list)
- self.min_actions_per_min = min(run.actions_per_min for run in self.run_list)
- self.min_turns_per_min = min(run.turns_per_min for run in self.run_list)
- self.min_low_sec = min(run.low_sec for run in self.run_list)
- self.min_hacks = min(run.hacks for run in self.run_list)
- self.min_success_hack_perc = min(run.success_hack_perc for run in self.run_list)
- self.min_damage = min(run.damage for run in self.run_list)
- def cstr(string, color_hex):
- return '<font color="#' + color_hex + '">' + str(string) + '</font>'
- def time_plaintext(play_time):
- if play_time > 60:
- time_str = str(play_time / 60) + 'h' + str(play_time % 60) + 'm'
- else:
- time_str = str(play_time) + 'm'
- return ('{:>' + str(TIME_FIELD_WIDTH) + '}').format(time_str)
- def time_html(play_time):
- if play_time > 60:
- time_str = (cstr(play_time / 60, COLOR1) + cstr('h', COLOR2)
- + cstr(play_time % 60, COLOR1) + cstr('m', COLOR2))
- else:
- time_str = cstr(play_time, COLOR1) + cstr('m', COLOR2)
- return (' '*(TIME_FIELD_WIDTH - len(time_plaintext(play_time).strip()))) + time_str
- def grad_color(val, min, max):
- ratio = float((val - min)) / (max - min) if (max - min) != 0 else 0.0;
- for i, col_hex in enumerate(COL_GRAD):
- if ratio <= float(i + 1) / len(COL_GRAD):
- return col_hex
- return FOREGROUND_COLOR
- def location_color(loc):
- if 'Materials' in loc or 'Scrapyard' in loc:
- return '9e8664'
- if 'Mines' in loc:
- return '666666'
- if 'Storage' in loc:
- return 'b25900'
- if 'Caves' in loc or 'Zion' in loc:
- return '665233'
- if 'Garrison' in loc:
- return 'b20000'
- if 'Factory' in loc:
- return '9e9e9e'
- if 'Research' in loc:
- return 'bf00ff'
- if 'Quarantine' in loc or 'Testing' in loc:
- return '00b200'
- if 'Armory' in loc:
- return 'ff0000'
- if 'Extension' in loc or 'Hub' in loc:
- return '848400'
- if 'Access' in loc:
- return 'dedede'
- if 'Command' in loc:
- return '00a3d9'
- if 'Warlord' in loc:
- return 'b22d00'
- return '00e100'
- if __name__ == '__main__':
- # Load and sort all run stats
- run_list = []
- for filename in os.listdir('scores'):
- if '.txt' in filename:
- with open(os.path.join('scores', filename), 'r') as f:
- run_list.append(RunStats(f))
- run_list = sorted(run_list, key=lambda run: run.score, reverse=True)
- agg_stats = AggregateRunStats(run_list)
- # Generate list of locations visisted
- branch_set = set()
- for run in run_list:
- branch_set = branch_set | set(run.route)
- branch_list = sorted(list(branch_set),
- key=lambda branch: int(branch[0:branch.index('/')]) if '/' in branch else branch,
- reverse=True)
- # Generate the high score plaintext output
- datetime_str = datetime.datetime.now().strftime("%I:%M%p, %B %d, %Y")
- out_str = '\n -----------------------------\n'
- out_str += ' --[ COGMIND HIGH SCORES ]--\n'
- out_str += ' -----------------------------\n '
- out_str += datetime_str + '\n\n'
- for i, run in enumerate(run_list):
- if i > 0: out_str += '\n\n'
- out_str += '{:<6s}'.format(str(i + 1) + '.') + str(run)
- total_time = sum(run.play_time for run in run_list)
- out_str += '\n\nTotal Time: ' + str(total_time / 60) + 'h' + str(total_time % 60) + 'm'
- out_str += '\n\n Locations Visited'
- out_str += '\n-------------------'
- for branch in branch_list:
- out_str += '\n' + str(branch)
- # Write the plaintext output to file
- with open(os.path.join(os.getcwd(), 'high_scores.txt'), 'w') as f:
- f.write(out_str)
- # Write the plaintext output to stdout
- print out_str
- # Generate the high score HTML output
- out_html = '<html><body text="#' + FOREGROUND_COLOR + '" bgcolor="#' + BACKGROUND_COLOR + '"><pre>'
- out_html += '\n -----------------------------\n'
- out_html += ' --[ ' + cstr('COGMIND HIGH SCORES', COLOR1) + ' ]--\n'
- out_html += ' -----------------------------\n '
- out_html += cstr(datetime_str, COLOR1) + '\n\n'
- for i, run in enumerate(run_list):
- if i > 0: out_html += '\n\n'
- out_html += cstr(i + 1, COLOR1) + '.' + (' '*(6-len(str(i))-1)) + run.html_str(agg_stats)
- out_html += '\n\nTotal Time: ' + time_html(total_time)
- out_html += '\n\n ' + cstr('Locations Visited', COLOR1)
- out_html += '\n-------------------'
- for branch in branch_list:
- out_html += '\n' + cstr(branch, location_color(branch))
- out_html += '</body></html>'
- # Write the HTML output to file
- with open(os.path.join(os.getcwd(), 'high_scores.html'), 'w') as f:
- f.write(out_html)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement