• 分享下找到的Github上大神的EmpireofCode进攻策略:反正我是用了没反应,改了代码后单位不进攻,蠢站在那里,我自己的策略调调能打败不少人,这个日后慢慢研究吧,Github上暂时找到的唯一策略


    from queue import PriorityQueue
    from enum import Enum
    
    from battle import commander
    from battle import ROLE
    
    
    class Map(object):
        def __init__(self, enemy_items, diagonal_movement=True):
            self.diags = diagonal_movement
            self.width = 20
            self.height = 40
            self._data = [[TILE.EMPTY for y in range(self.height)]for x in range(self.width)]
            self.populate_map(enemy_items)
            self.evil_callback = 0
            
        def populate_map(self, enemy_items):
            valid = lambda w:  any([isinstance(w, int), isinstance(w, float)])
            for entity in enemy_items:
                size = entity.get('size', 0)
                x,y = entity['coordinates']
                role = entity['role']
                if x+size>=self.width or y+size>=self.height:
                    self.extend_map((x+size,y+size))
                if not valid(x) or not valid(y):
                    self.evil_callback+=1
                    continue
                
                x = int(x)
                y = int(y)
                for x0, y0 in self.get_rect_from_center((x,y), size):
                    self._data[x0][y0] = MappedRoles.get(role, TILE.UNKNOWN)
    
        def extend_map(self,point):
            w,h = point
            if h>self.height:
                for y in self._data:
                    y.extend([TILE.EMPTY for _ in range(h-self.height)])
                self.height = h
            if w>self.
                for _ in range(w-self.width):
                    self._data.append([TILE.EMPTY for _ in range(self.height)])
                self.width = w
    
                
        def find_path(self, start, end, size=1, heuristic=None):
            """
            A*
            """
            if not heuristic:
                heuristic = lambda x,y:abs(x-end[0])+abs(y-end[1])
    
            dest = set(self.get_rect_from_center(end, size))
            start = tuple(start)
            fringe = PriorityQueue()
            fringe.put(start, 0)
            total_cost = {start:0}
    
            origin = {start:None}
            while not fringe.empty():
                current = fringe.get()
                if current in dest:
                    break
                cost = total_cost[current]+1
                nodes = self.get_adjacent(current[0], current[1])
                for node in nodes:
                    x,y = node
                    node_type = self._data[x][y]
                    if (node_type == TILE.EMPTY or node in dest) and (node not in total_cost or cost < total_cost[node]):
                        total_cost[node] = cost 
                        origin[node] = current
                        fringe.put(node, cost+heuristic(x, y))
            else:
                return []
    
            path = []
            n = current
            while n is not None:
                path.append(n)
                n = origin[n]
            path.reverse()
            print(path)
            return path
    
        def update(self, info):
            self.init_map(info)
            
        def get_bounds(self, x0,y0,x1,y1):
            xmin, xmax = (max(0, x0), min(self.width, x1))
            ymin, ymax = (max(0, y0), min(self.height, y1))
            return(xmin,ymin, xmax,ymax)
        
        def get_rect_from_center(self, pos, size): ## dist 0: single-point
            if size < 2:                        ## and single-tile bulidings are
                return [pos]                    ## handled in the same manner as of now
                
            even = size %2 == 0
            dist = int(size/2)
            px,py = pos
            if even: ##x/ymax will be exclusive in the for loop!
                xmin, ymin, xmax, ymax = self.get_bounds(px-dist+1, py-dist+1, px+dist+1, py+dist+1)
            else:
                xmin, ymin, xmax, ymax = self.get_bounds(px-dist, py-dist, px+dist+1, py+dist+1)
            print('for {} dist:{} we get a rect ({})'.format(pos, size, (xmin, ymin, xmax-1, ymax-1)))
            cells = []
            for x in range(xmin, xmax):
                for y in range(ymin, ymax):
                    cells.append((x,y))
            return cells
            
        def get_rect(self, top_left, size):
            cells = []
            x0,y0 = top_left
            xmin,ymin, xmax,ymax = self.get_bounds(x0,y0,x0+size, y0+size)
            for x in range(xmin, xmax):
                for y in range(ymin, ymax):
                    cells.append((x,y))
            return cells
    
        def get_adjacent(self, x0,y0, diag = True):
            """
            Returns a list of tuples of coords adjacent to (x0,y0)
                7 8 9
                4 @ 6
                1 2 3
            """
            res =[]
            if x0>0:
                res.append((x0-1,y0))       # 4
                if y0>0 and diag:
                  res.append((x0-1,y0-1))   # 7
                if y0 < self.height-1 and diag:
                  res.append((x0-1,y0+1))   # 1
    
            if y0>0:
                res.append((x0,y0-1))       # 8
    
            if x0 < self.width-1:
                res.append((x0+1,y0))       # 6
                if y0 < self.height-1 and diag:
                    res.append((x0+1,y0+1)) # 3
            if y0>0 and diag:
                res.append((x0+1,y0-1))     # 9
        
            if y0 < self.height-1:
                res.append((x0,y0+1))       # 2
            
            return [tuple(x) for x in res]
              
        def get_info(self):
            for x in range(self.width):
                for y in range(self.height):
                    a = self._data[x][y]
                    if a != TILE.EMPTY :
                        print("[{},{}],{}".format(x,y,a))
                        
        def __getitem__(self, index):
            return self._data[index]
    
    
    class Brain(object):
        """
        (0,0) is located in the northen corner of the map.
        X N->SE
        Y N-SW
        """
        def __init__(self,client, init_terrain=True):
            self.me = client
            self.update()
            if init_terrain:
                self.terrain = Map(self.me.ask_enemy_items())
        
        def update(self):
            info = self.me.ask_my_info()
            self.fire_range = info['firing_range']
            self.pos = info['coordinates']
            self.size = info.get('size', 0)
            
        def goto(self, pos, size = 1):
            return self.terrain.find_path(self.pos, pos, size)
    
    def midpoint(p1, p2):
        return ((p1[0]+p2[0])/2, (p1[1]+p2[1])/2)
        
    def dist(p1, p2):
        x,y = p1
        ox,oy = p2
        return pow((ox-x)*(ox-x) + (oy-y)*(oy-y), 1/2)
        
    def search_role(array,role):
        for e in array:
            if e['role'] == role:
                return True
        return False
    
    def search_and_destroy(data=None, *args, **kawargs):
        brain.update()
        
        center = unit.ask_center()
        cpos = center['coordinates']
        assert brain.terrain[cpos[0]][cpos[1]] == TILE.CENTER, 'CENTER NOT FOUND'
        mypos = unit.ask_my_info()['coordinates']
        if center["hit_points"]>0:
            if dist(cpos, mypos) < brain.fire_range:
                print('attacking center')
                unit.attack_item(center['id'])
                unit.subscribe_the_item_is_dead(center['id'], search_and_destroy)
            else:
                print('walking')
                p = path.pop()
                print(p)
                unit.move_to_point(p)
                
                unit.do_move(midpoint(cpos, mypos))
                
                unit.subscribe_im_idle(search_and_destroy)
        else:
            print('attacking other')
            eid=  unit.ask_nearest_enemy()['id']
            unit.attack_item(eid)
            unit.subscribe_the_item_is_dead(eid, search_and_destroy)
        unit.move_to_point((mypos+[0,brain.terrain.evil_callback]))
    
    #######
    TILE = Enum('TileContent', 'EMPTY UNIT ROCK BUILDING TURRET CENTER UNKNOWN')
    STATE = Enum("State", "ATTACKING FLEEING MOVING")
    MappedRoles = {
        ROLE.UNIT:TILE.UNIT,
        ROLE.BUILDING:TILE.BUILDING,
        ROLE.OBSTACLE:TILE.ROCK,
        ROLE.TOWER:TILE.TURRET,
        ROLE.CENTER:TILE.CENTER
        }
        
    if __name__ == "__main__":
        unit = commander.Client()
        brain = Brain(unit, True)
        cx,cy=unit.ask_center()['coordinates']
        path = brain.goto((cx,cy),4)
        path.reverse()
    
        brain.terrain.get_rect_from_center((2,2),0)
        brain.terrain.get_rect_from_center((2,2),1)
        brain.terrain.get_rect_from_center((2,2),-1)
        brain.terrain.get_rect_from_center((2,2),2)
        brain.terrain.get_rect_from_center((5,5),3)
    
        search_and_destroy()
  • 相关阅读:
    MySQL 5.7以上 root用户默认密码问题
    Win10秘笈:两种方式修改网卡物理地址(MAC)
    Win10秘笈:两种方式修改网卡物理地址(MAC)
    MySQL——修改root密码的4种方法(以windows为例)
    每天一个linux命令:df 命令
    linux-Centos下磁盘管理(fdisk)
    我的云栖社区博客, 支持一下呗~~
    服务器操作系统应该选择 Debian/Ubuntu 还是 CentOS?
    服务器操作系统应该选择Debian/Ubuntu还是CentOS?
    经典网络还是VPC,开发者作何选择?
  • 原文地址:https://www.cnblogs.com/fengbo1113/p/8095185.html
Copyright © 2020-2023  润新知