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.width:
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)) #
if y0>0 and diag:
res.append((x0-1,y0-1)) #
if y0 < self.height-1 and diag:
res.append((x0-1,y0+1)) # if y0>0:
res.append((x0,y0-1)) # if x0 < self.width-1:
res.append((x0+1,y0)) #
if y0 < self.height-1 and diag:
res.append((x0+1,y0+1)) #
if y0>0 and diag:
res.append((x0+1,y0-1)) # if y0 < self.height-1:
res.append((x0,y0+1)) # 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()

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

  1. python目标定位(借鉴csdn上大神)

    写博客是为了记录下来,毕竟好多东西记不住,看过就忘了,收藏又太多,还不如搬运到自己博客下面,随时可翻~~~ 近期再学目标识别与定位,看着原理都很简单,但是真自己做,又觉得困难重重. csdn上一个大神 ...

  2. 【python】抄写大神的糗事百科代码

    照着静觅大神的博客学习,原文在这:http://cuiqingcai.com/990.html 划重点: 1. str.strip() strip函数会把字符串的前后多余的空白字符去掉 2. resp ...

  3. LHC大神问的矩阵转置问题

    数学中线性代数中提到的矩阵转置,其实在我们的业务场景中也有需要的地方,比如LHC大神问到的这个问题 那么如何进行行列转换呢? 代码如下: <?php $array=array( '部门1'=&g ...

  4. github下载大文件太慢/失败

    场景 github下载大文件,使用浏览器下载zip包到本地在下载到1G时失败, 使用 git clone ssh下载速度20k/s以下,已fq. 解决方法(亲测) 1.下载Github Desktop ...

  5. 大学四年因为分享了这些软件测试常用软件,我成了别人眼中的(lei)大神(feng)!

    依稀记得,毕业那天,我们辅导员发给我毕业证的时候对我说"你可是咱们系的风云人物啊",哎呀,别提当时多开心啦????,嗯,我们辅导员是所有辅导员中最漂亮的一个,真的???? 不过,辅 ...

  6. 对话机器学习大神Yoshua Bengio(上)

    Yoshua Bengio教授(个人主页)是机器学习大神之一,尤其是在深度学习这个领域.他连同Geoff Hinton老先生以及 Yann LeCun(燕乐存)教授,缔造了2006年开始的深度学习复兴 ...

  7. 对话机器学习大神Yoshua Bengio(下)

    对话机器学习大神Yoshua Bengio(下) Yoshua Bengio教授(个人主页)是机器学习大神之一,尤其是在深度学习这个领域.他连同Geoff Hinton老先生以及 Yann LeCun ...

  8. 每一个程序员都应该知道的高并发处理技巧、创业公司如何解决高并发问题、互联网高并发问题解决思路、caoz大神多年经验总结分享

    本文来源于caoz梦呓公众号高并发专辑,以图形化.松耦合的方式,对互联网高并发问题做了详细解读与分析,"技术在短期内被高估,而在长期中又被低估",而不同的场景和人员成本又导致了巨头 ...

  9. 听SEO大神夜息分享

    今天偶然听说了百度站长平台,又偶然在上面发现了夜息大神的分享(http://zhanzhang.baidu.com/college/videoinfo?id=871). 之前对于SEO的了解只限于减少 ...

随机推荐

  1. Mantis优化改造(功能篇)

    共分为两篇,功能篇和技术篇. 时间大约是2016年冬天. 考虑搭一个用于Bug管理和追踪的系统. 综合比较下,选择了小巧的开源工具,Mantis. 在源码基础上,做代码修改,完成了定制版的优化改造. ...

  2. 跟我一起玩Win32开发(14):用对话框作为主窗口

    前面我们在编写Win32应用程序的思路都是: 1.设计窗口类.2.注册窗口类.3.创建窗口.…… 然而,当我们接触控件以后, 会发现一个问题,我们在窗口上放置控件实在不好弄,而资源中的对话框具有图形编 ...

  3. Android课程设计第四天ListView运用

    注意:课程设计只为完成任务,不做细节描述~ 效果图 <?xml version="1.0" encoding="utf-8"?> <Relat ...

  4. pyinstaller打包遇到的错误处理

    在python环境中运行中没问题,但打包时遇到以下问题 1.有时打包出现 UnicodeDecodeError错误, 可以改变cmd的编码(暂且这么叫),在cmd 中输入 chcp 65001,再次打 ...

  5. Angularjs中表格的增删改查

    在一个管理系统中,不外乎都是增删改查.现在比如有个表格,我想修改当前行的数据,如下图所示 一点击修改的时候,当前页面我需要修改的数据,变成能修改的样式,点击保存能保存当前修改的数据,如下图所示 需要引 ...

  6. NIO客户端主要创建过程

    NIO客户端主要创建过程:   步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下:    SocketChannel client ...

  7. Git之远程项目克隆到本地配置

    远程代码克隆到本地工作区,需要进行简单的配置,用于识别身份 1.git config --global user.name    [设置用户名,你的github用户名] 2.git config -- ...

  8. ArrayList不同循环方式

    一: ArrayList<String> list = new ArrayList<String>();  list.add("1");  list.add ...

  9. Android获取声音长度

    代码 MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever(); metaRetriever.setDataSource( ...

  10. laravel学习笔记(二)

    路由 HTTP方法:支持http1.1中所有类型传参方式,get,post,put,delete,options,patch Route::get($url,$callback); 路由参数: Rou ...