您的位置:首页 > 大数据 > 人工智能

隨手share - AI Challenge 2011 Fall - Ants - 我的源碼

2012-01-18 23:44 211 查看
雖然排名後, 分享至上。

此AI用 A* 思想,亂改進,最終排名3位數。 =。=

比賽地址: http://aichallenge.org/

#!/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], {})

        # 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 ...')
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐