-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathplayer_A.py
114 lines (89 loc) · 4.67 KB
/
player_A.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
""" Player module
This is a template/example class for your player.
This is the only file you should modify.
The logic of your hockey robot will be implemented in this class.
Please implement the interface next_move().
The only restrictions here are:
- to implement a class constructor with the args: paddle_pos, goal_side
- set self.my_display_name with your team's name, max. 15 characters
- to implement the function next_move(self, current_state),
returning the next position of your paddle
"""
import copy
import utils
class Player:
def __init__(self, paddle_pos, goal_side):
# set your team's name, max. 15 chars
self.my_display_name = "DREAM TEAM"
# these belong to my solution,
# you may erase or change them in yours
self.future_size = 30
self.my_goal = goal_side
self.my_goal_center = {}
self.opponent_goal_center = {}
self.my_paddle_pos = paddle_pos
def next_move(self, current_state):
""" Function that computes the next move of your paddle
Implement your algorithm here. This will be the only function
used by the GameCore. Be aware of abiding all the game rules.
Returns:
dict: coordinates of next position of your paddle.
"""
# update my paddle pos
# I need to do this because GameCore moves my paddle randomly
self.my_paddle_pos = current_state['paddle1_pos'] if self.my_goal == 'left' \
else current_state['paddle2_pos']
# estimate puck path
path = estimate_path(current_state, self.future_size)
# computing both goal centers
self.my_goal_center = {'x': 0 if self.my_goal == 'left' else current_state['board_shape'][1],
'y': current_state['board_shape'][0]/2}
self.opponent_goal_center = {'x': 0 if self.my_goal == 'right' else current_state['board_shape'][1],
'y': current_state['board_shape'][0]/2}
# find if puck path is inside my interest area
# roi_radius = current_state['board_shape'][0] * current_state['goal_size'] * 2
roi_radius = current_state['board_shape'][1] / 4 + 30
pt_in_roi = None
for p in path:
if utils.distance_between_points(p[0], self.my_goal_center) < roi_radius:
pt_in_roi = p
break
if pt_in_roi:
# estimate an aiming position
target_pos = utils.aim(pt_in_roi[0], pt_in_roi[1],
self.opponent_goal_center, current_state['puck_radius'],
current_state['paddle_radius'])
# move to target position, taking into account the max. paddle speed
if target_pos != self.my_paddle_pos:
direction_vector = {'x': target_pos['x'] - self.my_paddle_pos['x'],
'y': target_pos['y'] - self.my_paddle_pos['y']}
direction_vector = {k: v / utils.vector_l2norm(direction_vector)
for k, v in direction_vector.items()}
movement_dist = min(current_state['paddle_max_speed'] * current_state['delta_t'],
utils.distance_between_points(target_pos, self.my_paddle_pos))
direction_vector = {k: v * movement_dist
for k, v in direction_vector.items()}
new_paddle_pos = {'x': self.my_paddle_pos['x'] + direction_vector['x'],
'y': self.my_paddle_pos['y'] + direction_vector['y']}
# check if computed new position in not inside goal area
# check if computed new position in inside board limits
if utils.is_inside_goal_area_paddle(new_paddle_pos, current_state) is False and \
utils.is_out_of_boundaries_paddle(new_paddle_pos, current_state) is None:
self.my_paddle_pos = new_paddle_pos
return self.my_paddle_pos
def estimate_path(current_state, after_time):
""" Function that function estimates the next moves in a after_time window
Returns:
list: coordinates and speed of puck for next ticks
"""
state = copy.copy(current_state)
path = []
while after_time > 0:
state['puck_pos'] = utils.next_pos_from_state(state)
if utils.is_goal(state) is not None:
break
if utils.next_after_boundaries(state):
state['puck_speed'] = utils.next_after_boundaries(state)
path.append((state['puck_pos'], state['puck_speed']))
after_time -= state['delta_t']
return path