From 2043c362811805f1a9e6d63cb2dd47bd3424bbd8 Mon Sep 17 00:00:00 2001 From: jonomon Date: Mon, 8 Jul 2013 10:57:29 -0400 Subject: [PATCH 1/8] Added creepTracker --- sc2reader/factories/plugins/replay.py | 232 ++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) diff --git a/sc2reader/factories/plugins/replay.py b/sc2reader/factories/plugins/replay.py index 81a05c54..f1c3d38b 100644 --- a/sc2reader/factories/plugins/replay.py +++ b/sc2reader/factories/plugins/replay.py @@ -120,6 +120,238 @@ def APMTracker(replay): return replay +@plugin +def CreepTracker(replay): + from itertools import izip_longest, dropwhile + from random import random + from math import sqrt, pi + + def add_to_list(control_pid,unit_id,unit_location,\ + unit_type,event_time, creep_generating_units_list): + length_cgu_list = len(creep_generating_units_list[control_pid]) + if length_cgu_list==0: + creep_generating_units_list[control_pid].append([(unit_id, unit_location,unit_type,event_time)]) + else: + previous_list = creep_generating_units_list[control_pid][length_cgu_list-1][:] + previous_list.append((unit_id, unit_location,unit_type,event_time)) + creep_generating_units_list[control_pid].append(previous_list) + + def in_circles(point_x,point_y,cgu_radius): + for cgu in cgu_radius: + circle_x = cgu[0][0] + circle_y = cgu[0][1] + radius = cgu[1] + distance = (circle_x-point_x)**2 + (circle_y-point_y)**2 + if distance < (radius*radius): + return 1 + return 0 + + def distance(point1,point2): + distance = (point1[0]-point2[0])**2 + (point1[1]-point2[1])**2 + return distance + + def calculate_area(cgu_radius): + if len(cgu_radius)==1: + print "Area Calculated",pi*(cgu_radius[0][1]**2) + return pi*(cgu_radius[0][1]**2) + + # from cgu_radius get a square which surrounds maximum + # possible area that the creep lies in + max_x = max(cgu_radius, key=lambda x: x[0][0]+x[1]) + max_y = max(cgu_radius, key=lambda x: x[0][1]+x[1]) + min_x = min(cgu_radius, key=lambda x: x[0][0] - x[1]) + min_y = min(cgu_radius, key=lambda x: x[0][1] - x[1]) + + max_x = max_x[0][0] + max_x[1] + max_y = max_y[0][1] + max_y[1] + min_x = min_x[0][0] - min_x[1] + min_y = min_y[0][1] - min_y[1] + + area = 0 + for x in range(min_x,max_x): + for y in range(min_y,max_y): + if in_circles(x,y,cgu_radius): + area+=1 + return area + + + def single_linkage_clustering(cgu_points, maxR,labels=0,cgu_length = 0): + inf = -1000 + if labels==0: + labels = [0 for x in cgu_points] + cgu_length = len(cgu_points) + if len(cgu_points) ==1: + return [0] + + # calculate distance array + distance_array = list() + for i in range (len(cgu_points)): + i_lengths = list() + for j in range(len(cgu_points)): + if i !=j: + if cgu_points[i][0] == inf and cgu_points [j][0] == inf: + i_lengths.append(-inf) + else: + i_lengths.append(distance(cgu_points[i], cgu_points[j])) + + distance_array.append(i_lengths) + + #Find closest point distance for each point + min_array = map(lambda x:min(x), distance_array) + + #combine 2 points with smallest distance + min_distance = min(min_array) + if min_distance < maxR: + point1 = min_array.index(min_distance) + point2 = min_array[point1+1:].index(min_distance)+point1+1 + #label each cgu points + current_label = max(labels)+1 if labels[point1] ==0 and\ + labels[point2] ==0 else max(labels[point1],labels[point2]) + labels[point1] = current_label + labels[point2] = current_label + labels.append(current_label) + + new_x = (cgu_points[point1][0] + cgu_points[point2][0])/2 + new_y = (cgu_points[point1][1] + cgu_points[point2][1])/2 + cgu_points[point1]=(inf,inf) + cgu_points[point2]=(inf,inf) + cgu_points.append((new_x,new_y)) + + labels = single_linkage_clustering(cgu_points,maxR,labels,cgu_length) + return labels[0:cgu_length] + else: + return_value = labels[0:cgu_length] + return return_value + + + #Get Map Size + mapinfo = replay.map.archive.read_file('MapInfo') + mapSizeX = ord(mapinfo[16]) + mapSizeY = ord(mapinfo[20]) + mapSize = mapSizeX * mapSizeX/100 + + creep_generating_units_list = dict() + + for player in replay.players: + player.creep_spread_by_minute = defaultdict(int) + player.max_creep_spread = int() + creep_generating_units_list[player.pid] = list() + try: + replay.tracker_events + except AttributeError: + print "Replay does not have tracker events" + return replay + + for tracker_event,game_event in izip_longest(replay.tracker_events,replay.game_events): + + # First search things that generate creep + # Tumor, hatcheries, nydus and overlords generating creep + + if tracker_event and tracker_event.name == "UnitInitEvent": + units = ["CreepTumor", "Hatchery","Nydus"] # check nydus name + if tracker_event.unit_type_name in units: + add_to_list(tracker_event.control_pid,tracker_event.unit_id,\ + (tracker_event.x, tracker_event.y), \ + tracker_event.unit_type_name,\ + tracker_event.second,\ + creep_generating_units_list) + + if game_event and game_event.name == "AbilityEvent": + + if game_event.ability_name == "GenerateCreep": + add_to_list(game_event.control_pid,game_event.unit_id,\ + (game_event.x, game_event.y), \ + game_event.unit_type_name,\ + game_event.second,\ + creep_generating_units_list) + + # # Removes creep generating units that were destroyed + if tracker_event and tracker_event.name == "UnitDiedEvent": + for player in creep_generating_units_list: + length_cgu_list = len(creep_generating_units_list[player]) + if length_cgu_list ==0: + break + cgu_per_player = creep_generating_units_list[player][length_cgu_list-1] + creep_generating_died = dropwhile(lambda x: x[0] != tracker_event.unit_id, \ + cgu_per_player) + for creep_generating_died_unit in creep_generating_died: + + cgu_per_player.remove(creep_generating_died_unit) + creep_generating_units_list[player].append(cgu_per_player) + + #reduce all events to last event in the minute + last_minute_found = 0 + for player in replay.player: + cgu_per_player_new = list() + for cgu_per_player in creep_generating_units_list[player]: + if len(cgu_per_player) ==0: + continue + cgu_last_event_time = cgu_per_player[-1][3] + + if (cgu_last_event_time/60)>last_minute_found: + last_minute_found = cgu_last_event_time/60 + cgu_per_player_new.append(cgu_per_player) + cgu_per_player = cgu_per_player_new + + + max_creep_spread=defaultdict() + for player in replay.player: + # convert cg u list into centre of circles and radius + unit_name_to_radius = {'CreepTumor': 15, "Hatchery":17,\ + "GenerateCreep": 10, "Nydus": 5 } + + max_creep_spread[player] = 0 + + for index,cgu_per_player in enumerate(creep_generating_units_list[player]): + + cgu_radius = map(lambda x: (x[1], unit_name_to_radius[x[2]]),\ + cgu_per_player) + cgu_points = map(lambda x: x[0],cgu_radius) + + if cgu_points: + labels = single_linkage_clustering(cgu_points,350) + else: + if index != 0: + replay.player[player].creep_spread_by_minute[cgu_last_event_time+1] = 0 + continue + + area = 0 + #if all labels 0 (all separate clusters) calculate it separately + if max(labels) ==0: + for cgu_radi in cgu_radius: + area+= pi * cgu_radi[1]**2 + + cgu_last_event_time = cgu_per_player[-1][3]/60 + replay.player[player].creep_spread_by_minute[cgu_last_event_time] = area/mapSize + continue + + count =0 + while True: + clusters = filter(lambda x : True if x[0] == count else\ + False , zip(labels,cgu_radius) ) + + cgu_clusters = map(lambda x:x[1], clusters) + if count==0: + for cgu_radi in cgu_clusters: + area+= pi * cgu_radi[1]**2 + count+=1 + continue + if len(clusters) ==0: + break + count+=1 + area += calculate_area(cgu_clusters) + cgu_last_event_time = cgu_per_player[-1][3]/60 + replay.player[player].creep_spread_by_minute[cgu_last_event_time] = area/mapSize + + if area>max_creep_spread[player]: + max_creep_spread[player] =area + + + for player in replay.player: + replay.player[player].max_creep_spread = max_creep_spread[player]/mapSize + + return replay + @plugin def SelectionTracker(replay): From 0ffbe41e179c6e56b5643b2e04eb69c4aee4d66d Mon Sep 17 00:00:00 2001 From: jonomon Date: Wed, 31 Jul 2013 12:07:45 -0400 Subject: [PATCH 2/8] Added supply tracker --- sc2reader/engine/plugins/supply.py | 73 ++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 sc2reader/engine/plugins/supply.py diff --git a/sc2reader/engine/plugins/supply.py b/sc2reader/engine/plugins/supply.py new file mode 100644 index 00000000..535d190c --- /dev/null +++ b/sc2reader/engine/plugins/supply.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, print_function, unicode_literals, division + +from collections import defaultdict + +class SupplyTracker(object): + def add_to_units_alive(self,event,replay): + try: ## see if the unit takes supply + supplyCount = self.unit_name_to_supply[event.unit_type_name] + new_unit = (supplyCount, event.unit_id) + self.units_alive[event.control_pid].append(new_unit) + total_supply = sum([x[0] for x in self.units_alive[event.control_pid]]) + replay.players[event.control_pid-1].current_food_used[event.second]= total_supply + print("SECOND",event.second, "Player",replay.players[event.control_pid-1],"SUPPLY",replay.players[event.control_pid-1].current_food_used[event.second]) + except KeyError: + try: ## see if the unit provides supply + supply_gen_count = (self.supply_gen_unit[event.unit_type_name]) + supply_gen_unit = (supply_gen_count,event.unit_id) + self.supply_gen[event.control_pid].append(supply_gen_unit) + total_supply_gen = sum([x[0] for x in self.units_alive[event.control_pid]]) + replay.players[event.control_pid-1].current_food_made[event.second]= total_supply_gen + except KeyError: + print("Unit name {0} does not exist".format(event.unit_type_name)) + return + + def remove_from_units_alive(self,event,replay): + died_unit_id = event.unit_id + for player in replay.player: + dead_unit = filter(lambda x:x[1]==died_unit_id, self.units_alive[player]) + if dead_unit: + self.units_alive[player].remove(dead_unit[0]) + total_supply = sum([x[0] for x in self.units_alive[player]]) + replay.players[player-1].current_food_used[event.second] = total_supply + print("Second", event.second, "Killed", event.unit.name,"SUPPLY",replay.players[player-1].current_food_used[event.second]) + + dead_supply_gen = filter(lambda x:x[1]==died_unit_id, self.supply_gen[player]) + if dead_supply_gen: + self.supply_gen[player].remove(dead_supply_gen[0]) + total_supply_gen = sum([x[0] for x in self.supply_gen[player]]) + replay.players[player-1].current_food_made[event.second] = total_supply_gen + print("Second", event.second, "Killed", event.unit.name,"SUPPLY",replay.players[player-1].current_food_made[event.second]) + + def handleInitGame(self, event, replay): + ## This dictionary contains te supply of every unit + self.unit_name_to_supply = { "Drone":1,"Zergling":1,"Baneling":1,\ + "Queen":2,\ + "SCV":1,"Marine":1,"Marauder":2,"SiegeTank":2} + self.supply_gen_unit = {"Overlord":8, "SupplyDepot":8,"Pylon":8} + ## This list contains a turple of the units supply and unit ID. + self.units_alive = dict() + self.supply_gen = dict() + for player in replay.players: + self.supply_gen[player.pid] = list() + self.units_alive[player.pid] = list() + player.current_food_used = defaultdict(int) + player.current_food_made = defaultdict(int) + player.time_supply_capped = int() + + def handleUnitInitEvent(self,event,replay): + print ("Init",event.unit_type_name, event.unit_id) + self.add_to_units_alive(event,replay) + + def handleUnitBornEvent(self,event,replay): + print ("Born",event.unit_type_name,event.unit_id) + self.add_to_units_alive(event,replay) + + def handleUnitDiedEvent(self,event,replay): + if event.unit.name not in self.unit_name_to_supply: + return + self.remove_from_units_alive(event,replay) + + def handleEndGame(self, event, replay): + pass From dc824ca132461da5c91211a0b72e3bfb25308716 Mon Sep 17 00:00:00 2001 From: jonomon Date: Wed, 31 Jul 2013 13:03:39 -0400 Subject: [PATCH 3/8] Added Creep Tracker Class --- sc2reader/engine/plugins/creeptracker.py | 40 +++ sc2reader/engine/plugins/creeptrackerClass.py | 238 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 sc2reader/engine/plugins/creeptracker.py create mode 100644 sc2reader/engine/plugins/creeptrackerClass.py diff --git a/sc2reader/engine/plugins/creeptracker.py b/sc2reader/engine/plugins/creeptracker.py new file mode 100644 index 00000000..e70efea5 --- /dev/null +++ b/sc2reader/engine/plugins/creeptracker.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, print_function, unicode_literals, division + +from collections import defaultdict +from sc2reader.engine.plugins.creeptrackerClass import creep_tracker + +class CreepTracker(object): + ''' + The Creep tracker populates player.max_creep_spread and + player.creep_spread by minute + This uses the creep_tracker class to calculate the features + ''' + def handleInitGame(self, event, replay): + try: + replay.tracker_events + except AttributeError: + print("Replay does not have tracker events") + return + try: + replay.map.minimap + except AttributeError: + print("Map was not loaded") + return + self.creepTracker = creep_tracker(replay) + for player in replay.players: + self.creepTracker.init_cgu_lists(player.pid) + + def handleEvent(self, event, replay): + self.creepTracker.add_event(event) + + def handleEndGame(self, event, replay): + for player_id in replay.player: + self.creepTracker.reduce_cgu_per_minute(player_id) + for player in replay.players: + player.creep_spread_by_minute = self.creepTracker.get_creep_spread_area(player.pid) + for player in replay.players: + if player.creep_spread_by_minute: + player.max_creep_spread = max(player.creep_spread_by_minute.items(),key=lambda x:x[1]) + else: + player.max_creep_spread =0 diff --git a/sc2reader/engine/plugins/creeptrackerClass.py b/sc2reader/engine/plugins/creeptrackerClass.py new file mode 100644 index 00000000..cf69e837 --- /dev/null +++ b/sc2reader/engine/plugins/creeptrackerClass.py @@ -0,0 +1,238 @@ +from __future__ import absolute_import + +from itertools import dropwhile +from sets import Set +from Image import open as PIL_open +from Image import ANTIALIAS +from StringIO import StringIO +from collections import defaultdict + +class creep_tracker(): + def __init__(self,replay): + #if the debug option is selected, minimaps will be printed to a file + ##and a stringIO containing the minimap image will be saved for + ##every minite in the game and the minimap with creep highlighted + ## will be printed out. + self.debug = replay.opt.debug + ##This list contains creep spread area for each player + self.creep_spread_by_minute = dict() + ## this list contains a minimap highlighted with creep spread for each player + if self.debug: + self.creep_spread_image_by_minute = dict() + ## This list contains all the active cgus in every time frame + self.creep_gen_units = dict() + ## Thist list corresponds to creep_gen_units storing the time of each CGU + self.creep_gen_units_times= dict() + ## convert all possible cgu radii into a sets of coordinates centred around the origin, + ## in order to use this with the CGUs, the centre point will be + ## subtracted with coordinates of cgus created in game + self.unit_name_to_radius = {'CreepTumor': 10, "Hatchery":8,\ + "NydusCanal": 5 } + self.radius_to_coordinates= dict() + for x in self.unit_name_to_radius: + self.radius_to_coordinates[self.unit_name_to_radius[x]] =\ + self.radius_to_map_positions(self.unit_name_to_radius[x]) + + #Get map information + replayMap = replay.map + # extract image from replay package + mapsio = StringIO(replayMap.minimap) + im = PIL_open(mapsio) + mapinfo = replay.map.archive.read_file('MapInfo') + ##remove black box around minimap + cropped = im.crop(im.getbbox()) + cropsize = cropped.size + self.map_height = 100.0 + # resize height to MAPHEIGHT, and compute new width that + # would preserve aspect ratio + self.map_width = int(cropsize[0] * (float(self.map_height) / cropsize[1])) + self.mapSize =self.map_height * self.map_width + ## the following parameters are only needed if minimaps have to be printed + minimapSize = ( self.map_width,int(self.map_height) ) + self.minimap_image = cropped.resize(minimapSize, ANTIALIAS) + mapOffsetX, mapOffsetY = self.cameraOffset(mapinfo) + mapCenter = [mapOffsetX + cropsize[0]/2.0, mapOffsetY + cropsize[1]/2.0] + # this is the center of the minimap image, in pixel coordinates + imageCenter = [(self.map_width/2), self.map_height/2] + # this is the scaling factor to go from the SC2 coordinate + # system to pixel coordinates + self.image_scale = float(self.map_height) / cropsize[0] + self.transX =imageCenter[0] + self.image_scale * (mapCenter[0]) + self.transY = imageCenter[1] + self.image_scale * (mapCenter[1]) + + def radius_to_map_positions(self,radius): + ## this function converts all radius into map coordinates + ## centred around the origin that the creep can exist + ## the cgu_radius_to_map_position function will simply + ## substract every coordinate with the centre point of the tumour + output_coordinates = list() + # Sample a square area using the radius + for x in range (-radius,radius): + for y in range (-radius, radius): + if (x**2 + y**2) <= (radius * radius): + output_coordinates.append((x,y)) + return output_coordinates + + def init_cgu_lists(self, player_id): + self.creep_spread_by_minute[player_id] = defaultdict(int) + if self.debug: + self.creep_spread_image_by_minute[player_id] = defaultdict(StringIO) + self.creep_gen_units[player_id] = list() + self.creep_gen_units_times[player_id] = list() + + def add_to_list(self,player_id,unit_id,unit_location,unit_type,event_time): + # This functions adds a new time frame to creep_generating_units_list + # Each time frame contains a list of all CGUs that are alive + length_cgu_list = len(self.creep_gen_units[player_id]) + if length_cgu_list==0: + self.creep_gen_units[player_id].append([(unit_id, unit_location,unit_type)]) + self.creep_gen_units_times[player_id].append(event_time) + else: + #if the list is not empty, take the previous time frame, + # add the new CGU to it and append it as a new time frame + previous_list = self.creep_gen_units[player_id][length_cgu_list-1][:] + previous_list.append((unit_id, unit_location,unit_type)) + self.creep_gen_units[player_id].append(previous_list) + self.creep_gen_units_times[player_id].append(event_time) + + def remove_from_list(self,unit_id,time_frame): + ## This function searches is given a unit ID for every unit who died + ## the unit id will be searched in cgu_gen_units for matches + ## if there are any, that unit will be removed from active CGUs + ## and appended as a new time frame + for player_id in self.creep_gen_units: + length_cgu_list = len(self.creep_gen_units[player_id]) + if length_cgu_list ==0: + break + cgu_per_player = self.creep_gen_units[player_id]\ + [length_cgu_list-1] + creep_generating_died = dropwhile(lambda x: x[0] != \ + unit_id, cgu_per_player) + for creep_generating_died_unit in creep_generating_died: + cgu_per_player.remove(creep_generating_died_unit) + self.creep_gen_units[player_id].append(cgu_per_player) + self.creep_gen_units_times[player_id].append(time_frame) + + def add_event(self,event): + # Search things that generate creep + # Tumor, hatcheries, nydus + if event.name == "UnitBornEvent": + if event.unit_type_name== "Hatchery": + self.add_to_list(event.control_pid, event.unit_id,\ + (event.x,event.y),event.unit_type_name,event.second) + if event.name == "UnitInitEvent": + units = ["CreepTumor", "Hatchery","NydusCanal"] + if event.unit_type_name in units: + self.add_to_list(event.control_pid,event.unit_id,\ + (event.x, event.y), event.unit_type_name,event.second) + # Removes creep generating units that were destroyed + if event.name == "UnitDiedEvent": + self.remove_from_list(event.unit_id,event.second) + + def reduce_cgu_per_minute(self,player_id): + #the creep_gen_units_lists contains every single time frame + #where a CGU is added, + #To reduce the calculations required, the time frame containing + #the most cgus every minute will be used to represent that minute + last_minute_found = 0 + cgu_per_player_new = list() + cgu_time_per_player_new = list() + cgu_last_minute_list = list() + for index,cgu_time in enumerate(self.creep_gen_units_times[player_id]): + cgu_last_minute_list.append(self.creep_gen_units[player_id][index]) + if (cgu_time/60) ==0: + cgu_per_player_new.append(self.creep_gen_units[player_id][0]) + cgu_time_per_player_new.append(0) + cgu_last_minute_list = list() + if (cgu_time/60)>last_minute_found: + cgu_max_in_min = max(cgu_last_minute_list,key = len) + cgu_per_player_new.append(cgu_max_in_min) + cgu_max_in_min_index = self.creep_gen_units[player_id].index(cgu_max_in_min) + cgu_time_per_player_new.append(self.creep_gen_units_times[player_id][cgu_max_in_min_index]) + last_minute_found = cgu_time/60 + cgu_last_minute_list=list() + + self.creep_gen_units[player_id] = cgu_per_player_new + self.creep_gen_units_times[player_id] = cgu_time_per_player_new + + def get_creep_spread_area(self,player_id): + ## iterates through all cgus and and calculate the area + for index,cgu_per_player in enumerate(self.creep_gen_units[player_id]): + # convert cgu list into centre of circles and radius + cgu_radius = map(lambda x: (x[1], self.unit_name_to_radius[x[2]]),\ + cgu_per_player) + # convert event coords to minimap coords + cgu_radius = self.convert_cgu_radius_event_to_map_coord(cgu_radius) + creep_area_positions = self.cgu_radius_to_map_positions(cgu_radius,self.radius_to_coordinates) + cgu_last_event_time = self.creep_gen_units_times[player_id][index]/60 + if self.debug: + self.print_image(creep_area_positions,player_id,cgu_last_event_time) + creep_area = len(creep_area_positions) + self.creep_spread_by_minute[player_id][cgu_last_event_time]=\ + float(creep_area)/self.mapSize*100 + return self.creep_spread_by_minute[player_id] + + def cgu_radius_to_map_positions(self,cgu_radius,radius_to_coordinates): + ## This function uses the output of radius_to_map_positions + total_points_on_map = Set() + if len(cgu_radius)==0: + return [] + for cgu in cgu_radius: + point = cgu[0] + radius = cgu[1] + ## subtract all radius_to_coordinates with centre of + ## cgu radius to change centre of circle + cgu_map_position = map( lambda x:(x[0]+point[0],x[1]+point[1])\ + ,self.radius_to_coordinates[radius]) + total_points_on_map= total_points_on_map | Set(cgu_map_position) + return total_points_on_map + + def print_image(self,total_points_on_map,player_id,time_stamp): + minimap_copy = self.minimap_image.copy() + # Convert all creeped points to white + for points in total_points_on_map: + x = points[0] + y = points[1] + x,y = self.check_image_pixel_within_boundary(x,y) + minimap_copy.putpixel((x,y) , (255, 255, 255)) + creeped_image = minimap_copy + # write creeped minimap image to a string as a png + creeped_imageIO = StringIO() + creeped_image.save(creeped_imageIO, "png") + self.creep_spread_image_by_minute[player_id][time_stamp]=creeped_imageIO + ##debug for print out the images + f = open(str(player_id)+'image'+str(time_stamp)+'.png','w') + f.write(creeped_imageIO.getvalue()) + creeped_imageIO.close() + f.close() + + def check_image_pixel_within_boundary(self,pointX, pointY): + pointX = 0 if pointX <0 else pointX + pointY=0 if pointY <0 else pointY + # put a minus 1 to make sure the pixel is not directly on the edge + pointX = int(self.map_width-1 if pointX >= self.map_width else pointX) + pointY = int(self.map_height-1 if pointY >= self.map_height else pointY) + return pointX,pointY + + def convert_cgu_radius_event_to_map_coord(self,cgu_radius): + cgu_radius_new = list() + for cgu in cgu_radius: + x = cgu[0][0] + y = cgu[0][1] + (x,y) = self.convert_event_coord_to_map_coord(x,y) + cgu = ((x,y),cgu[1]) + cgu_radius_new.append(cgu) + return cgu_radius_new + + def convert_event_coord_to_map_coord(self,x,y): + imageX = int(self.map_height - self.transX + self.image_scale * x) + imageY = int(self.transY - self.image_scale * y) + return imageX, imageY + + def cameraOffset(self,mapinfo): + fogOfWarStart = mapinfo.find('Dark') + textureEnd = mapinfo[fogOfWarStart + 5:-1].find('\0') + rest = mapinfo[fogOfWarStart + 5 + textureEnd + 1: -1] + return ord(rest[0]), ord(rest[4]) + + From 3d1bd6452e3a1bdb32d810f1b4f53ca94eb9f7de Mon Sep 17 00:00:00 2001 From: jonomon Date: Wed, 31 Jul 2013 22:04:36 -0400 Subject: [PATCH 4/8] added new creepTracker, supplyTracker and tests --- sc2reader/engine/plugins/__init__.py | 2 + sc2reader/engine/plugins/creeptracker.py | 242 +++++++++++++++++- sc2reader/engine/plugins/supply.py | 82 ++++-- sc2reader/factories/plugins/replay.py | 233 ----------------- .../2.0.8.25605/ggtracker_3621322.SC2Replay | Bin 0 -> 46503 bytes .../2.0.8.25605/ggtracker_3621402.SC2Replay | Bin 0 -> 79299 bytes .../2.0.8.25605/ggtracker_3663861.SC2Replay | Bin 0 -> 23933 bytes .../2.0.8.25605/ggtracker_3695400.SC2Replay | Bin 0 -> 41347 bytes test_replays/test_all.py | 28 +- 9 files changed, 318 insertions(+), 269 deletions(-) create mode 100644 test_replays/2.0.8.25605/ggtracker_3621322.SC2Replay create mode 100644 test_replays/2.0.8.25605/ggtracker_3621402.SC2Replay create mode 100644 test_replays/2.0.8.25605/ggtracker_3663861.SC2Replay create mode 100644 test_replays/2.0.8.25605/ggtracker_3695400.SC2Replay diff --git a/sc2reader/engine/plugins/__init__.py b/sc2reader/engine/plugins/__init__.py index d506b69b..be6d155f 100644 --- a/sc2reader/engine/plugins/__init__.py +++ b/sc2reader/engine/plugins/__init__.py @@ -5,3 +5,5 @@ from sc2reader.engine.plugins.selection import SelectionTracker from sc2reader.engine.plugins.context import ContextLoader from sc2reader.engine.plugins.gameheart import GameHeartNormalizer +from sc2reader.engine.plugins.supply import SupplyTracker +from sc2reader.engine.plugins.creeptracker import CreepTracker diff --git a/sc2reader/engine/plugins/creeptracker.py b/sc2reader/engine/plugins/creeptracker.py index e70efea5..bda1c1da 100644 --- a/sc2reader/engine/plugins/creeptracker.py +++ b/sc2reader/engine/plugins/creeptracker.py @@ -1,9 +1,14 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals, division +from itertools import dropwhile +from sets import Set +from Image import open as PIL_open +from Image import ANTIALIAS +from StringIO import StringIO from collections import defaultdict -from sc2reader.engine.plugins.creeptrackerClass import creep_tracker +# The creep tracker plugin class CreepTracker(object): ''' The Creep tracker populates player.max_creep_spread and @@ -11,22 +16,26 @@ class CreepTracker(object): This uses the creep_tracker class to calculate the features ''' def handleInitGame(self, event, replay): - try: - replay.tracker_events - except AttributeError: - print("Replay does not have tracker events") - return - try: - replay.map.minimap - except AttributeError: - print("Map was not loaded") + if len( replay.tracker_events) ==0 : return + if replay.map is None: + replay.load_map() self.creepTracker = creep_tracker(replay) for player in replay.players: self.creepTracker.init_cgu_lists(player.pid) - def handleEvent(self, event, replay): - self.creepTracker.add_event(event) + def handleUnitDiedEvent(self, event, replay): + self.creepTracker.remove_from_list(event.unit_id,event.second) + + def handleUnitInitEvent(self,event,replay): + if event.unit_type_name in ["CreepTumor", "Hatchery","NydusCanal"] : + self.creepTracker.add_to_list(event.control_pid,event.unit_id,\ + (event.x, event.y), event.unit_type_name,event.second) + + def handleUnitBornEvent(self,event,replay): + if event.unit_type_name== "Hatchery": + self.creepTracker.add_to_list(event.control_pid, event.unit_id,\ + (event.x,event.y),event.unit_type_name,event.second) def handleEndGame(self, event, replay): for player_id in replay.player: @@ -38,3 +47,212 @@ def handleEndGame(self, event, replay): player.max_creep_spread = max(player.creep_spread_by_minute.items(),key=lambda x:x[1]) else: player.max_creep_spread =0 + +## The class used to used to calculate the creep spread +class creep_tracker(): + def __init__(self,replay): + #if the debug option is selected, minimaps will be printed to a file + ##and a stringIO containing the minimap image will be saved for + ##every minite in the game and the minimap with creep highlighted + ## will be printed out. + self.debug = replay.opt.debug + ##This list contains creep spread area for each player + self.creep_spread_by_minute = dict() + ## this list contains a minimap highlighted with creep spread for each player + if self.debug: + self.creep_spread_image_by_minute = dict() + ## This list contains all the active cgus in every time frame + self.creep_gen_units = dict() + ## Thist list corresponds to creep_gen_units storing the time of each CGU + self.creep_gen_units_times= dict() + ## convert all possible cgu radii into a sets of coordinates centred around the origin, + ## in order to use this with the CGUs, the centre point will be + ## subtracted with coordinates of cgus created in game + self.unit_name_to_radius={'CreepTumor': 10,"Hatchery":8,"NydusCanal": 5} + self.radius_to_coordinates= dict() + for x in self.unit_name_to_radius: + self.radius_to_coordinates[self.unit_name_to_radius[x]] =\ + self.radius_to_map_positions(self.unit_name_to_radius[x]) + + #Get map information + replayMap = replay.map + # extract image from replay package + mapsio = StringIO(replayMap.minimap) + im = PIL_open(mapsio) + ##remove black box around minimap + cropped = im.crop(im.getbbox()) + cropsize = cropped.size + self.map_height = 100.0 + # resize height to MAPHEIGHT, and compute new width that + # would preserve aspect ratio + self.map_width = int(cropsize[0] * (float(self.map_height) / cropsize[1])) + self.mapSize =self.map_height * self.map_width + ## the following parameters are only needed if minimaps have to be printed + minimapSize = ( self.map_width,int(self.map_height) ) + self.minimap_image = cropped.resize(minimapSize, ANTIALIAS) + mapOffsetX= replayMap.map_info.camera_left + mapOffsetY = replayMap.map_info.camera_bottom + mapCenter = [mapOffsetX + cropsize[0]/2.0, mapOffsetY + cropsize[1]/2.0] + # this is the center of the minimap image, in pixel coordinates + imageCenter = [(self.map_width/2), self.map_height/2] + # this is the scaling factor to go from the SC2 coordinate + # system to pixel coordinates + self.image_scale = float(self.map_height) / cropsize[0] + self.transX =imageCenter[0] + self.image_scale * (mapCenter[0]) + self.transY = imageCenter[1] + self.image_scale * (mapCenter[1]) + + def radius_to_map_positions(self,radius): + ## this function converts all radius into map coordinates + ## centred around the origin that the creep can exist + ## the cgu_radius_to_map_position function will simply + ## substract every coordinate with the centre point of the tumour + output_coordinates = list() + # Sample a square area using the radius + for x in range (-radius,radius): + for y in range (-radius, radius): + if (x**2 + y**2) <= (radius * radius): + output_coordinates.append((x,y)) + return output_coordinates + + def init_cgu_lists(self, player_id): + self.creep_spread_by_minute[player_id] = defaultdict(int) + if self.debug: + self.creep_spread_image_by_minute[player_id] = defaultdict(StringIO) + self.creep_gen_units[player_id] = list() + self.creep_gen_units_times[player_id] = list() + + def add_to_list(self,player_id,unit_id,unit_location,unit_type,event_time): + # This functions adds a new time frame to creep_generating_units_list + # Each time frame contains a list of all CGUs that are alive + length_cgu_list = len(self.creep_gen_units[player_id]) + if length_cgu_list==0: + self.creep_gen_units[player_id].append([(unit_id, unit_location,unit_type)]) + self.creep_gen_units_times[player_id].append(event_time) + else: + #if the list is not empty, take the previous time frame, + # add the new CGU to it and append it as a new time frame + previous_list = self.creep_gen_units[player_id][length_cgu_list-1][:] + previous_list.append((unit_id, unit_location,unit_type)) + self.creep_gen_units[player_id].append(previous_list) + self.creep_gen_units_times[player_id].append(event_time) + + def remove_from_list(self,unit_id,time_frame): + ## This function searches is given a unit ID for every unit who died + ## the unit id will be searched in cgu_gen_units for matches + ## if there are any, that unit will be removed from active CGUs + ## and appended as a new time frame + for player_id in self.creep_gen_units: + length_cgu_list = len(self.creep_gen_units[player_id]) + if length_cgu_list ==0: + break + cgu_per_player = self.creep_gen_units[player_id]\ + [length_cgu_list-1] + creep_generating_died = dropwhile(lambda x: x[0] != \ + unit_id, cgu_per_player) + for creep_generating_died_unit in creep_generating_died: + cgu_per_player.remove(creep_generating_died_unit) + self.creep_gen_units[player_id].append(cgu_per_player) + self.creep_gen_units_times[player_id].append(time_frame) + + def reduce_cgu_per_minute(self,player_id): + #the creep_gen_units_lists contains every single time frame + #where a CGU is added, + #To reduce the calculations required, the time frame containing + #the most cgus every minute will be used to represent that minute + last_minute_found = 0 + cgu_per_player_new = list() + cgu_time_per_player_new = list() + cgu_last_minute_list = list() + for index,cgu_time in enumerate(self.creep_gen_units_times[player_id]): + cgu_last_minute_list.append(self.creep_gen_units[player_id][index]) + if (cgu_time/60) ==0: + cgu_per_player_new.append(self.creep_gen_units[player_id][0]) + cgu_time_per_player_new.append(0) + cgu_last_minute_list = list() + if (cgu_time/60)>last_minute_found: + cgu_max_in_min = max(cgu_last_minute_list,key = len) + cgu_per_player_new.append(cgu_max_in_min) + cgu_max_in_min_index = self.creep_gen_units[player_id].index(cgu_max_in_min) + cgu_time_per_player_new.append(self.creep_gen_units_times[player_id][cgu_max_in_min_index]) + last_minute_found = cgu_time/60 + cgu_last_minute_list=list() + + self.creep_gen_units[player_id] = cgu_per_player_new + self.creep_gen_units_times[player_id] = cgu_time_per_player_new + + def get_creep_spread_area(self,player_id): + ## iterates through all cgus and and calculate the area + for index,cgu_per_player in enumerate(self.creep_gen_units[player_id]): + # convert cgu list into centre of circles and radius + cgu_radius = map(lambda x: (x[1], self.unit_name_to_radius[x[2]]),\ + cgu_per_player) + # convert event coords to minimap coords + cgu_radius = self.convert_cgu_radius_event_to_map_coord(cgu_radius) + creep_area_positions = self.cgu_radius_to_map_positions(cgu_radius,self.radius_to_coordinates) + cgu_last_event_time = self.creep_gen_units_times[player_id][index]/60 + if self.debug: + self.print_image(creep_area_positions,player_id,cgu_last_event_time) + creep_area = len(creep_area_positions) + self.creep_spread_by_minute[player_id][cgu_last_event_time]=\ + float(creep_area)/self.mapSize*100 + return self.creep_spread_by_minute[player_id] + + def cgu_radius_to_map_positions(self,cgu_radius,radius_to_coordinates): + ## This function uses the output of radius_to_map_positions + total_points_on_map = Set() + if len(cgu_radius)==0: + return [] + for cgu in cgu_radius: + point = cgu[0] + radius = cgu[1] + ## subtract all radius_to_coordinates with centre of + ## cgu radius to change centre of circle + cgu_map_position = map( lambda x:(x[0]+point[0],x[1]+point[1])\ + ,self.radius_to_coordinates[radius]) + total_points_on_map= total_points_on_map | Set(cgu_map_position) + return total_points_on_map + + def print_image(self,total_points_on_map,player_id,time_stamp): + minimap_copy = self.minimap_image.copy() + # Convert all creeped points to white + for points in total_points_on_map: + x = points[0] + y = points[1] + x,y = self.check_image_pixel_within_boundary(x,y) + minimap_copy.putpixel((x,y) , (255, 255, 255)) + creeped_image = minimap_copy + # write creeped minimap image to a string as a png + creeped_imageIO = StringIO() + creeped_image.save(creeped_imageIO, "png") + self.creep_spread_image_by_minute[player_id][time_stamp]=creeped_imageIO + ##debug for print out the images + f = open(str(player_id)+'image'+str(time_stamp)+'.png','w') + f.write(creeped_imageIO.getvalue()) + creeped_imageIO.close() + f.close() + + def check_image_pixel_within_boundary(self,pointX, pointY): + pointX = 0 if pointX <0 else pointX + pointY=0 if pointY <0 else pointY + # put a minus 1 to make sure the pixel is not directly on the edge + pointX = int(self.map_width-1 if pointX >= self.map_width else pointX) + pointY = int(self.map_height-1 if pointY >= self.map_height else pointY) + return pointX,pointY + + def convert_cgu_radius_event_to_map_coord(self,cgu_radius): + cgu_radius_new = list() + for cgu in cgu_radius: + x = cgu[0][0] + y = cgu[0][1] + (x,y) = self.convert_event_coord_to_map_coord(x,y) + cgu = ((x,y),cgu[1]) + cgu_radius_new.append(cgu) + return cgu_radius_new + + def convert_event_coord_to_map_coord(self,x,y): + imageX = int(self.map_height - self.transX + self.image_scale * x) + imageY = int(self.transY - self.image_scale * y) + return imageX, imageY + + + diff --git a/sc2reader/engine/plugins/supply.py b/sc2reader/engine/plugins/supply.py index 535d190c..394a3a64 100644 --- a/sc2reader/engine/plugins/supply.py +++ b/sc2reader/engine/plugins/supply.py @@ -5,35 +5,44 @@ class SupplyTracker(object): def add_to_units_alive(self,event,replay): - try: ## see if the unit takes supply - supplyCount = self.unit_name_to_supply[event.unit_type_name] + unit_name = event.unit_type_name + if unit_name in self.unit_name_to_supply: + supplyCount = self.unit_name_to_supply[event.unit_type_name][0] + buildTime = self.unit_name_to_supply[event.unit_type_name][1] + time_built = event.second - buildTime + time_built= 0 if time_built < 0 else time_built new_unit = (supplyCount, event.unit_id) self.units_alive[event.control_pid].append(new_unit) total_supply = sum([x[0] for x in self.units_alive[event.control_pid]]) - replay.players[event.control_pid-1].current_food_used[event.second]= total_supply - print("SECOND",event.second, "Player",replay.players[event.control_pid-1],"SUPPLY",replay.players[event.control_pid-1].current_food_used[event.second]) - except KeyError: - try: ## see if the unit provides supply - supply_gen_count = (self.supply_gen_unit[event.unit_type_name]) - supply_gen_unit = (supply_gen_count,event.unit_id) - self.supply_gen[event.control_pid].append(supply_gen_unit) - total_supply_gen = sum([x[0] for x in self.units_alive[event.control_pid]]) - replay.players[event.control_pid-1].current_food_made[event.second]= total_supply_gen - except KeyError: - print("Unit name {0} does not exist".format(event.unit_type_name)) - return + replay.players[event.control_pid-1].current_food_used[time_built]= total_supply + print("Second",time_built,replay.players[event.control_pid-1],"SUPPLY",replay.players[event.control_pid-1].current_food_used[time_built]) + + elif unit_name in self.supply_gen_unit: + ## see if the unit provides supply + supply_gen_count = self.supply_gen_unit[event.unit_type_name][0] + build_time = self.supply_gen_unit[event.unit_type_name][1] + time_complete = event.second+ build_time + supply_gen_unit = (supply_gen_count,event.unit_id) + self.supply_gen[event.control_pid].append(supply_gen_unit) + total_supply_gen = sum([x[0] for x in self.supply_gen[event.control_pid]]) + replay.players[event.control_pid-1].current_food_made[time_complete]= total_supply_gen + print("Second",time_complete, replay.players[event.control_pid-1],"Built",replay.players[event.control_pid-1].current_food_made[time_complete]) + else: + print("Unit name {0} does not exist".format(event.unit_type_name)) + return def remove_from_units_alive(self,event,replay): died_unit_id = event.unit_id for player in replay.player: - dead_unit = filter(lambda x:x[1]==died_unit_id, self.units_alive[player]) + dead_unit = filter(lambda x:x[1]==died_unit_id,self.units_alive[player]) if dead_unit: self.units_alive[player].remove(dead_unit[0]) total_supply = sum([x[0] for x in self.units_alive[player]]) + replay.players[player-1].current_food_used[event.second] = total_supply print("Second", event.second, "Killed", event.unit.name,"SUPPLY",replay.players[player-1].current_food_used[event.second]) - dead_supply_gen = filter(lambda x:x[1]==died_unit_id, self.supply_gen[player]) + dead_supply_gen=filter(lambda x:x[1]==died_unit_id, self.supply_gen[player]) if dead_supply_gen: self.supply_gen[player].remove(dead_supply_gen[0]) total_supply_gen = sum([x[0] for x in self.supply_gen[player]]) @@ -42,12 +51,37 @@ def remove_from_units_alive(self,event,replay): def handleInitGame(self, event, replay): ## This dictionary contains te supply of every unit - self.unit_name_to_supply = { "Drone":1,"Zergling":1,"Baneling":1,\ - "Queen":2,\ - "SCV":1,"Marine":1,"Marauder":2,"SiegeTank":2} - self.supply_gen_unit = {"Overlord":8, "SupplyDepot":8,"Pylon":8} + self.unit_name_to_supply = { + #Zerg + "Drone":(1,17),"Zergling":(1,25),"Baneling":(0,20),"Queen":(2,50),\ + "Hydralisk":(2,33),"Roach":(2,27),"Infestor":(2,50),"Mutalisk":(2,33),\ + "Corruptor":(2,40),"Utralisk":(6,55),"Broodlord":(2,34),\ + "SwarmHost":(3,40), "Viper":(3,40),\ + #Terran + "SCV":(1,17),"Marine":(1,25),"Marauder":(2,30),"SiegeTank":(2,45),\ + "Reaper":(1,45),"Ghost":(2,40),"Hellion":(2,30),"Thor":(6,60),\ + "Viking":(2,42),"Medivac":(2,42),"Raven":(2,60), "Banshee":(3,60),\ + "Battlecruiser":(6,90), "Hellbat":(2,30),"WidowMine":(2,40),\ + #Protoss + "Probe":(1,17),"Zealot":(2,38),"Stalker":(2,42),"Sentry":(2,42),\ + "Observer":(1,30), "Immortal":(4,55),"WarpPrism":(2,50),\ + "Colossus":(6,75), "Phoenix":(2,35),"VoidRay":(4,60), \ + "HighTemplar":(2,55),"DarkTemplar":(2,55), "Archon":(4,12),\ + "Carrier":(6,120), "Mothership":(6,100),"MothershipCore":(2,30),\ + "Oracle":(3,50),"Tempest":(4,60)} + + self.supply_gen_unit = { + #overlord build time is zero because event for units are made when + # it is born not when it's created + "Overlord":(8,0),"Hatchery":(2,100), \ + "SupplyDepot":(8,30),"CommandCenter":(11,100),\ + "Pylon":(8,25),"Nexus":(10,100) + } ## This list contains a turple of the units supply and unit ID. + ## the purpose of the list is to know which user owns which unit + ## so that when a unit dies, that self.units_alive = dict() + ## self.supply_gen = dict() for player in replay.players: self.supply_gen[player.pid] = list() @@ -57,11 +91,11 @@ def handleInitGame(self, event, replay): player.time_supply_capped = int() def handleUnitInitEvent(self,event,replay): - print ("Init",event.unit_type_name, event.unit_id) + #print ("Init",event.unit_type_name, event.unit_id) self.add_to_units_alive(event,replay) def handleUnitBornEvent(self,event,replay): - print ("Born",event.unit_type_name,event.unit_id) + #print ("Born",event.unit_type_name,event.unit_id) self.add_to_units_alive(event,replay) def handleUnitDiedEvent(self,event,replay): @@ -70,4 +104,6 @@ def handleUnitDiedEvent(self,event,replay): self.remove_from_units_alive(event,replay) def handleEndGame(self, event, replay): - pass + for player in replay.players: + player.current_food_used = sorted(player.current_food_used.iteritems(), key=lambda x: x[0]) + player.current_food_made = sorted(player.current_food_made.iteritems(), key=lambda x:x[0]) diff --git a/sc2reader/factories/plugins/replay.py b/sc2reader/factories/plugins/replay.py index f1c3d38b..8267dff3 100644 --- a/sc2reader/factories/plugins/replay.py +++ b/sc2reader/factories/plugins/replay.py @@ -120,239 +120,6 @@ def APMTracker(replay): return replay -@plugin -def CreepTracker(replay): - from itertools import izip_longest, dropwhile - from random import random - from math import sqrt, pi - - def add_to_list(control_pid,unit_id,unit_location,\ - unit_type,event_time, creep_generating_units_list): - length_cgu_list = len(creep_generating_units_list[control_pid]) - if length_cgu_list==0: - creep_generating_units_list[control_pid].append([(unit_id, unit_location,unit_type,event_time)]) - else: - previous_list = creep_generating_units_list[control_pid][length_cgu_list-1][:] - previous_list.append((unit_id, unit_location,unit_type,event_time)) - creep_generating_units_list[control_pid].append(previous_list) - - def in_circles(point_x,point_y,cgu_radius): - for cgu in cgu_radius: - circle_x = cgu[0][0] - circle_y = cgu[0][1] - radius = cgu[1] - distance = (circle_x-point_x)**2 + (circle_y-point_y)**2 - if distance < (radius*radius): - return 1 - return 0 - - def distance(point1,point2): - distance = (point1[0]-point2[0])**2 + (point1[1]-point2[1])**2 - return distance - - def calculate_area(cgu_radius): - if len(cgu_radius)==1: - print "Area Calculated",pi*(cgu_radius[0][1]**2) - return pi*(cgu_radius[0][1]**2) - - # from cgu_radius get a square which surrounds maximum - # possible area that the creep lies in - max_x = max(cgu_radius, key=lambda x: x[0][0]+x[1]) - max_y = max(cgu_radius, key=lambda x: x[0][1]+x[1]) - min_x = min(cgu_radius, key=lambda x: x[0][0] - x[1]) - min_y = min(cgu_radius, key=lambda x: x[0][1] - x[1]) - - max_x = max_x[0][0] + max_x[1] - max_y = max_y[0][1] + max_y[1] - min_x = min_x[0][0] - min_x[1] - min_y = min_y[0][1] - min_y[1] - - area = 0 - for x in range(min_x,max_x): - for y in range(min_y,max_y): - if in_circles(x,y,cgu_radius): - area+=1 - return area - - - def single_linkage_clustering(cgu_points, maxR,labels=0,cgu_length = 0): - inf = -1000 - if labels==0: - labels = [0 for x in cgu_points] - cgu_length = len(cgu_points) - if len(cgu_points) ==1: - return [0] - - # calculate distance array - distance_array = list() - for i in range (len(cgu_points)): - i_lengths = list() - for j in range(len(cgu_points)): - if i !=j: - if cgu_points[i][0] == inf and cgu_points [j][0] == inf: - i_lengths.append(-inf) - else: - i_lengths.append(distance(cgu_points[i], cgu_points[j])) - - distance_array.append(i_lengths) - - #Find closest point distance for each point - min_array = map(lambda x:min(x), distance_array) - - #combine 2 points with smallest distance - min_distance = min(min_array) - if min_distance < maxR: - point1 = min_array.index(min_distance) - point2 = min_array[point1+1:].index(min_distance)+point1+1 - #label each cgu points - current_label = max(labels)+1 if labels[point1] ==0 and\ - labels[point2] ==0 else max(labels[point1],labels[point2]) - labels[point1] = current_label - labels[point2] = current_label - labels.append(current_label) - - new_x = (cgu_points[point1][0] + cgu_points[point2][0])/2 - new_y = (cgu_points[point1][1] + cgu_points[point2][1])/2 - cgu_points[point1]=(inf,inf) - cgu_points[point2]=(inf,inf) - cgu_points.append((new_x,new_y)) - - labels = single_linkage_clustering(cgu_points,maxR,labels,cgu_length) - return labels[0:cgu_length] - else: - return_value = labels[0:cgu_length] - return return_value - - - #Get Map Size - mapinfo = replay.map.archive.read_file('MapInfo') - mapSizeX = ord(mapinfo[16]) - mapSizeY = ord(mapinfo[20]) - mapSize = mapSizeX * mapSizeX/100 - - creep_generating_units_list = dict() - - for player in replay.players: - player.creep_spread_by_minute = defaultdict(int) - player.max_creep_spread = int() - creep_generating_units_list[player.pid] = list() - try: - replay.tracker_events - except AttributeError: - print "Replay does not have tracker events" - return replay - - for tracker_event,game_event in izip_longest(replay.tracker_events,replay.game_events): - - # First search things that generate creep - # Tumor, hatcheries, nydus and overlords generating creep - - if tracker_event and tracker_event.name == "UnitInitEvent": - units = ["CreepTumor", "Hatchery","Nydus"] # check nydus name - if tracker_event.unit_type_name in units: - add_to_list(tracker_event.control_pid,tracker_event.unit_id,\ - (tracker_event.x, tracker_event.y), \ - tracker_event.unit_type_name,\ - tracker_event.second,\ - creep_generating_units_list) - - if game_event and game_event.name == "AbilityEvent": - - if game_event.ability_name == "GenerateCreep": - add_to_list(game_event.control_pid,game_event.unit_id,\ - (game_event.x, game_event.y), \ - game_event.unit_type_name,\ - game_event.second,\ - creep_generating_units_list) - - # # Removes creep generating units that were destroyed - if tracker_event and tracker_event.name == "UnitDiedEvent": - for player in creep_generating_units_list: - length_cgu_list = len(creep_generating_units_list[player]) - if length_cgu_list ==0: - break - cgu_per_player = creep_generating_units_list[player][length_cgu_list-1] - creep_generating_died = dropwhile(lambda x: x[0] != tracker_event.unit_id, \ - cgu_per_player) - for creep_generating_died_unit in creep_generating_died: - - cgu_per_player.remove(creep_generating_died_unit) - creep_generating_units_list[player].append(cgu_per_player) - - #reduce all events to last event in the minute - last_minute_found = 0 - for player in replay.player: - cgu_per_player_new = list() - for cgu_per_player in creep_generating_units_list[player]: - if len(cgu_per_player) ==0: - continue - cgu_last_event_time = cgu_per_player[-1][3] - - if (cgu_last_event_time/60)>last_minute_found: - last_minute_found = cgu_last_event_time/60 - cgu_per_player_new.append(cgu_per_player) - cgu_per_player = cgu_per_player_new - - - max_creep_spread=defaultdict() - for player in replay.player: - # convert cg u list into centre of circles and radius - unit_name_to_radius = {'CreepTumor': 15, "Hatchery":17,\ - "GenerateCreep": 10, "Nydus": 5 } - - max_creep_spread[player] = 0 - - for index,cgu_per_player in enumerate(creep_generating_units_list[player]): - - cgu_radius = map(lambda x: (x[1], unit_name_to_radius[x[2]]),\ - cgu_per_player) - cgu_points = map(lambda x: x[0],cgu_radius) - - if cgu_points: - labels = single_linkage_clustering(cgu_points,350) - else: - if index != 0: - replay.player[player].creep_spread_by_minute[cgu_last_event_time+1] = 0 - continue - - area = 0 - #if all labels 0 (all separate clusters) calculate it separately - if max(labels) ==0: - for cgu_radi in cgu_radius: - area+= pi * cgu_radi[1]**2 - - cgu_last_event_time = cgu_per_player[-1][3]/60 - replay.player[player].creep_spread_by_minute[cgu_last_event_time] = area/mapSize - continue - - count =0 - while True: - clusters = filter(lambda x : True if x[0] == count else\ - False , zip(labels,cgu_radius) ) - - cgu_clusters = map(lambda x:x[1], clusters) - if count==0: - for cgu_radi in cgu_clusters: - area+= pi * cgu_radi[1]**2 - count+=1 - continue - if len(clusters) ==0: - break - count+=1 - area += calculate_area(cgu_clusters) - cgu_last_event_time = cgu_per_player[-1][3]/60 - replay.player[player].creep_spread_by_minute[cgu_last_event_time] = area/mapSize - - if area>max_creep_spread[player]: - max_creep_spread[player] =area - - - for player in replay.player: - replay.player[player].max_creep_spread = max_creep_spread[player]/mapSize - - return replay - - @plugin def SelectionTracker(replay): debug = replay.opt.debug diff --git a/test_replays/2.0.8.25605/ggtracker_3621322.SC2Replay b/test_replays/2.0.8.25605/ggtracker_3621322.SC2Replay new file mode 100644 index 0000000000000000000000000000000000000000..3ee9b5ea06a210bfc8267440c72c1e26079f7203 GIT binary patch literal 46503 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 E023sLOaK4? literal 0 HcmV?d00001 diff --git a/test_replays/2.0.8.25605/ggtracker_3663861.SC2Replay b/test_replays/2.0.8.25605/ggtracker_3663861.SC2Replay new file mode 100644 index 0000000000000000000000000000000000000000..ca6356de1811a667434790d39b1a4050ec464ce9 GIT binary patch literal 23933 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 S5jBir#eRPNxUxr}5CK3YH8*1yaTj9?H!@jS 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 + assert replay.player[player_id].creep_spread_by_minute + + + replay =factory.load_replay("test_replays/2.0.8.25605/ggtracker_3621402.SC2Replay",load_map= True,engine=pluginEngine,load_level=4) + assert replay.player[2].max_creep_spread == (14,22.95) + assert replay.player[2].creep_spread_by_minute[7] == 8.21 + assert replay.player[2].creep_spread_by_minute[13] == 22.42 + if __name__ == '__main__': unittest.main() From 39511d97bce80acc838270322028e571aff3bfec Mon Sep 17 00:00:00 2001 From: jonomon Date: Thu, 1 Aug 2013 10:12:13 -0400 Subject: [PATCH 5/8] added no tracker events handling --- sc2reader/engine/plugins/creeptracker.py | 6 + sc2reader/engine/plugins/creeptrackerClass.py | 238 ------------------ 2 files changed, 6 insertions(+), 238 deletions(-) delete mode 100644 sc2reader/engine/plugins/creeptrackerClass.py diff --git a/sc2reader/engine/plugins/creeptracker.py b/sc2reader/engine/plugins/creeptracker.py index bda1c1da..7f32976c 100644 --- a/sc2reader/engine/plugins/creeptracker.py +++ b/sc2reader/engine/plugins/creeptracker.py @@ -38,6 +38,11 @@ def handleUnitBornEvent(self,event,replay): (event.x,event.y),event.unit_type_name,event.second) def handleEndGame(self, event, replay): + if len( replay.tracker_events) ==0 : + for player in replay.players: + player.creep_spread_by_minute = 0 + player.max_creep_spread =0 + return for player_id in replay.player: self.creepTracker.reduce_cgu_per_minute(player_id) for player in replay.players: @@ -46,6 +51,7 @@ def handleEndGame(self, event, replay): if player.creep_spread_by_minute: player.max_creep_spread = max(player.creep_spread_by_minute.items(),key=lambda x:x[1]) else: + ## Else statement is for players with no creep spread(ie: not Z) player.max_creep_spread =0 ## The class used to used to calculate the creep spread diff --git a/sc2reader/engine/plugins/creeptrackerClass.py b/sc2reader/engine/plugins/creeptrackerClass.py deleted file mode 100644 index cf69e837..00000000 --- a/sc2reader/engine/plugins/creeptrackerClass.py +++ /dev/null @@ -1,238 +0,0 @@ -from __future__ import absolute_import - -from itertools import dropwhile -from sets import Set -from Image import open as PIL_open -from Image import ANTIALIAS -from StringIO import StringIO -from collections import defaultdict - -class creep_tracker(): - def __init__(self,replay): - #if the debug option is selected, minimaps will be printed to a file - ##and a stringIO containing the minimap image will be saved for - ##every minite in the game and the minimap with creep highlighted - ## will be printed out. - self.debug = replay.opt.debug - ##This list contains creep spread area for each player - self.creep_spread_by_minute = dict() - ## this list contains a minimap highlighted with creep spread for each player - if self.debug: - self.creep_spread_image_by_minute = dict() - ## This list contains all the active cgus in every time frame - self.creep_gen_units = dict() - ## Thist list corresponds to creep_gen_units storing the time of each CGU - self.creep_gen_units_times= dict() - ## convert all possible cgu radii into a sets of coordinates centred around the origin, - ## in order to use this with the CGUs, the centre point will be - ## subtracted with coordinates of cgus created in game - self.unit_name_to_radius = {'CreepTumor': 10, "Hatchery":8,\ - "NydusCanal": 5 } - self.radius_to_coordinates= dict() - for x in self.unit_name_to_radius: - self.radius_to_coordinates[self.unit_name_to_radius[x]] =\ - self.radius_to_map_positions(self.unit_name_to_radius[x]) - - #Get map information - replayMap = replay.map - # extract image from replay package - mapsio = StringIO(replayMap.minimap) - im = PIL_open(mapsio) - mapinfo = replay.map.archive.read_file('MapInfo') - ##remove black box around minimap - cropped = im.crop(im.getbbox()) - cropsize = cropped.size - self.map_height = 100.0 - # resize height to MAPHEIGHT, and compute new width that - # would preserve aspect ratio - self.map_width = int(cropsize[0] * (float(self.map_height) / cropsize[1])) - self.mapSize =self.map_height * self.map_width - ## the following parameters are only needed if minimaps have to be printed - minimapSize = ( self.map_width,int(self.map_height) ) - self.minimap_image = cropped.resize(minimapSize, ANTIALIAS) - mapOffsetX, mapOffsetY = self.cameraOffset(mapinfo) - mapCenter = [mapOffsetX + cropsize[0]/2.0, mapOffsetY + cropsize[1]/2.0] - # this is the center of the minimap image, in pixel coordinates - imageCenter = [(self.map_width/2), self.map_height/2] - # this is the scaling factor to go from the SC2 coordinate - # system to pixel coordinates - self.image_scale = float(self.map_height) / cropsize[0] - self.transX =imageCenter[0] + self.image_scale * (mapCenter[0]) - self.transY = imageCenter[1] + self.image_scale * (mapCenter[1]) - - def radius_to_map_positions(self,radius): - ## this function converts all radius into map coordinates - ## centred around the origin that the creep can exist - ## the cgu_radius_to_map_position function will simply - ## substract every coordinate with the centre point of the tumour - output_coordinates = list() - # Sample a square area using the radius - for x in range (-radius,radius): - for y in range (-radius, radius): - if (x**2 + y**2) <= (radius * radius): - output_coordinates.append((x,y)) - return output_coordinates - - def init_cgu_lists(self, player_id): - self.creep_spread_by_minute[player_id] = defaultdict(int) - if self.debug: - self.creep_spread_image_by_minute[player_id] = defaultdict(StringIO) - self.creep_gen_units[player_id] = list() - self.creep_gen_units_times[player_id] = list() - - def add_to_list(self,player_id,unit_id,unit_location,unit_type,event_time): - # This functions adds a new time frame to creep_generating_units_list - # Each time frame contains a list of all CGUs that are alive - length_cgu_list = len(self.creep_gen_units[player_id]) - if length_cgu_list==0: - self.creep_gen_units[player_id].append([(unit_id, unit_location,unit_type)]) - self.creep_gen_units_times[player_id].append(event_time) - else: - #if the list is not empty, take the previous time frame, - # add the new CGU to it and append it as a new time frame - previous_list = self.creep_gen_units[player_id][length_cgu_list-1][:] - previous_list.append((unit_id, unit_location,unit_type)) - self.creep_gen_units[player_id].append(previous_list) - self.creep_gen_units_times[player_id].append(event_time) - - def remove_from_list(self,unit_id,time_frame): - ## This function searches is given a unit ID for every unit who died - ## the unit id will be searched in cgu_gen_units for matches - ## if there are any, that unit will be removed from active CGUs - ## and appended as a new time frame - for player_id in self.creep_gen_units: - length_cgu_list = len(self.creep_gen_units[player_id]) - if length_cgu_list ==0: - break - cgu_per_player = self.creep_gen_units[player_id]\ - [length_cgu_list-1] - creep_generating_died = dropwhile(lambda x: x[0] != \ - unit_id, cgu_per_player) - for creep_generating_died_unit in creep_generating_died: - cgu_per_player.remove(creep_generating_died_unit) - self.creep_gen_units[player_id].append(cgu_per_player) - self.creep_gen_units_times[player_id].append(time_frame) - - def add_event(self,event): - # Search things that generate creep - # Tumor, hatcheries, nydus - if event.name == "UnitBornEvent": - if event.unit_type_name== "Hatchery": - self.add_to_list(event.control_pid, event.unit_id,\ - (event.x,event.y),event.unit_type_name,event.second) - if event.name == "UnitInitEvent": - units = ["CreepTumor", "Hatchery","NydusCanal"] - if event.unit_type_name in units: - self.add_to_list(event.control_pid,event.unit_id,\ - (event.x, event.y), event.unit_type_name,event.second) - # Removes creep generating units that were destroyed - if event.name == "UnitDiedEvent": - self.remove_from_list(event.unit_id,event.second) - - def reduce_cgu_per_minute(self,player_id): - #the creep_gen_units_lists contains every single time frame - #where a CGU is added, - #To reduce the calculations required, the time frame containing - #the most cgus every minute will be used to represent that minute - last_minute_found = 0 - cgu_per_player_new = list() - cgu_time_per_player_new = list() - cgu_last_minute_list = list() - for index,cgu_time in enumerate(self.creep_gen_units_times[player_id]): - cgu_last_minute_list.append(self.creep_gen_units[player_id][index]) - if (cgu_time/60) ==0: - cgu_per_player_new.append(self.creep_gen_units[player_id][0]) - cgu_time_per_player_new.append(0) - cgu_last_minute_list = list() - if (cgu_time/60)>last_minute_found: - cgu_max_in_min = max(cgu_last_minute_list,key = len) - cgu_per_player_new.append(cgu_max_in_min) - cgu_max_in_min_index = self.creep_gen_units[player_id].index(cgu_max_in_min) - cgu_time_per_player_new.append(self.creep_gen_units_times[player_id][cgu_max_in_min_index]) - last_minute_found = cgu_time/60 - cgu_last_minute_list=list() - - self.creep_gen_units[player_id] = cgu_per_player_new - self.creep_gen_units_times[player_id] = cgu_time_per_player_new - - def get_creep_spread_area(self,player_id): - ## iterates through all cgus and and calculate the area - for index,cgu_per_player in enumerate(self.creep_gen_units[player_id]): - # convert cgu list into centre of circles and radius - cgu_radius = map(lambda x: (x[1], self.unit_name_to_radius[x[2]]),\ - cgu_per_player) - # convert event coords to minimap coords - cgu_radius = self.convert_cgu_radius_event_to_map_coord(cgu_radius) - creep_area_positions = self.cgu_radius_to_map_positions(cgu_radius,self.radius_to_coordinates) - cgu_last_event_time = self.creep_gen_units_times[player_id][index]/60 - if self.debug: - self.print_image(creep_area_positions,player_id,cgu_last_event_time) - creep_area = len(creep_area_positions) - self.creep_spread_by_minute[player_id][cgu_last_event_time]=\ - float(creep_area)/self.mapSize*100 - return self.creep_spread_by_minute[player_id] - - def cgu_radius_to_map_positions(self,cgu_radius,radius_to_coordinates): - ## This function uses the output of radius_to_map_positions - total_points_on_map = Set() - if len(cgu_radius)==0: - return [] - for cgu in cgu_radius: - point = cgu[0] - radius = cgu[1] - ## subtract all radius_to_coordinates with centre of - ## cgu radius to change centre of circle - cgu_map_position = map( lambda x:(x[0]+point[0],x[1]+point[1])\ - ,self.radius_to_coordinates[radius]) - total_points_on_map= total_points_on_map | Set(cgu_map_position) - return total_points_on_map - - def print_image(self,total_points_on_map,player_id,time_stamp): - minimap_copy = self.minimap_image.copy() - # Convert all creeped points to white - for points in total_points_on_map: - x = points[0] - y = points[1] - x,y = self.check_image_pixel_within_boundary(x,y) - minimap_copy.putpixel((x,y) , (255, 255, 255)) - creeped_image = minimap_copy - # write creeped minimap image to a string as a png - creeped_imageIO = StringIO() - creeped_image.save(creeped_imageIO, "png") - self.creep_spread_image_by_minute[player_id][time_stamp]=creeped_imageIO - ##debug for print out the images - f = open(str(player_id)+'image'+str(time_stamp)+'.png','w') - f.write(creeped_imageIO.getvalue()) - creeped_imageIO.close() - f.close() - - def check_image_pixel_within_boundary(self,pointX, pointY): - pointX = 0 if pointX <0 else pointX - pointY=0 if pointY <0 else pointY - # put a minus 1 to make sure the pixel is not directly on the edge - pointX = int(self.map_width-1 if pointX >= self.map_width else pointX) - pointY = int(self.map_height-1 if pointY >= self.map_height else pointY) - return pointX,pointY - - def convert_cgu_radius_event_to_map_coord(self,cgu_radius): - cgu_radius_new = list() - for cgu in cgu_radius: - x = cgu[0][0] - y = cgu[0][1] - (x,y) = self.convert_event_coord_to_map_coord(x,y) - cgu = ((x,y),cgu[1]) - cgu_radius_new.append(cgu) - return cgu_radius_new - - def convert_event_coord_to_map_coord(self,x,y): - imageX = int(self.map_height - self.transX + self.image_scale * x) - imageY = int(self.transY - self.image_scale * y) - return imageX, imageY - - def cameraOffset(self,mapinfo): - fogOfWarStart = mapinfo.find('Dark') - textureEnd = mapinfo[fogOfWarStart + 5:-1].find('\0') - rest = mapinfo[fogOfWarStart + 5 + textureEnd + 1: -1] - return ord(rest[0]), ord(rest[4]) - - From aa15245dcc64b4979ac9a89b9ce165db54c443e5 Mon Sep 17 00:00:00 2001 From: jonomon Date: Thu, 1 Aug 2013 10:19:44 -0400 Subject: [PATCH 6/8] Update creeptracker.py --- sc2reader/engine/plugins/creeptracker.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sc2reader/engine/plugins/creeptracker.py b/sc2reader/engine/plugins/creeptracker.py index 7f32976c..23053574 100644 --- a/sc2reader/engine/plugins/creeptracker.py +++ b/sc2reader/engine/plugins/creeptracker.py @@ -39,9 +39,6 @@ def handleUnitBornEvent(self,event,replay): def handleEndGame(self, event, replay): if len( replay.tracker_events) ==0 : - for player in replay.players: - player.creep_spread_by_minute = 0 - player.max_creep_spread =0 return for player_id in replay.player: self.creepTracker.reduce_cgu_per_minute(player_id) @@ -51,7 +48,7 @@ def handleEndGame(self, event, replay): if player.creep_spread_by_minute: player.max_creep_spread = max(player.creep_spread_by_minute.items(),key=lambda x:x[1]) else: - ## Else statement is for players with no creep spread(ie: not Z) + ## Else statement is for players with no creep spread(ie: not Zerg) player.max_creep_spread =0 ## The class used to used to calculate the creep spread From 6f6793bb084c13d168342e49f4f2da48d2c5efea Mon Sep 17 00:00:00 2001 From: Graylin Kim Date: Mon, 12 Aug 2013 10:31:34 -0400 Subject: [PATCH 7/8] Fix trailing whitespace. --- sc2reader/engine/plugins/creeptracker.py | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sc2reader/engine/plugins/creeptracker.py b/sc2reader/engine/plugins/creeptracker.py index 23053574..bd6ff84f 100644 --- a/sc2reader/engine/plugins/creeptracker.py +++ b/sc2reader/engine/plugins/creeptracker.py @@ -4,7 +4,7 @@ from itertools import dropwhile from sets import Set from Image import open as PIL_open -from Image import ANTIALIAS +from Image import ANTIALIAS from StringIO import StringIO from collections import defaultdict @@ -31,7 +31,7 @@ def handleUnitInitEvent(self,event,replay): if event.unit_type_name in ["CreepTumor", "Hatchery","NydusCanal"] : self.creepTracker.add_to_list(event.control_pid,event.unit_id,\ (event.x, event.y), event.unit_type_name,event.second) - + def handleUnitBornEvent(self,event,replay): if event.unit_type_name== "Hatchery": self.creepTracker.add_to_list(event.control_pid, event.unit_id,\ @@ -51,12 +51,12 @@ def handleEndGame(self, event, replay): ## Else statement is for players with no creep spread(ie: not Zerg) player.max_creep_spread =0 -## The class used to used to calculate the creep spread +## The class used to used to calculate the creep spread class creep_tracker(): def __init__(self,replay): #if the debug option is selected, minimaps will be printed to a file - ##and a stringIO containing the minimap image will be saved for - ##every minite in the game and the minimap with creep highlighted + ##and a stringIO containing the minimap image will be saved for + ##every minite in the game and the minimap with creep highlighted ## will be printed out. self.debug = replay.opt.debug ##This list contains creep spread area for each player @@ -76,7 +76,7 @@ def __init__(self,replay): for x in self.unit_name_to_radius: self.radius_to_coordinates[self.unit_name_to_radius[x]] =\ self.radius_to_map_positions(self.unit_name_to_radius[x]) - + #Get map information replayMap = replay.map # extract image from replay package @@ -89,7 +89,7 @@ def __init__(self,replay): # resize height to MAPHEIGHT, and compute new width that # would preserve aspect ratio self.map_width = int(cropsize[0] * (float(self.map_height) / cropsize[1])) - self.mapSize =self.map_height * self.map_width + self.mapSize =self.map_height * self.map_width ## the following parameters are only needed if minimaps have to be printed minimapSize = ( self.map_width,int(self.map_height) ) self.minimap_image = cropped.resize(minimapSize, ANTIALIAS) @@ -100,10 +100,10 @@ def __init__(self,replay): imageCenter = [(self.map_width/2), self.map_height/2] # this is the scaling factor to go from the SC2 coordinate # system to pixel coordinates - self.image_scale = float(self.map_height) / cropsize[0] + self.image_scale = float(self.map_height) / cropsize[0] self.transX =imageCenter[0] + self.image_scale * (mapCenter[0]) self.transY = imageCenter[1] + self.image_scale * (mapCenter[1]) - + def radius_to_map_positions(self,radius): ## this function converts all radius into map coordinates ## centred around the origin that the creep can exist @@ -142,7 +142,7 @@ def add_to_list(self,player_id,unit_id,unit_location,unit_type,event_time): def remove_from_list(self,unit_id,time_frame): ## This function searches is given a unit ID for every unit who died ## the unit id will be searched in cgu_gen_units for matches - ## if there are any, that unit will be removed from active CGUs + ## if there are any, that unit will be removed from active CGUs ## and appended as a new time frame for player_id in self.creep_gen_units: length_cgu_list = len(self.creep_gen_units[player_id]) @@ -179,12 +179,12 @@ def reduce_cgu_per_minute(self,player_id): cgu_time_per_player_new.append(self.creep_gen_units_times[player_id][cgu_max_in_min_index]) last_minute_found = cgu_time/60 cgu_last_minute_list=list() - + self.creep_gen_units[player_id] = cgu_per_player_new self.creep_gen_units_times[player_id] = cgu_time_per_player_new def get_creep_spread_area(self,player_id): - ## iterates through all cgus and and calculate the area + ## iterates through all cgus and and calculate the area for index,cgu_per_player in enumerate(self.creep_gen_units[player_id]): # convert cgu list into centre of circles and radius cgu_radius = map(lambda x: (x[1], self.unit_name_to_radius[x[2]]),\ @@ -209,7 +209,7 @@ def cgu_radius_to_map_positions(self,cgu_radius,radius_to_coordinates): point = cgu[0] radius = cgu[1] ## subtract all radius_to_coordinates with centre of - ## cgu radius to change centre of circle + ## cgu radius to change centre of circle cgu_map_position = map( lambda x:(x[0]+point[0],x[1]+point[1])\ ,self.radius_to_coordinates[radius]) total_points_on_map= total_points_on_map | Set(cgu_map_position) From ba7e2055368e0cf4e96972600885a3f5f4a66536 Mon Sep 17 00:00:00 2001 From: Graylin Kim Date: Mon, 12 Aug 2013 10:32:20 -0400 Subject: [PATCH 8/8] Change test to use unittest and use old division to make tests pass. --- sc2reader/engine/plugins/creeptracker.py | 27 +++++++------- test_replays/test_all.py | 46 +++++++++++------------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/sc2reader/engine/plugins/creeptracker.py b/sc2reader/engine/plugins/creeptracker.py index bd6ff84f..42eee635 100644 --- a/sc2reader/engine/plugins/creeptracker.py +++ b/sc2reader/engine/plugins/creeptracker.py @@ -7,6 +7,8 @@ from Image import ANTIALIAS from StringIO import StringIO from collections import defaultdict +from sc2reader.engine import PluginExit + # The creep tracker plugin class CreepTracker(object): @@ -15,9 +17,12 @@ class CreepTracker(object): player.creep_spread by minute This uses the creep_tracker class to calculate the features ''' + name = "CreepTracker" + def handleInitGame(self, event, replay): - if len( replay.tracker_events) ==0 : - return + if len(replay.tracker_events) == 0 : + yield PluginExit(self, code=0, details={}) + if replay.map is None: replay.load_map() self.creepTracker = creep_tracker(replay) @@ -38,8 +43,6 @@ def handleUnitBornEvent(self,event,replay): (event.x,event.y),event.unit_type_name,event.second) def handleEndGame(self, event, replay): - if len( replay.tracker_events) ==0 : - return for player_id in replay.player: self.creepTracker.reduce_cgu_per_minute(player_id) for player in replay.players: @@ -168,16 +171,16 @@ def reduce_cgu_per_minute(self,player_id): cgu_last_minute_list = list() for index,cgu_time in enumerate(self.creep_gen_units_times[player_id]): cgu_last_minute_list.append(self.creep_gen_units[player_id][index]) - if (cgu_time/60) ==0: + if (cgu_time//60) ==0: cgu_per_player_new.append(self.creep_gen_units[player_id][0]) cgu_time_per_player_new.append(0) cgu_last_minute_list = list() - if (cgu_time/60)>last_minute_found: + if (cgu_time//60)>last_minute_found: cgu_max_in_min = max(cgu_last_minute_list,key = len) cgu_per_player_new.append(cgu_max_in_min) cgu_max_in_min_index = self.creep_gen_units[player_id].index(cgu_max_in_min) cgu_time_per_player_new.append(self.creep_gen_units_times[player_id][cgu_max_in_min_index]) - last_minute_found = cgu_time/60 + last_minute_found = cgu_time//60 cgu_last_minute_list=list() self.creep_gen_units[player_id] = cgu_per_player_new @@ -187,17 +190,15 @@ def get_creep_spread_area(self,player_id): ## iterates through all cgus and and calculate the area for index,cgu_per_player in enumerate(self.creep_gen_units[player_id]): # convert cgu list into centre of circles and radius - cgu_radius = map(lambda x: (x[1], self.unit_name_to_radius[x[2]]),\ - cgu_per_player) + cgu_radius = map(lambda x: (x[1], self.unit_name_to_radius[x[2]]), cgu_per_player) # convert event coords to minimap coords cgu_radius = self.convert_cgu_radius_event_to_map_coord(cgu_radius) creep_area_positions = self.cgu_radius_to_map_positions(cgu_radius,self.radius_to_coordinates) - cgu_last_event_time = self.creep_gen_units_times[player_id][index]/60 - if self.debug: + cgu_last_event_time = self.creep_gen_units_times[player_id][index]//60 + if self.debug: self.print_image(creep_area_positions,player_id,cgu_last_event_time) creep_area = len(creep_area_positions) - self.creep_spread_by_minute[player_id][cgu_last_event_time]=\ - float(creep_area)/self.mapSize*100 + self.creep_spread_by_minute[player_id][cgu_last_event_time]=float(creep_area)/self.mapSize*100 return self.creep_spread_by_minute[player_id] def cgu_radius_to_map_positions(self,cgu_radius,radius_to_coordinates): diff --git a/test_replays/test_all.py b/test_replays/test_all.py index 9d5b7941..1dab0afd 100644 --- a/test_replays/test_all.py +++ b/test_replays/test_all.py @@ -359,31 +359,27 @@ def test_gameheartnormalizer_plugin(self): self.assertEqual(replay.winner, replay.teams[0]) -def test_creepTracker(): - from sc2reader.engine.plugins import CreepTracker - - for replayfilename in [ - "test_replays/2.0.8.25605/ggtracker_3621322.SC2Replay", - "test_replays/2.0.8.25605/ggtracker_3621402.SC2Replay", - "test_replays/2.0.8.25605/ggtracker_3663861.SC2Replay", - "test_replays/2.0.8.25605/ggtracker_3695400.SC2Replay", - ]: - factory = sc2reader.factories.SC2Factory() - pluginEngine=sc2reader.engine.GameEngine(plugins=[ - CreepTracker() - ]) - replay =factory.load_replay(replayfilename,engine=pluginEngine,load_map= True,load_level=4) - - for player_id in replay.player: - if replay.player[player_id].play_race == "Zerg": - assert replay.player[player_id].max_creep_spread >0 - assert replay.player[player_id].creep_spread_by_minute - - - replay =factory.load_replay("test_replays/2.0.8.25605/ggtracker_3621402.SC2Replay",load_map= True,engine=pluginEngine,load_level=4) - assert replay.player[2].max_creep_spread == (14,22.95) - assert replay.player[2].creep_spread_by_minute[7] == 8.21 - assert replay.player[2].creep_spread_by_minute[13] == 22.42 + def test_creepTracker(self): + from sc2reader.engine.plugins import CreepTracker + pluginEngine = sc2reader.engine.GameEngine(plugins=[CreepTracker()]) + + for replayfilename in [ + "test_replays/2.0.8.25605/ggtracker_3621322.SC2Replay", + "test_replays/2.0.8.25605/ggtracker_3621402.SC2Replay", + "test_replays/2.0.8.25605/ggtracker_3663861.SC2Replay", + "test_replays/2.0.8.25605/ggtracker_3695400.SC2Replay", + ]: + + replay = sc2reader.load_replay(replayfilename, engine=pluginEngine, load_map=True) + for player_id in replay.player: + if replay.player[player_id].play_race == "Zerg": + self.assertTrue(replay.player[player_id].max_creep_spread > 0) + self.assertTrue(replay.player[player_id].creep_spread_by_minute) + + replay = sc2reader.load_replay("test_replays/2.0.8.25605/ggtracker_3621402.SC2Replay", load_map=True, engine=pluginEngine) + self.assertEqual(replay.player[2].max_creep_spread, (14,22.95)) + self.assertEqual(replay.player[2].creep_spread_by_minute[7], 8.21) + self.assertEqual(replay.player[2].creep_spread_by_minute[13], 22.42) if __name__ == '__main__': unittest.main()