-
Notifications
You must be signed in to change notification settings - Fork 0
/
HostedBot_v5.py
225 lines (204 loc) · 11.5 KB
/
HostedBot_v5.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/usr/bin/env python3
# Python 3.6
# Import the Halite SDK, which will let you interact with the game.
import hlt
# This library contains constant values.
from hlt import constants
# This library contains direction metadata to better interface with the game.
from hlt.positionals import Direction, Position
# Logging allows you to save messages for yourself. This is required because the regular STDOUT
# (print statements) are reserved for the engine-bot communication.
import logging
log_LEVEL = "i"
TURNCOUNT = 500
TURN = 0
EMERGENCY = False
""" <<<Game Begin>>> """
# This game object contains the initial game state.
game = hlt.Game()
# At this point "game" variable is populated with initial map data.
# This is a good place to do computationally expensive start-up pre-processing.
# As soon as you call "ready" function below, the 2 second per turn timer will start.
game.ready("L4TTiCe v5")
# Now that your bot is initialized, save a message to yourself in the log file with some important information.
# Here, you log here your id, which you can always fetch from the game object by using my_id.
logging.info("Successfully created bot! My Player ID is {}.".format(game.my_id))
""" <<<Game Loop>>> """
ship_INTENT = {}
ship_BACKUP = 5
GAME_STATE = 0
shipyard_inuse = False
while True:
# This loop handles each turn of the game. The game object changes every turn, and you refresh that state by
# running update_frame().
game.update_frame()
# You extract player metadata and the updated map metadata here for convenience.
me = game.me
game_map = game.game_map
TURN += 1
if GAME_STATE == 0:
MAP_SIZE = game_map.width
logging.info("MAP SIZE : "+str(MAP_SIZE))
if MAP_SIZE == 64:
TURNCOUNT = 500
elif MAP_SIZE == 56:
TURNCOUNT = 475
elif MAP_SIZE == 48:
TURNCOUNT = 450
elif MAP_SIZE == 40:
TURNCOUNT == 425
elif MAP_SIZE == 32:
TURNCOUNT == 400
GAME_STATE = 1
if TURNCOUNT-TURN < 20:
EMERGENCY = True
logging.info("EMERGENCY MODE")
#logging.info("TURN :"+str(TURN))
# A command queue holds all the commands you will run this turn. You build this list up and submit it at the
# end of the turn.
command_queue = []
directions = [Direction.North, Direction.South, Direction.East, Direction.West, Direction.Still]
queued_coords = []
logging.info("Refreshing Inventory Co-ordinates...")
my_deposit_coords = [item.position for item in list(me.get_dropoffs())] + [me.shipyard.position]
my_ship_coords = [item.position for item in list(me.get_ships())]
logging.info("Ship Coords :" + str(my_ship_coords))
logging.info("depo Coords :" + str(my_deposit_coords))
logging.info("Instructing Ships...")
shipyard_inuse = False
if EMERGENCY:
queued_coords = []
logging.info("Ship Target : " + str(me.shipyard.position))
for ship in me.get_ships():
logging.info("Processing Ship #" + str(ship.id))
logging.info("COORDS\t: " + str(ship.position))
predicted_move = game_map.get_unsafe_moves(ship.position, me.shipyard.position)
logging.info("Ship MOVES : " + str(predicted_move))
if predicted_move == []:
command_queue.append(ship.move(Direction.Still))
logging.info("At Shipyard... Staying Still...")
else:
next_pos = ship.position + Position(*predicted_move[0])
if next_pos == me.shipyard.position:
command_queue.append(ship.move(predicted_move[0]))
logging.info("Crashing into Shipyard")
elif next_pos not in queued_coords:
queued_coords.append(next_pos)
command_queue.append(ship.move(predicted_move[0]))
logging.info("Queued Coord : " + str(next_pos))
else:
predicted_move = game_map.naive_navigate(ship, me.shipyard.position)
next_pos = ship.position + Position(*predicted_move)
if next_pos not in queued_coords:
queued_coords.append(next_pos)
command_queue.append(ship.move(predicted_move))
logging.info("Queued Coord : " + str(next_pos))
game.end_turn(command_queue)
else:
for ship in me.get_ships():
if ship.id not in ship_INTENT:
logging.info("Initializing Ship #" + str(ship.id))
ship_INTENT[ship.id] = "COLLECT"
logging.info("Processing Ship #" + str(ship.id))
logging.info("INTENT\t: " + str(ship_INTENT[ship.id]))
logging.info("COORDS\t: " + str(ship.position))
if ship_INTENT[ship.id] == "COLLECT":
ship_surrounding_coord = ship.position.get_surrounding_cardinals() + [ship.position]
ship_surrounding_coord_DB = {}
# ship_surrounding_coord[ Direction.North ] = Its Position in map like (25, 30)
for index, direction in enumerate(directions):
ship_surrounding_coord_DB[direction] = ship_surrounding_coord[index]
ship_surrounding_coord_haliteDB = {}
# ship_surrounding_coord_haliteDB[ Direction.North ] = Halite in that Location
for direction in ship_surrounding_coord_DB:
position = ship_surrounding_coord_DB[direction]
halite_count = game_map[position].halite_amount
if ship_surrounding_coord_DB[direction] not in queued_coords:
if direction == Direction.Still:
# Biasing Current location to encourage Collecting
halite_count = halite_count * 2
ship_surrounding_coord_haliteDB[direction] = halite_count
if game_map.calculate_distance(ship.position, me.shipyard.position) < ((TURNCOUNT-TURN)+2):
if log_LEVEL == 'v':
logging.info("Halite on-Board : " + str(ship.halite_amount))
logging.info("Halite on-Origin-Cell : " + str(round(0.1 * game_map[ship.position].halite_amount, 2)))
preferred_direction = max(ship_surrounding_coord_haliteDB, key=ship_surrounding_coord_haliteDB.get)
if ship.halite_amount < round(0.1 * game_map[ship.position].halite_amount, 2):
preferred_direction = Direction.Still
logging.info("Insufficient Halite to move. HALTING.")
elif preferred_direction != Direction.Still and game_map[
ship.position + Position(*preferred_direction)].is_occupied:
logging.info("Collision imminent...")
while game_map[ship.position + Position(*preferred_direction)].is_occupied and len(
ship_surrounding_coord_DB.keys()) > 0:
logging.info("Attempting to reroute")
logging.info("Possible Routes : " + str(ship_surrounding_coord_haliteDB))
logging.info("Elimintate route : " + str(preferred_direction))
ship_surrounding_coord_haliteDB.pop(preferred_direction, None)
preferred_direction = max(ship_surrounding_coord_haliteDB, key=ship_surrounding_coord_haliteDB.get)
if preferred_direction == Direction.Still:
break
queued_coords.append(ship_surrounding_coord_DB[preferred_direction])
logging.info("Queued Coord : " + str(ship_surrounding_coord_DB[preferred_direction]))
command_queue.append(ship.move(preferred_direction))
else:
ship_INTENT[ship.id] = "EMER"
predicted_move = game_map.get_unsafe_moves(ship.position, me.shipyard.position)
if predicted_move == []:
ship_INTENT[ship.id] = "COLLECT"
else:
next_pos = ship.position + Position(*predicted_move[0])
if next_pos not in queued_coords:
queued_coords.append(next_pos)
command_queue.append(ship.move(predicted_move[0]))
# logging.info("Queued Coord : " + str(ship_surrounding_coord_DB[predicted_move]))
if predicted_move == Direction.Still:
logging.info("Switching INTENT to Collect Mode")
ship_INTENT[ship.id] = "COLLECT"
if ship.halite_amount >= constants.MAX_HALITE * 0.80:
logging.info("Switching INTENT to Deposit Mode")
ship_INTENT[ship.id] = "DEPOSIT"
elif ship_INTENT[ship.id] == "DEPOSIT":
if EMERGENCY:
predicted_move = game_map.naive_navigate(ship, me.shipyard.position)
next_pos = ship.position + Position(*predicted_move)
queued_coords.append(next_pos)
command_queue.append(ship.move(predicted_move))
else:
predicted_move = game_map.naive_navigate(ship, me.shipyard.position)
next_pos = ship.position + Position(*predicted_move)
if next_pos not in queued_coords:
queued_coords.append(next_pos)
command_queue.append(ship.move(predicted_move))
# logging.info("Queued Coord : " + str(ship_surrounding_coord_DB[predicted_move]))
if predicted_move == Direction.Still:
logging.info("Switching INTENT to Collect Mode")
ship_INTENT[ship.id] = "COLLECT"
for coords in queued_coords:
if coords == me.shipyard.position:
shipyard_inuse=True
for coords in my_ship_coords:
if coords == me.shipyard.position:
shipyard_inuse=True
# If the game is in the first 200 turns and you have enough halite, spawn a ship.
# Don't spawn a ship if you currently have a ship at port, though - the ships will collide.
if game.turn_number <= 200 and me.halite_amount >= constants.SHIP_COST and not game_map[me.shipyard].is_occupied:
command_queue.append(me.shipyard.spawn())
logging.info("Deploying Ship")
elif game.turn_number > 200 and me.halite_amount >= constants.SHIP_COST and not game_map[
me.shipyard].is_occupied and ship_BACKUP > 0:
if len(me.get_ships()) < 20 and game.turn_number < 350:
if me.shipyard.position not in queued_coords:
command_queue.append(me.shipyard.spawn())
logging.info("Deploying Backup Ship")
ship_BACKUP = ship_BACKUP - 1
logging.info("Backup Ships available : " + str(ship_BACKUP))
else:
logging.info("Deferring Backup ship Deployment")
elif game_map[me.shipyard].is_occupied and me.halite_amount >= constants.SHIP_COST:
if not shipyard_inuse:
logging.info("Enemy Blockade Detected")
command_queue.append(me.shipyard.spawn())
logging.info("Deploying Ship to break Blockade")
# Send your moves back to the game environment, ending this turn.
game.end_turn(command_queue)