Skip to content

Instantly share code, notes, and snippets.

@zagfai
Created December 24, 2011 09:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zagfai/1516984 to your computer and use it in GitHub Desktop.
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.
#!/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