Created
December 24, 2011 09:27
-
-
Save zagfai/1516984 to your computer and use it in GitHub Desktop.
My BOT which got the 800th place in the Ants ( AI Challenge ). Have fun.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import math | |
import heapq | |
from ants import * | |
class MyBot: | |
def __init__(self): | |
pass | |
def do_setup(self, ants): | |
self.hills_enemy = [] | |
self.view_radius = int(math.sqrt( ants.viewradius2)) | |
self.light_house = [] | |
self.has_friend = {} | |
for row in range(1, ants.rows, int(self.view_radius<<3)): | |
for col in range(1, ants.cols, int(self.view_radius<<3)): | |
self.light_house.append((row, col)) | |
# End of setup | |
def do_move_direction(self, loc, direction, orders, ants_close_book, ants): | |
new_loc = ants.destination(loc, direction) | |
if ants.unoccupied(new_loc) and new_loc not in orders: | |
ants.issue_order((loc, direction)) | |
orders[new_loc] = loc | |
ants_close_book[loc] = 1 | |
return True | |
else: | |
return False | |
def do_move_location(self, loc, dest, mark_set, orders, ants_close_book, ants): | |
directions = ants.direction(loc, dest) | |
for direction in directions: | |
if self.do_move_direction(loc, direction, orders, ants_close_book, ants): | |
mark_set[dest] = mark_set.get(dest, 0) +1 | |
return True | |
return False | |
def do_move_astar(self, loc, dest, max_step, food_Ks, ants): | |
q = [] | |
vis_nood = {} | |
heapq.heapify(q) | |
vis_nood[ loc] = True | |
for dist in ['e','s','w','n']: | |
new_loc = ants.destination(loc, dist) | |
if ants.unoccupied(new_loc): | |
vis_nood[ new_loc] = True | |
heapq.heappush(q, (ants.distance(new_loc, dest), new_loc, max_step, dist)) | |
while len(q) > 0: | |
g_h, now_loc, left_step, order_dist = heapq.heappop(q) | |
if food_Ks.get(now_loc, 0) > 0: | |
food_Ks[ now_loc] -= 1 | |
return order_dist | |
if not ants.visible( now_loc): | |
return order_dist | |
if now_loc in self.has_friend: | |
self.has_friend[loc] +=1 | |
for dist in ['e','s','w','n']: | |
new_loc = ants.destination(now_loc, dist) | |
if ants.passable(new_loc) and new_loc not in vis_nood and left_step>0: | |
vis_nood[ new_loc] = True | |
heapq.heappush(q, (ants.distance(new_loc, dest), new_loc, left_step-1, order_dist)) | |
return None | |
def protect_hill_bfs(self, loc, need_ants, distance, orders, ants_close_book, ants): | |
que = [ (loc, distance) ] | |
ant_count = len(ants.my_ants()) | |
visited_loc = {} | |
while que and need_ants: | |
v = que.pop(0) | |
if v[0] not in ants_close_book and v[0] in ants.my_ants(): | |
ants_close_book[ v[0]] = 1 | |
need_ants -= 1 | |
new_loc = ants.destination( ants.destination( loc, 'n'), 'e') | |
for i in xrange(75, ant_count, 75): | |
new_loc = ants.destination( ants.destination( new_loc, 'n'), 'e') | |
self.do_move_location( v[0], new_loc, {}, orders, ants_close_book, ants) | |
for i in ['e', 's', 'w', 'n']: | |
new_loc = ants.destination( v[0], i) | |
if need_ants and v[1]-1 >0 and new_loc not in visited_loc and ants.passable(new_loc): | |
que.append( (new_loc, v[1]-1)) | |
# End of protect hill bfs | |
def do_turn(self, ants): | |
ants_my_sum = len(ants.my_ants()) | |
hills_my_sum = len(ants.my_hills()) | |
ants_close_book = {} | |
orders = {} # protect the crash new_loc:old_loc | |
food_Ks = {} # ants/food counts book | |
def move_direct( loc, direct): | |
return self.do_move_direction( loc, direct, orders, ants_close_book, ants) | |
def move_distan( loc, dest, mark_set): | |
return self.do_move_location( loc, dest, mark_set, orders, ants_close_book, ants) | |
# Make ants' book | |
self.has_friend.clear() | |
for ant in ants.my_ants(): | |
self.has_friend[ ant] = 0 | |
# Protect hills | |
for hill in ants.my_hills(): | |
self.protect_hill_bfs( hill, int(ants_my_sum *0.1/hills_my_sum), self.view_radius, orders, ants_close_book, ants) | |
# ready unseen | |
unseen = [] | |
step = self.view_radius + 3 | |
for ant in ants.my_ants(): | |
for aim in [ (0,step), (step,0), (0, -step), (-step, 0)]: | |
d_row, d_col = aim | |
loc = ((ant[0] + d_row) % ants.rows, (ant[1] + d_col) % ants.cols) | |
if not ants.visible(loc): | |
unseen.append(loc) | |
# ready enemy hills | |
for hill_loc in self.hills_enemy[:]: | |
if ants.visible(hill_loc): | |
self.hills_enemy.remove(hill_loc) | |
for hill_loc, hill_owner in ants.enemy_hills(): | |
if hill_loc not in self.hills_enemy: | |
self.hills_enemy.append(hill_loc) | |
# ready | |
for pos in unseen: | |
food_Ks [pos] = 5 | |
for food in ants.food(): | |
food_Ks [food] = 3 | |
for hill in self.hills_enemy: | |
food_Ks [hill] = 10 | |
# Find foods or hills of enemies | |
ant_dist = [] | |
for ant_loc in ants.my_ants(): | |
if ant_loc not in ants_close_book: | |
for food_loc in food_Ks: | |
dist = ants.distance(ant_loc, food_loc) | |
ant_dist.append((dist, ant_loc, food_loc)) | |
ant_dist.sort() | |
for dist, ant_loc, food_loc in ant_dist: | |
if ants.time_remaining() < 15+ (ants_my_sum>>1) + (hills_my_sum << 3): break | |
if ant_loc not in ants_close_book and food_Ks[food_loc]>0: | |
go_direct = self.do_move_astar( ant_loc, food_loc, self.view_radius<<2, food_Ks, ants) | |
if go_direct != None: | |
move_direct( ant_loc, go_direct) | |
ants_close_book[ ant_loc] = 1 | |
elif len(self.hills_enemy) !=0 and ant_dist> (self.view_radius<<1): | |
move_distan( ant_loc, self.hills_enemy[0], {}) | |
elif ant_dist > (self.view_radius<<1): | |
move_distan( ant_loc, food_loc, {}) | |
# Get some ants together | |
min_friend = ((0,0), 100) | |
for i in self.has_friend: | |
if self.has_friend[i] > min_friend[1]: | |
min_friend = (i, self.has_friend[i]) | |
for ant_loc in ants.my_ants(): | |
if ants.time_remaining() < 10 + (hills_my_sum << 3): break | |
if ant_loc not in ants_close_book: | |
move_distan( ant_loc, min_friend[0], {}) | |
# Open black | |
# lighthouse = [] | |
# for loc in self.light_house: | |
# if not ants.visible(loc): | |
# lighthouse.append(loc) | |
# K_of_lighthouse = int( (ants_my_sum - len(ants_close_book)) / (len(lighthouse)+1) ) | |
# | |
# unseen_dist = [] | |
# for ant_loc in ants.my_ants(): | |
# if ant_loc not in ants_close_book: | |
# for unseen_loc in lighthouse: | |
# dist = ants.distance(ant_loc, unseen_loc) | |
# unseen_dist.append((dist, unseen_loc, ant_loc)) | |
# if ants.time_remaining() < 50: | |
# break | |
# unseen_dist.sort() | |
# for dist, unseen_loc, ant_loc in unseen_dist: | |
# if lighthouse_Ks.get(unseen_loc) < K_of_lighthouse and ant_loc not in ants_close_book: | |
# move_distan(ant_loc, unseen_loc, lighthouse_Ks) | |
# | |
# Spawn an ant | |
for hill_loc in ants.my_hills(): | |
if hill_loc in ants.my_ants() and hill_loc not in orders.values(): | |
for direction in ('s','e','w','n'): | |
if move_direct(hill_loc, direction): | |
break | |
# End of turn | |
if __name__ == '__main__': | |
try: | |
import psyco | |
psyco.full() | |
except ImportError: | |
pass | |
try: | |
Ants.run(MyBot()) | |
except KeyboardInterrupt: | |
print('ctrl-c, leaving ...') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment