function sqr(x)
return x*x
end
function Distance(x1, y1, x2, y2)
return math.sqrt(sqr(x1-x2) + sqr(y1-y2))
end
pathIndex = nil
--Стрелять в ближайшего врага
function ShootAtClosest()
local mX, mY = api:position(0) --Наши координаты
local n = api:count() --количество юнитов в радиусе видимости
local myOwner = api:owner(0)--наш номер игрока (владелец робота)
local closestEnemy = 1.5*api.field_size
local shotX = nil
local shotY = nil
for i = 1, n do
if (api:type(i) == 2) then -- Юнит - робот
local town = api:owner(i); -- Кому принадлежит робот
if (town ~= myOwner and town >= 0) then -- Если вражеский робот
local sx, sy = api:position(i) -- Позиция вражеского робота
local dist = Distance(sx, sy, mX, mY) -- Расстояние до него
if (dist < closestEnemy) then -- Проверка на кратчайшее расстояние
shotX, shotY = sx, sy -- Сохранение результата, если робот находится ближе чем предыдущий найденный
closestEnemy = dist;
end
end
end
end
if (shotX) then -- если нашли хоть одного в области видимости
api:shoot_at_pos(shotX, shotY)
else
api:shoot_stop()
end
end
function MoveToPoint(x, y) -- Двигаемся в точку x,y
local mX, mY = api:position(0)
api:move_by_delta(x-mX, y-mY)
end
last = nil
function good()
local mX, mY = api:position(0)
local n = api:count()
local myOwner = api:owner(0)
local bad = false
for i = 1, n do
if (api:type(i) == 2) then -- Юнит - робот
local town = api:owner(i); -- Кому принадлежит робот
if (town ~= myOwner and town >= 0) then -- Если вражеский робот
bad = true
end
end
end
if (bad) then
last = nil
return false
end
for i = 1, n do
if (api:type(i) == 1) then
local town = api:owner(i);
local sx, sy = api:position(i)
if (Distance(sx, sy, path[pathIndex].x, path[pathIndex].y) < 1e-5) then
if (town == myOwner) then
if (not last) then
last = api:time()
end
if (api:time() - last > 200) then
last = nil
return true
end
end
end
end
end
return false
end
function MoveAlongPath(path, isCycle) -- Двигаемся вдоль контура path, если isCycle = true, то зацикливаемся по контуру
if (path == nil) then
return
end
if (pathIndex == nil) then
pathIndex = 0
end
local mX, mY = api:position(0)
if (good()) then
pathIndex = pathIndex + 1
end
if (path[pathIndex] == nil) then
if (not isCycle) then
return
end
pathIndex = 0
end
MoveToPoint(path[pathIndex].x, path[pathIndex].y)
end
function Pass()
local mX, mY = api:position(0)
local n = api:count()
local myOwner = api:owner(0)
local closestFriend = 2.1*api:radius(0)
local friendX = nil
local friendY = nil
for i = 1, n do
if (api:type(i) == 2) then
local town = api:owner(i);
if (town == myOwner) then
local sx, sy = api:position(i)
local dist = Distance(sx, sy, mX, mY)
if (dist < closestFriend) then
friendX, friendY = sx, sy
closestFriend = dist;
end
end
end
end
if (friendX) then
api:move_by_delta((-friendX+mX) / 10 + (-friendY+mY), (-friendY+mY) / 10 - (-friendX+mX))
-- api:shoot_at_pos(0, 0)
return 1
end
return nil
end
function Think()
if (not Pass()) then
if (capture) then
MoveToPoint(capture.x, capture.y)
else
MoveAlongPath(path, true)
end
end
ShootAtClosest() -- Стреляем в ближайшего соперника
end
ZnVuY3Rpb24gc3FyKHgpCglyZXR1cm4geCp4CmVuZApmdW5jdGlvbiBEaXN0YW5jZSh4MSwgeTEsIHgyLCB5MikKCXJldHVybiBtYXRoLnNxcnQoc3FyKHgxLXgyKSArIHNxcih5MS15MikpCmVuZAoKcGF0aEluZGV4ID0gbmlsCgotLdCh0YLRgNC10LvRj9GC0Ywg0LIg0LHQu9C40LbQsNC50YjQtdCz0L4g0LLRgNCw0LPQsApmdW5jdGlvbiBTaG9vdEF0Q2xvc2VzdCgpCglsb2NhbCBtWCwgbVkgPSBhcGk6cG9zaXRpb24oMCkgLS3QndCw0YjQuCDQutC+0L7RgNC00LjQvdCw0YLRiwoJbG9jYWwgbiA9IGFwaTpjb3VudCgpIC0t0LrQvtC70LjRh9C10YHRgtCy0L4g0Y7QvdC40YLQvtCyINCyINGA0LDQtNC40YPRgdC1INCy0LjQtNC40LzQvtGB0YLQuAoJbG9jYWwgbXlPd25lciA9IGFwaTpvd25lcigwKS0t0L3QsNGIINC90L7QvNC10YAg0LjQs9GA0L7QutCwICjQstC70LDQtNC10LvQtdGGINGA0L7QsdC+0YLQsCkKCglsb2NhbCBjbG9zZXN0RW5lbXkgPSAxLjUqYXBpLmZpZWxkX3NpemUKCWxvY2FsIHNob3RYID0gbmlsCglsb2NhbCBzaG90WSA9IG5pbAoJZm9yIGkgPSAxLCBuIGRvCgkJaWYgKGFwaTp0eXBlKGkpID09IDIpIHRoZW4gLS0g0K7QvdC40YIgLSDRgNC+0LHQvtGCCgkJCWxvY2FsIHRvd24gPSBhcGk6b3duZXIoaSk7IC0tINCa0L7QvNGDINC/0YDQuNC90LDQtNC70LXQttC40YIg0YDQvtCx0L7RggoJCQlpZiAodG93biB+PSBteU93bmVyIGFuZCB0b3duID49IDApIHRoZW4gLS0g0JXRgdC70Lgg0LLRgNCw0LbQtdGB0LrQuNC5INGA0L7QsdC+0YIKCQkJCWxvY2FsIHN4LCBzeSA9IGFwaTpwb3NpdGlvbihpKSAtLSDQn9C+0LfQuNGG0LjRjyDQstGA0LDQttC10YHQutC+0LPQviDRgNC+0LHQvtGC0LAKCQkJCWxvY2FsIGRpc3QgPSBEaXN0YW5jZShzeCwgc3ksIG1YLCBtWSkgLS0g0KDQsNGB0YHRgtC+0Y/QvdC40LUg0LTQviDQvdC10LPQvgoJCQkJaWYgKGRpc3QgPCBjbG9zZXN0RW5lbXkpIHRoZW4gLS0g0J/RgNC+0LLQtdGA0LrQsCDQvdCwINC60YDQsNGC0YfQsNC50YjQtdC1INGA0LDRgdGB0YLQvtGP0L3QuNC1CgkJCQkJc2hvdFgsIHNob3RZID0gc3gsIHN5IC0tINCh0L7RhdGA0LDQvdC10L3QuNC1INGA0LXQt9GD0LvRjNGC0LDRgtCwLCDQtdGB0LvQuCDRgNC+0LHQvtGCINC90LDRhdC+0LTQuNGC0YHRjyDQsdC70LjQttC1INGH0LXQvCDQv9GA0LXQtNGL0LTRg9GJ0LjQuSDQvdCw0LnQtNC10L3QvdGL0LkKCQkJCQljbG9zZXN0RW5lbXkgPSBkaXN0OwoJCQkJZW5kCgkJCWVuZAoJCWVuZAoJZW5kCglpZiAoc2hvdFgpIHRoZW4gLS0g0LXRgdC70Lgg0L3QsNGI0LvQuCDRhdC+0YLRjCDQvtC00L3QvtCz0L4g0LIg0L7QsdC70LDRgdGC0Lgg0LLQuNC00LjQvNC+0YHRgtC4CgkJYXBpOnNob290X2F0X3BvcyhzaG90WCwgc2hvdFkpCgllbHNlCgkJYXBpOnNob290X3N0b3AoKQoJZW5kCmVuZAoKZnVuY3Rpb24gTW92ZVRvUG9pbnQoeCwgeSkgLS0g0JTQstC40LPQsNC10LzRgdGPINCyINGC0L7Rh9C60YMgeCx5Cglsb2NhbCBtWCwgbVkgPSBhcGk6cG9zaXRpb24oMCkKCWFwaTptb3ZlX2J5X2RlbHRhKHgtbVgsIHktbVkpCmVuZAoKbGFzdCA9IG5pbAoKZnVuY3Rpb24gZ29vZCgpCglsb2NhbCBtWCwgbVkgPSBhcGk6cG9zaXRpb24oMCkKCWxvY2FsIG4gPSBhcGk6Y291bnQoKQoJbG9jYWwgbXlPd25lciA9IGFwaTpvd25lcigwKQoKCWxvY2FsIGJhZCA9IGZhbHNlCgoJZm9yIGkgPSAxLCBuIGRvCgkJaWYgKGFwaTp0eXBlKGkpID09IDIpIHRoZW4gLS0g0K7QvdC40YIgLSDRgNC+0LHQvtGCCgkJCWxvY2FsIHRvd24gPSBhcGk6b3duZXIoaSk7IC0tINCa0L7QvNGDINC/0YDQuNC90LDQtNC70LXQttC40YIg0YDQvtCx0L7RggoJCQlpZiAodG93biB+PSBteU93bmVyIGFuZCB0b3duID49IDApIHRoZW4gLS0g0JXRgdC70Lgg0LLRgNCw0LbQtdGB0LrQuNC5INGA0L7QsdC+0YIKCQkJCWJhZCA9IHRydWUKCQkJZW5kCgkJZW5kCgllbmQKCglpZiAoYmFkKSB0aGVuCgkJbGFzdCA9IG5pbAoJCXJldHVybiBmYWxzZQoJZW5kCgoJZm9yIGkgPSAxLCBuIGRvCgkJaWYgKGFwaTp0eXBlKGkpID09IDEpIHRoZW4KCQkJbG9jYWwgdG93biA9IGFwaTpvd25lcihpKTsKCQkJbG9jYWwgc3gsIHN5ID0gYXBpOnBvc2l0aW9uKGkpCgkJCWlmIChEaXN0YW5jZShzeCwgc3ksIHBhdGhbcGF0aEluZGV4XS54LCBwYXRoW3BhdGhJbmRleF0ueSkgPCAxZS01KSB0aGVuCgkJCQlpZiAodG93biA9PSBteU93bmVyKSB0aGVuCgkJCQkJaWYgKG5vdCBsYXN0KSB0aGVuCgkJCQkJCWxhc3QgPSBhcGk6dGltZSgpCgkJCQkJZW5kCgkJCQkJaWYgKGFwaTp0aW1lKCkgLSBsYXN0ID4gMjAwKSB0aGVuCgkJCQkJCWxhc3QgPSBuaWwKCQkJCQkJcmV0dXJuIHRydWUKCQkJCQllbmQKCQkJCWVuZAoJCQllbmQKCQllbmQKCWVuZAoJcmV0dXJuIGZhbHNlCmVuZAoKZnVuY3Rpb24gTW92ZUFsb25nUGF0aChwYXRoLCBpc0N5Y2xlKSAtLSDQlNCy0LjQs9Cw0LXQvNGB0Y8g0LLQtNC+0LvRjCDQutC+0L3RgtGD0YDQsCBwYXRoLCDQtdGB0LvQuCBpc0N5Y2xlID0gdHJ1ZSwg0YLQviDQt9Cw0YbQuNC60LvQuNCy0LDQtdC80YHRjyDQv9C+INC60L7QvdGC0YPRgNGDCglpZiAocGF0aCA9PSBuaWwpIHRoZW4KCQlyZXR1cm4KCWVuZAoJaWYgKHBhdGhJbmRleCA9PSBuaWwpIHRoZW4KCQlwYXRoSW5kZXggPSAwCgllbmQKCWxvY2FsIG1YLCBtWSA9IGFwaTpwb3NpdGlvbigwKQoKCiAgICBpZiAoZ29vZCgpKSB0aGVuCgkJcGF0aEluZGV4ID0gcGF0aEluZGV4ICsgMQoJZW5kCglpZiAocGF0aFtwYXRoSW5kZXhdID09IG5pbCkgdGhlbgoJCWlmIChub3QgaXNDeWNsZSkgdGhlbgoJCQlyZXR1cm4KCQllbmQKCQlwYXRoSW5kZXggPSAwCgllbmQKCU1vdmVUb1BvaW50KHBhdGhbcGF0aEluZGV4XS54LCBwYXRoW3BhdGhJbmRleF0ueSkKZW5kCgpmdW5jdGlvbiBQYXNzKCkKCWxvY2FsIG1YLCBtWSA9IGFwaTpwb3NpdGlvbigwKQoJbG9jYWwgbiA9IGFwaTpjb3VudCgpCglsb2NhbCBteU93bmVyID0gYXBpOm93bmVyKDApCgoJbG9jYWwgY2xvc2VzdEZyaWVuZCA9IDIuMSphcGk6cmFkaXVzKDApCglsb2NhbCBmcmllbmRYID0gbmlsCglsb2NhbCBmcmllbmRZID0gbmlsCglmb3IgaSA9IDEsIG4gZG8KCQlpZiAoYXBpOnR5cGUoaSkgPT0gMikgdGhlbgoJCQlsb2NhbCB0b3duID0gYXBpOm93bmVyKGkpOwoJCQlpZiAodG93biA9PSBteU93bmVyKSB0aGVuCgkJCQlsb2NhbCBzeCwgc3kgPSBhcGk6cG9zaXRpb24oaSkKCQkJCWxvY2FsIGRpc3QgPSBEaXN0YW5jZShzeCwgc3ksIG1YLCBtWSkKCQkJCWlmIChkaXN0IDwgY2xvc2VzdEZyaWVuZCkgdGhlbgoJCQkJCWZyaWVuZFgsIGZyaWVuZFkgPSBzeCwgc3kKCQkJCQljbG9zZXN0RnJpZW5kID0gZGlzdDsKCQkJCWVuZAoJCQllbmQKCQllbmQKCWVuZAoJaWYgKGZyaWVuZFgpIHRoZW4KCQlhcGk6bW92ZV9ieV9kZWx0YSgoLWZyaWVuZFgrbVgpIC8gMTAgKyAoLWZyaWVuZFkrbVkpLCAoLWZyaWVuZFkrbVkpIC8gMTAgLSAoLWZyaWVuZFgrbVgpKQotLQkJYXBpOnNob290X2F0X3BvcygwLCAwKQoJCXJldHVybiAxCgllbmQKCXJldHVybiBuaWwKZW5kCgpmdW5jdGlvbiBUaGluaygpCglpZiAobm90IFBhc3MoKSkgdGhlbgoJCWlmIChjYXB0dXJlKSB0aGVuCgkJCU1vdmVUb1BvaW50KGNhcHR1cmUueCwgY2FwdHVyZS55KQoJCWVsc2UKCQkJTW92ZUFsb25nUGF0aChwYXRoLCB0cnVlKQoJCWVuZAoJZW5kCglTaG9vdEF0Q2xvc2VzdCgpIC0tINCh0YLRgNC10LvRj9C10Lwg0LIg0LHQu9C40LbQsNC50YjQtdCz0L4g0YHQvtC/0LXRgNC90LjQutCwCmVuZAo=