-
Notifications
You must be signed in to change notification settings - Fork 0
/
Scheduler.py
114 lines (106 loc) · 3.95 KB
/
Scheduler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from model.ActionType import ActionType
from model.Move import Move
from model.World import World
from model.VehicleType import VehicleType
from Utils import get_center, Area
from Analyze import WorldState, Vehicles
class Action:
def __init__(self, action: ActionType = ActionType.NONE):
self.action = action
def resolve(self, move: Move, ws: WorldState, world: World):
move.action = self.action
class Event:
#: Action
def __init__(self):
pass
def at_move_end():
pass
def after():
pass
class NukeAction(Action):
def __init__(self):
pass
class MoveAction(Action):
def __init__(self, position_obtainer: callable):
## position obtainer should return the Unit of target position in absolute coordinates
Action.__init__(self, ActionType.MOVE)
self.position_obtainer = position_obtainer
def resolve(self, move: Move, ws: WorldState, w: World):
Action.resolve(move, ws, w)
position = self.position_obtainer(ws, w)
current_position = get_center(ws.vehicles.resolve(ws.vehicles.selected))
move.x = position.x - current_position.x
move.y = position.y - current_position.y
class RotateAction(Action):
def __init__(self, epicenter_obtainer: callable):
## epicenter_obtainer should return tuple of center Unit and angle
Action.__init__(self, ActionType.ROTATE)
self.epicenter_obtainer = epicenter_obtainer
def resolve(self, move: Move, ws: WorldState, w: World):
Action.resolve(self, move, ws, w)
epicenter = self.epicenter_obtainer(ws, w)
move.x = epicenter[0].x
move.y = epicenter[0].y
move.angle = epicenter[1]
class Selector(Action):
def __init__(self, area: Area, group: int = -1, vtype: VehicleType = -1, action = ActionType.CLEAR_AND_SELECT):
Action.__init__(self, action)
self.area = area
self.vehicle_type = vtype
self.group = group
def to_set(self, prev: set, vehicles: Vehicles):
if self.group > 0:
result = vehicles.by_group[self.group]
else:
result = vehicles.in_area(self.area) & vehicles.by_player[vehicles.me]
if self.vehicle_type > 0:
result &= vehicles.by_type[self.vehicle_type]
if self.action == ActionType.CLEAR_AND_SELECT:
return result
elif self.action == ActionType.ADD_TO_SELECTION:
return result | prev
elif self.action == ActionType.DESELECT:
return prev - result
def resolve(self, move: Move, ws: WorldState, world: World):
Action.resolve(self, move, ws, world)
move.left = self.area.left
move.right = self.area.right
move.top = self.area.top
move.bottom = self.area.bottom
move.group = self.group
move.vehicle_type = self.vehicle_type
class ActionChain:
counter = 0
queue = list() # List of Actions
last_selection = set()
def __init__(self):
pass
def select(self, area: Area, group: int = -1, vtype: VehicleType = -1):
selector = Selector(area, group, vtype, ActionType.CLEAR_AND_SELECT)
self.queue.append(selector)
return self
def add_to_select(self, area: Area, group: int = -1, vtype: VehicleType = -1):
selector = Selector(area, group, vtype, ActionType.ADD_TO_SELECTION)
self.queue.append(selector)
return self
def remove_from_select(self, area: Area, group: int = -1, vtype: VehicleType = -1):
selector = Selector(area, group, vtype, ActionType.DESELECT)
self.queue.append(selector)
return self
def move(self, position_obtainer: callable):
## returns move_end event
action = MoveAction(position_obtainer)
self.queue.append(action)
return self
def rotate(self, epicenter_obtainer: callable):
self.queue.append(RotateAction(epicenter_obtainer))
return self
def nuke(self):
return self
def resolve(self, move: Move, ws: WorldState, world: World):
if len(self.queue) <= self.counter:
return True
current_action = self.queue[self.counter]
self.last_selection = ws.vehicles.selected
current_action.resolve(move, ws, world)
self.counter += 1