Advertisement
Guest User

Cogmind Highscore script Legacy fix

a guest
Jun 22nd, 2017
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.48 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. # Copyright 2017 DBrickShaw
  4.  
  5. # Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  6. # and associated documentation files (the "Software"), to deal in the Software without restriction,
  7. # including without limitation the rights to use, copy, modify, merge, publish, distribute,
  8. # sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
  9. # furnished to do so, subject to the following conditions:
  10.  
  11. # The above copyright notice and this permission notice shall be included in all copies or
  12. # substantial portions of the Software.
  13.  
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
  15. # NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  17. # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19.  
  20. import os, re, datetime
  21.  
  22. BACKGROUND_COLOR = '000000'
  23. FOREGROUND_COLOR = 'cccccc'
  24. COLOR1 = '00e400'
  25. COLOR2 = '0086b2'
  26.  
  27. COL_GRAD = ['d90000', 'b25900', 'd9d900', '00d900', '00a3d9', 'bf00ff']
  28.  
  29. TIME_FIELD_WIDTH = 6
  30. STATS_FIELD_WIDTH = 50
  31. STATS_INDENT = 16
  32.  
  33. class RunStats(object):
  34.     def __init__(self, file):
  35.         self.parse(file)
  36.  
  37.     def parse(self, file):
  38.         for line in file:
  39.             line_split = line.split()
  40.            
  41.             if '---[' in line:
  42.                 self.ending = line.strip()
  43.            
  44.             # Performance
  45.             if 'TOTAL SCORE:' in line:
  46.                 self.score = int(line_split[2])
  47.                
  48.             # Cogmind
  49.             if 'Location' in line:
  50.                 self.location = ' '.join(line_split[1:])
  51.            
  52.             # Parts
  53.             if 'Power (' in line:
  54.                 self.power_slots = int(re.sub("[^0-9.]", "", line_split[1]))
  55.             if 'Propulsion (' in line:
  56.                 self.prop_slots = int(re.sub("[^0-9.]", "", line_split[1]))
  57.             if 'Utility (' in line:
  58.                 self.util_slots = int(re.sub("[^0-9.]", "", line_split[1]))
  59.             if 'Weapon (' in line:
  60.                 self.weap_slots = int(re.sub("[^0-9.]", "", line_split[1]))
  61.                
  62.             # Peak State
  63.             if '[Rating:' in line:
  64.                 self.rating = int(re.sub("[^0-9.]", "", line_split[1]))
  65.            
  66.             # Stats
  67.             if 'Damage Inflicted' in line:
  68.                 self.damage = int(line_split[2])
  69.             if 'Core Damage Taken' in line:
  70.                 self.damage_taken = int(line_split[3])
  71.             elif 'Damage Taken' in line:
  72.                 self.damage_taken = int(line_split[2])
  73.             if 'Turns Passed' in line:
  74.                 self.turns_passed = int(line_split[2])
  75.             if 'Shots Fired' in line:
  76.                 self.shots_fired = int(line_split[2])
  77.             if 'Melee Attacks' in line:
  78.                 self.melee = int(line_split[2])
  79.             if 'Maximum Alert Level' in line:
  80.                 self.max_alert = int(line_split[3])
  81.             if 'Low Security (%)' in line:
  82.                 self.low_sec = int(line_split[3])
  83.             if 'Total Hacks' in line:
  84.                 self.hacks = int(line_split[2])
  85.             if 'Successful' in line:
  86.                 self.success_hacks = int(line_split[1])
  87.             if 'Actions Taken' in line:
  88.                 self.actions = int(line_split[2])
  89.                
  90.             # Route
  91.             if 'Regions Visited' in line:
  92.                 self.visited = int(line_split[2])
  93.             if 'Route' in line:
  94.                 self.route = []
  95.                 for line in file:
  96.                     line_split = line.split()
  97.                     if not line.strip():
  98.                         break
  99.                     if '-------' in line:
  100.                         continue
  101.                     discovered_exits = False
  102.                     discovered_i = 0
  103.                     for i, token in enumerate(line_split):
  104.                         if '(' in token:
  105.                             discovered_exits = True
  106.                             discovered_i = i
  107.                             break
  108.                     if discovered_exits:
  109.                         self.route.append(' '.join(line_split[0:discovered_i]))
  110.                     else:
  111.                         self.route.append(line.strip())
  112.            
  113.             # Game
  114.             if 'Play Time:' in line:
  115.                 self.play_time = int(line_split[2])
  116.            
  117.         # Derived Stats
  118.         self.score_per_turn = float(self.score) / self.turns_passed
  119.         self.turns_per_min = float(self.turns_passed) / self.play_time
  120.         if self.hacks > 0:
  121.             self.success_hack_perc = (float(self.success_hacks) / self.hacks) * 100
  122.         else:
  123.             self.success_hack_perc = float(0)
  124.         self.actions_per_min = float(self.actions) / self.play_time
  125.        
  126.     def slot_config_plaintext(self):
  127.         return ('[' + str(self.power_slots) + '\\' + str(self.prop_slots) + '\\'
  128.                     + str(self.util_slots) + '\\' + str(self.weap_slots) + ']')
  129.                    
  130.     def __str__(self):            
  131.         return  ('{:<6}'.format(self.score) + '    ' + (' '*((STATS_FIELD_WIDTH-len(self.ending))/2)) + self.ending
  132.                 + '\n' + (' '*STATS_INDENT) + '{:<15}'.format(self.slot_config_plaintext())
  133.                     + 'Rating:    ' + ('%3d' % self.rating) + '  ' + ('{:^19}'.format(self.location))
  134.                 + '\n' + (' '*STATS_INDENT) + 'Shots:   ' + ('%4d' % self.shots_fired)
  135.                     + '  Melee:    ' + ('%4d' % self.melee) + '  Visited:         ' + ('%2d' % self.visited)
  136.                 + '\n' + (' '*STATS_INDENT) + 'Damage         Dealt: ' + ('%7d' % self.damage) + '  Taken:      ' + ('%7d' % self.damage_taken)
  137.                 + '\n' + (' '*STATS_INDENT) + 'Max Alert:  ' + str(self.max_alert) + '  Low Sec:  ' + ('%3d' % self.low_sec)
  138.                     + '%' + '  Hacks: ' + ('%3d' %  self.hacks)
  139.                     + ' (' + ('%5.1f' % self.success_hack_perc) + '%)'
  140.                 + '\n' + (' '*STATS_INDENT) + 'Turns: ' + ('%6d' % self.turns_passed) + '  Time:   ' + time_plaintext(self.play_time)
  141.                     + '  Actions:  ' + ('%9d' % self.actions)
  142.                 + '\n' + (' '*STATS_INDENT) + 'SPT: ' + ('%8.2f' % self.score_per_turn) + '  TPM:  ' + ('%8.2f' % self.turns_per_min)
  143.                     + '  APM:  ' + ('%13.2f' % self.actions_per_min))    
  144.  
  145.     def html_str(self, agg_stats):
  146.         return  (cstr('{:<6}'.format(self.score), COLOR1) + '    ' + (' '*((STATS_FIELD_WIDTH-len(self.ending))/2)) + cstr(self.ending, COLOR1)
  147.                 + '\n' + (' '*STATS_INDENT) + '[' + cstr(self.power_slots, COLOR1) + cstr('\\', COLOR2) + cstr(self.prop_slots, COLOR1) + cstr('\\', COLOR2)
  148.                     + cstr(self.util_slots, COLOR1) + cstr('\\', COLOR2) + cstr(self.weap_slots, COLOR1) + ']'
  149.                     + (' '*(15-len(self.slot_config_plaintext())))
  150.                     + 'Rating:    ' + cstr('%3d' % self.rating, grad_color(self.rating, agg_stats.min_rating, agg_stats.max_rating))
  151.                     + '  ' + cstr('{:^19}'.format(self.location), location_color(self.location))
  152.                 + '\n' + (' '*STATS_INDENT) + 'Shots:   ' + cstr('%4d' % self.shots_fired, COLOR1)
  153.                     + '  Melee:    ' + cstr('%4d' %self.melee, COLOR1) + '  Visited:         ' + cstr('%2d' % self.visited, COLOR1)
  154.                 + '\n' + (' '*STATS_INDENT) + 'Damage         Dealt: ' + cstr('%7d' % self.damage, COLOR1) + '  Taken:      ' + cstr('%7d' % self.damage_taken, COLOR1)
  155.                 + '\n' + (' '*STATS_INDENT) + 'Max Alert:  ' + cstr(self.max_alert, COLOR1) + '  Low Sec:  ' + cstr('%3d' % self.low_sec, COLOR1)
  156.                     + cstr('%', COLOR2) + '  Hacks: ' + cstr('%3d' %  self.hacks, COLOR1)
  157.                     + ' (' + cstr(('%5.1f' % self.success_hack_perc), COLOR1) + cstr('%', COLOR2) + ')'
  158.                 + '\n' + (' '*STATS_INDENT) + 'Turns: ' + cstr('%6d' % self.turns_passed, COLOR1) + '  Time:   ' + time_html(self.play_time)
  159.                     + '  Actions:  ' + cstr('%9d' % self.actions, COLOR1)
  160.                 + '\n' + (' '*STATS_INDENT) + 'SPT: '
  161.                     + 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))
  162.                     + '  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))
  163.                     + '  APM:  '
  164.                     + 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)))
  165.  
  166.                
  167. class AggregateRunStats(object):
  168.     def __init__(self, run_list):
  169.         self.run_list = run_list
  170.        
  171.         self.max_rating = max(run.rating for run in self.run_list)
  172.         self.max_score_per_turn = max(run.score_per_turn for run in self.run_list)
  173.         self.max_actions_per_min = max(run.actions_per_min for run in self.run_list)
  174.         self.max_turns_per_min = max(run.turns_per_min for run in self.run_list)
  175.         self.max_low_sec = max(run.low_sec for run in self.run_list)
  176.         self.max_hacks = max(run.hacks for run in self.run_list)
  177.         self.max_success_hack_perc = max(run.success_hack_perc for run in self.run_list)
  178.         self.max_damage = max(run.damage for run in self.run_list)
  179.        
  180.         self.min_rating = min(run.rating for run in self.run_list)
  181.         self.min_score_per_turn = min(run.score_per_turn for run in self.run_list)
  182.         self.min_actions_per_min = min(run.actions_per_min for run in self.run_list)
  183.         self.min_turns_per_min = min(run.turns_per_min for run in self.run_list)
  184.         self.min_low_sec = min(run.low_sec for run in self.run_list)
  185.         self.min_hacks = min(run.hacks for run in self.run_list)
  186.         self.min_success_hack_perc = min(run.success_hack_perc for run in self.run_list)
  187.         self.min_damage = min(run.damage for run in self.run_list)
  188.        
  189.        
  190. def cstr(string, color_hex):
  191.     return '<font color="#' + color_hex + '">' + str(string) + '</font>'
  192.  
  193. def time_plaintext(play_time):
  194.     if play_time > 60:
  195.         time_str = str(play_time / 60) + 'h' + str(play_time % 60) + 'm'
  196.     else:
  197.         time_str = str(play_time) + 'm'
  198.     return ('{:>' + str(TIME_FIELD_WIDTH) + '}').format(time_str)
  199.    
  200. def time_html(play_time):
  201.     if play_time > 60:
  202.         time_str = (cstr(play_time / 60, COLOR1)  + cstr('h', COLOR2)
  203.                 + cstr(play_time % 60, COLOR1) + cstr('m', COLOR2))
  204.     else:
  205.         time_str = cstr(play_time, COLOR1)  + cstr('m', COLOR2)
  206.     return (' '*(TIME_FIELD_WIDTH - len(time_plaintext(play_time).strip()))) + time_str
  207.  
  208. def grad_color(val, min, max):
  209.     ratio = float((val - min)) / (max - min);
  210.     for i, col_hex in enumerate(COL_GRAD):
  211.         if ratio <= float(i + 1) / len(COL_GRAD):
  212.             return col_hex
  213.     return FOREGROUND_COLOR
  214.    
  215. def location_color(loc):
  216.     if 'Materials' in loc or 'Scrapyard' in loc:
  217.         return '9e8664'
  218.     if 'Mines' in loc:
  219.         return '666666'
  220.     if 'Storage' in loc:
  221.         return 'b25900'
  222.     if 'Caves' in loc or 'Zion' in loc:
  223.         return '665233'
  224.     if 'Garrison' in loc:
  225.         return 'b20000'
  226.     if 'Factory' in loc:
  227.         return '9e9e9e'
  228.     if 'Research' in loc:
  229.         return 'bf00ff'
  230.     if 'Quarantine' in loc or 'Testing' in loc:
  231.         return '00b200'
  232.     if 'Armory' in loc:
  233.         return 'ff0000'
  234.     if 'Extension' in loc or 'Hub' in loc:
  235.         return '848400'
  236.     if 'Access' in loc:
  237.         return 'dedede'
  238.     if 'Command' in loc:
  239.         return '00a3d9'
  240.     if 'Warlord' in loc:
  241.         return 'b22d00'
  242.     return '00e100'
  243.    
  244.    
  245. if __name__ == '__main__':
  246.     # Load and sort all run stats
  247.     run_list = []
  248.     for filename in os.listdir('scores'):
  249.         if '.txt' in filename:
  250.             with open(os.path.join('scores', filename), 'r') as f:
  251.                 run_list.append(RunStats(f))
  252.     run_list = sorted(run_list, key=lambda run: run.score, reverse=True)
  253.     agg_stats = AggregateRunStats(run_list)
  254.     # Generate list of locations visisted
  255.     branch_set = set()
  256.     for run in run_list:
  257.         branch_set = branch_set | set(run.route)
  258.     branch_list = sorted(list(branch_set),
  259.         key=lambda branch: int(branch[0:branch.index('/')]) if '/' in branch else branch,
  260.         reverse=True)
  261.    
  262.     # Generate the high score plaintext output
  263.     datetime_str = datetime.datetime.now().strftime("%I:%M%p, %B %d, %Y")
  264.     out_str =  '\n -----------------------------\n'
  265.     out_str += '  --[ COGMIND HIGH SCORES ]--\n'
  266.     out_str += ' -----------------------------\n   '
  267.     out_str += datetime_str + '\n\n'
  268.     for i, run in enumerate(run_list):
  269.         if i > 0: out_str += '\n\n'
  270.         out_str += '{:<6s}'.format(str(i + 1) + '.') + str(run)
  271.     total_time = sum(run.play_time for run in run_list)
  272.     out_str += '\n\nTotal Time: ' + str(total_time / 60) + 'h' + str(total_time % 60) + 'm'
  273.     out_str += '\n\n Locations Visited'
  274.     out_str += '\n-------------------'
  275.     for branch in branch_list:
  276.         out_str += '\n' + str(branch)
  277.     # Write the plaintext output to file
  278.     with open(os.path.join(os.getcwd(), 'high_scores.txt'), 'w') as f:
  279.         f.write(out_str)
  280.     # Write the plaintext output to stdout
  281.     print out_str
  282.    
  283.     # Generate the high score HTML output
  284.     out_html = '<html><body text="#' + FOREGROUND_COLOR + '" bgcolor="#' + BACKGROUND_COLOR + '"><pre>'
  285.     out_html += '\n -----------------------------\n'
  286.     out_html += '  --[ ' + cstr('COGMIND HIGH SCORES', COLOR1) + ' ]--\n'
  287.     out_html += ' -----------------------------\n   '
  288.     out_html += cstr(datetime_str, COLOR1) + '\n\n'
  289.     for i, run in enumerate(run_list):
  290.         if i > 0: out_html += '\n\n'
  291.         out_html += cstr(i + 1, COLOR1) + '.' + (' '*(6-len(str(i))-1)) + run.html_str(agg_stats)
  292.     out_html += '\n\nTotal Time: ' + time_html(total_time)
  293.     out_html += '\n\n Locations Visited'
  294.     out_html += '\n-------------------'
  295.     for branch in branch_list:
  296.         out_html += '\n' + cstr(branch, location_color(branch))
  297.     out_html += '</body></html>'
  298.     # Write the HTML output to file
  299.     with open(os.path.join(os.getcwd(), 'high_scores.html'), 'w') as f:
  300.         f.write(out_html)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement