Skip to content

Commit 3f020da

Browse files
committed
seems to work OK
1 parent f3ef915 commit 3f020da

File tree

3 files changed

+65
-39
lines changed

3 files changed

+65
-39
lines changed

sc2reader/engine/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
def setGameEngine(engine):
1414
module = sys.modules[__name__]
1515
module.run = engine.run
16+
module.plugins = engine.plugins
1617
module.register_plugin = engine.register_plugin
1718
module.register_plugins = engine.register_plugins
1819

sc2reader/engine/engine.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ def register_plugins(self, *plugins):
9494
for plugin in plugins:
9595
self.register_plugin(plugin)
9696

97+
def plugins(self):
98+
return self._plugins
99+
97100
def run(self, replay):
98101
# A map of [event.name] => event handlers in plugin registration order
99102
# ranked from most generic to most specific

sc2reader/engine/plugins/creeptracker.py

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import absolute_import, print_function, unicode_literals, division
33

4-
from itertools import dropwhile
54
from sets import Set
65
from Image import open as PIL_open
76
from Image import ANTIALIAS
87
from StringIO import StringIO
98
from collections import defaultdict
9+
from itertools import tee
1010

1111
# The creep tracker plugin
1212
class CreepTracker(object):
@@ -16,40 +16,62 @@ class CreepTracker(object):
1616
This uses the creep_tracker class to calculate the features
1717
'''
1818
def handleInitGame(self, event, replay):
19+
try:
1920
if len( replay.tracker_events) ==0 :
2021
return
2122
if replay.map is None:
2223
replay.load_map()
2324
self.creepTracker = creep_tracker(replay)
2425
for player in replay.players:
26+
if player.play_race[0] == 'Z':
2527
self.creepTracker.init_cgu_lists(player.pid)
28+
except Exception as e:
29+
print("Whoa! {}".format(e))
30+
pass
2631

2732
def handleUnitDiedEvent(self, event, replay):
33+
try:
2834
self.creepTracker.remove_from_list(event.unit_id,event.second)
35+
except Exception as e:
36+
print("Whoa! {}".format(e))
37+
pass
38+
2939

3040
def handleUnitInitEvent(self,event,replay):
41+
try:
3142
if event.unit_type_name in ["CreepTumor", "Hatchery","NydusCanal"] :
3243
self.creepTracker.add_to_list(event.control_pid,event.unit_id,\
3344
(event.x, event.y), event.unit_type_name,event.second)
45+
except Exception as e:
46+
print("Whoa! {}".format(e))
47+
pass
3448

3549
def handleUnitBornEvent(self,event,replay):
50+
try:
3651
if event.unit_type_name== "Hatchery":
3752
self.creepTracker.add_to_list(event.control_pid, event.unit_id,\
3853
(event.x,event.y),event.unit_type_name,event.second)
54+
except Exception as e:
55+
print("Whoa! {}".format(e))
56+
pass
3957

4058
def handleEndGame(self, event, replay):
59+
try:
4160
if len( replay.tracker_events) ==0 :
4261
return
43-
for player_id in replay.player:
44-
self.creepTracker.reduce_cgu_per_minute(player_id)
4562
for player in replay.players:
63+
if player.play_race[0] == 'Z':
64+
self.creepTracker.reduce_cgu_per_minute(player.pid)
4665
player.creep_spread_by_minute = self.creepTracker.get_creep_spread_area(player.pid)
47-
for player in replay.players:
4866
if player.creep_spread_by_minute:
4967
player.max_creep_spread = max(player.creep_spread_by_minute.items(),key=lambda x:x[1])
5068
else:
5169
## Else statement is for players with no creep spread(ie: not Zerg)
5270
player.max_creep_spread =0
71+
except Exception as e:
72+
print("Whoa! {}".format(e))
73+
pass
74+
5375

5476
## The class used to used to calculate the creep spread
5577
class creep_tracker():
@@ -76,7 +98,6 @@ def __init__(self,replay):
7698
for x in self.unit_name_to_radius:
7799
self.radius_to_coordinates[self.unit_name_to_radius[x]] =\
78100
self.radius_to_map_positions(self.unit_name_to_radius[x])
79-
80101
#Get map information
81102
replayMap = replay.map
82103
# extract image from replay package
@@ -95,7 +116,7 @@ def __init__(self,replay):
95116
self.minimap_image = cropped.resize(minimapSize, ANTIALIAS)
96117
mapOffsetX= replayMap.map_info.camera_left
97118
mapOffsetY = replayMap.map_info.camera_bottom
98-
mapCenter = [mapOffsetX + cropsize[0]/2.0, mapOffsetY + cropsize[1]/2.0]
119+
mapCenter = [mapOffsetX+ cropsize[0]/2.0, mapOffsetY + cropsize[1]/2.0]
99120
# this is the center of the minimap image, in pixel coordinates
100121
imageCenter = [(self.map_width/2), self.map_height/2]
101122
# this is the scaling factor to go from the SC2 coordinate
@@ -148,40 +169,42 @@ def remove_from_list(self,unit_id,time_frame):
148169
length_cgu_list = len(self.creep_gen_units[player_id])
149170
if length_cgu_list ==0:
150171
break
151-
cgu_per_player = self.creep_gen_units[player_id]\
152-
[length_cgu_list-1]
153-
creep_generating_died = dropwhile(lambda x: x[0] != \
154-
unit_id, cgu_per_player)
172+
cgu_per_player = self.creep_gen_units[player_id] [length_cgu_list-1]
173+
creep_generating_died =filter(lambda x:x[0]==unit_id,cgu_per_player)
155174
for creep_generating_died_unit in creep_generating_died:
156-
cgu_per_player.remove(creep_generating_died_unit)
157-
self.creep_gen_units[player_id].append(cgu_per_player)
175+
new_cgu_per_player = filter(lambda x:x != creep_generating_died_unit, cgu_per_player )
176+
self.creep_gen_units[player_id].append(new_cgu_per_player)
158177
self.creep_gen_units_times[player_id].append(time_frame)
159178

179+
def cgu_gen_times_to_chunks(self,cgu_time_list):
180+
## this function returns the index and value of every cgu time
181+
maximum_cgu_time = max(cgu_time_list)
182+
for i in range(0, maximum_cgu_time):
183+
a = filter(lambda (x,y): int(y/60)==i, enumerate(cgu_time_list))
184+
if len(a)>0:
185+
yield a
186+
187+
def cgu_in_min_to_cgu_units(self,player_id,cgu_in_minutes):
188+
## this function takes index and value of CGU times and returns
189+
## the cgu units with the maximum length
190+
for cgu_per_minute in cgu_in_minutes:
191+
indexes = map(lambda x:x[0], cgu_per_minute)
192+
cgu_units = list()
193+
for index in indexes:
194+
cgu_units.append(self.creep_gen_units[player_id][index])
195+
cgu_max_in_minute = max(cgu_units,key = len)
196+
yield cgu_max_in_minute
197+
160198
def reduce_cgu_per_minute(self,player_id):
161199
#the creep_gen_units_lists contains every single time frame
162200
#where a CGU is added,
163201
#To reduce the calculations required, the time frame containing
164202
#the most cgus every minute will be used to represent that minute
165-
last_minute_found = 0
166-
cgu_per_player_new = list()
167-
cgu_time_per_player_new = list()
168-
cgu_last_minute_list = list()
169-
for index,cgu_time in enumerate(self.creep_gen_units_times[player_id]):
170-
cgu_last_minute_list.append(self.creep_gen_units[player_id][index])
171-
if (cgu_time/60) ==0:
172-
cgu_per_player_new.append(self.creep_gen_units[player_id][0])
173-
cgu_time_per_player_new.append(0)
174-
cgu_last_minute_list = list()
175-
if (cgu_time/60)>last_minute_found:
176-
cgu_max_in_min = max(cgu_last_minute_list,key = len)
177-
cgu_per_player_new.append(cgu_max_in_min)
178-
cgu_max_in_min_index = self.creep_gen_units[player_id].index(cgu_max_in_min)
179-
cgu_time_per_player_new.append(self.creep_gen_units_times[player_id][cgu_max_in_min_index])
180-
last_minute_found = cgu_time/60
181-
cgu_last_minute_list=list()
182-
183-
self.creep_gen_units[player_id] = cgu_per_player_new
184-
self.creep_gen_units_times[player_id] = cgu_time_per_player_new
203+
cgu_per_minute1, cgu_per_minute2 = tee (self.cgu_gen_times_to_chunks(self.creep_gen_units_times[player_id]))
204+
cgu_unit_max_per_minute = self.cgu_in_min_to_cgu_units(player_id,cgu_per_minute1)
205+
minutes = map(lambda x:int(x[0][1]/60)*60, cgu_per_minute2)
206+
self.creep_gen_units[player_id] = list(cgu_unit_max_per_minute)
207+
self.creep_gen_units_times[player_id] = list(minutes)
185208

186209
def get_creep_spread_area(self,player_id):
187210
## iterates through all cgus and and calculate the area
@@ -192,12 +215,14 @@ def get_creep_spread_area(self,player_id):
192215
# convert event coords to minimap coords
193216
cgu_radius = self.convert_cgu_radius_event_to_map_coord(cgu_radius)
194217
creep_area_positions = self.cgu_radius_to_map_positions(cgu_radius,self.radius_to_coordinates)
195-
cgu_last_event_time = self.creep_gen_units_times[player_id][index]/60
218+
cgu_event_time = self.creep_gen_units_times[player_id][index]
219+
cgu_event_time_str=str(int(cgu_event_time/60))+":"+str(cgu_event_time%60)
196220
if self.debug:
197-
self.print_image(creep_area_positions,player_id,cgu_last_event_time)
221+
self.print_image(creep_area_positions,player_id,cgu_event_time_str)
198222
creep_area = len(creep_area_positions)
199-
self.creep_spread_by_minute[player_id][cgu_last_event_time]=\
223+
self.creep_spread_by_minute[player_id][cgu_event_time]=\
200224
float(creep_area)/self.mapSize*100
225+
201226
return self.creep_spread_by_minute[player_id]
202227

203228
def cgu_radius_to_map_positions(self,cgu_radius,radius_to_coordinates):
@@ -229,7 +254,7 @@ def print_image(self,total_points_on_map,player_id,time_stamp):
229254
creeped_image.save(creeped_imageIO, "png")
230255
self.creep_spread_image_by_minute[player_id][time_stamp]=creeped_imageIO
231256
##debug for print out the images
232-
f = open(str(player_id)+'image'+str(time_stamp)+'.png','w')
257+
f = open(str(player_id)+'image'+time_stamp+'.png','w')
233258
f.write(creeped_imageIO.getvalue())
234259
creeped_imageIO.close()
235260
f.close()
@@ -256,6 +281,3 @@ def convert_event_coord_to_map_coord(self,x,y):
256281
imageX = int(self.map_height - self.transX + self.image_scale * x)
257282
imageY = int(self.transY - self.image_scale * y)
258283
return imageX, imageY
259-
260-
261-

0 commit comments

Comments
 (0)