-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathBaselineBot.py
75 lines (58 loc) · 2.26 KB
/
BaselineBot.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
#
# Baseline Overkill Bot based on nmalaguti's starter pack
#
import hltold as hlt
from hltold import NORTH, EAST, SOUTH, WEST, STILL, Move
myID, game_map = hlt.get_init()
hlt.send_init("BaselineBot")
def find_nearest_enemy_direction(square):
"""
Identify closest enemy direction/location
:param square: Map location for move
:return: Direction of closest enemy
"""
direction = NORTH
max_distance = min(game_map.width, game_map.height) / 2
for d in (NORTH, EAST, SOUTH, WEST):
distance = 0
current = square
while current.owner == myID and distance < max_distance:
distance += 1
current = game_map.get_target(current, d)
if distance < max_distance:
direction = d
max_distance = distance
return direction
def heuristic(square):
"""
Calculate optimal movement heuristic
:param square: Map location for move
:return: Total potential offense damage
"""
if square.owner == 0 and square.strength > 0:
return square.production / square.strength
else:
# Total potential damage caused by overkill when attacking this square
return sum(neighbor.strength for neighbor in game_map.neighbors(square) if neighbor.owner not in (0, myID))
# Maximum 1 second
def get_move(square):
"""
Return move for square - NORTH, SOUTH, WEST, EAST, STILL
:param square: Map location for move
:return: NORTH, SOUTH, WEST, EAST, STILL
"""
target, direction = max(((neighbor, direction) for direction, neighbor in enumerate(game_map.neighbors(square))
if neighbor.owner != myID), default=(None, None), key=lambda t: heuristic(t[0]))
if target is not None and target.strength < square.strength:
return Move(square, direction)
elif square.strength < square.production * 5:
return Move(square, STILL)
border = any(neighbor.owner != myID for neighbor in game_map.neighbors(square))
if not border:
return Move(square, find_nearest_enemy_direction(square))
# Wait till strong enough to attack
return Move(square, STILL)
while True:
game_map.get_frame()
moves = [get_move(_square) for _square in game_map if _square.owner == myID]
hlt.send_frame(moves)