[Lua] - GetDistance() Avoid Placing Near Cities

Come in here to talk about your sky-net style world-destroying super bots!

Moderator: Defcon moderators

User avatar
Ace Rimmer
level5
level5
Posts: 10803
Joined: Thu Dec 07, 2006 9:46 pm
Location: The Multiverse

Postby Ace Rimmer » Thu Feb 18, 2010 10:18 pm

Update:

I was able to incorporated the code for 'more variance on placement' above, though changing the GeneratePosition() lowerlimit to 0/upper limit to 25 (entire eastern NA seaboard+) and crank up the repeat to 1000 and it works perfectly.

An off-label use of this code that just occurred to me: Naval nuking target selection when the enemy is moving and they're not visible any longer (based on last known location and velocity and/or speed of the unit; find max possible travel distance, nuke in that radius). Or, just because you need a random bunch of sea nukes in a particular area. :twisted:

Results of the above:

Image

I was looking for a quick way to place ground units in the middle of a bunch of cities (think EU) without getting too close, no matter which map/territory is used. This is perfect, especially as now the bot will be able to get right between the 'cracks', so to speak. See yellow circles (placement locations right between two blast-zones but in neither.

Edit: Once again, thanks! Perhaps the Bot will now randomly remind forum users about their avatar size (based on KeyID, of course). :twisted:
User avatar
roflamingo
level3
level3
Posts: 404
Joined: Fri Jan 19, 2007 10:25 am

Postby roflamingo » Thu Feb 18, 2010 11:17 pm

On what are you basing the starting location to search? Ace-Rimmer experience?
User avatar
Ace Rimmer
level5
level5
Posts: 10803
Joined: Thu Dec 07, 2006 9:46 pm
Location: The Multiverse

Postby Ace Rimmer » Thu Feb 18, 2010 11:41 pm

Question:
roflamingo wrote:On what are you basing the starting location to search?

Answer:
roflamingo wrote:Ace Rimmer experience.


Yep, as far as I'm concerned, the (my) bot doesn't need learn anything, assuming I can program it to play as I would. Does that mean I think I'm the greatest Defcon player eva? Nope, just that a Bot that can micromanage/resource manage/uber multitask what I'd do in a game would be good enough to beat 100% of the players 90% of the time (including me). Again, that's assuming I can program it properly.

In short: Gamma[Bot] should = Ace Rimmer + AI decisionmaking/commandperforming speed.

Perhaps somebody that knows how to make a learning bot could take my finished product and help it make better decisions. ? That's a ways away though.
Smoke me a kipper, I'll be back for breakfast...
User avatar
roflamingo
level3
level3
Posts: 404
Joined: Fri Jan 19, 2007 10:25 am

Postby roflamingo » Thu Feb 18, 2010 11:53 pm

We have very similar goals. My head spins from trying to pick strategies but at least I want it to be good at the placement and naval-micro levels.



I've spent the last week getting ROFLBot to pick a good starting space based on the following criteria:

- find the city that i have that is closest to the other cities I have (i.e. the most neighboring cities, where distance to neighbor is between 4 and 10.
- start there.
- now determine a location starting here that is at least 20 units away from an enemy's border (note if it's foreign land (or water) but not enemy-run, it's ok)

This part works pretty well. I can pick a starting point near the top of russia (and even kind of guarding cities) even with Europe, Africa, Asia all as enemies, without being in any of their radar ranges.


...

- this becomes the starting point for starting to drop down silos.
- i am trying to read your note on the logic for placing silos where distance > 1.8 from any own city but haven't grasped it all yet. It's my next step.

Obviously dropping Radars should come earlier in the order.

I'm sharing the code with you (especially my DrawRadiatingSpokes), in case any of it interests you.

Code: Select all

function OnFirstTick()

StartLongTask(function()

-- Put Cities and Territories in Tables
myCities ={}
enemyCities = {}
enemyTerritories = ""

local allCities = GetCityIDs()
local us = GetOwnTeamID()

   for i, city in next, allCities do
     if city:GetTeamID() == us then
        table.insert(myCities, city)
         myTerritoryName = GetTerritoryName(city:GetLongitude(), city:GetLatitude() )
      YieldLongTask()
   else
        table.insert(enemyCities, city)
--      SendChat(GetTerritoryName(city:GetLongitude(), city:GetLatitude() ) .. " - " .. city:GetLongitude() .. " - " .. city:GetLatitude() )
      enemyTerritories = enemyTerritories .. GetTerritoryName(city:GetLongitude(), city:GetLatitude() )
      YieldLongTask()
 end
 end
  YieldLongTask()

-- List out the Enemy Territories
SendChat(enemyTerritories)

-- find the 4 cities that are most connected to other cities (city that has the most close neighbors) 
myMostConnectedCities ={}
local runningcounter = 0
local keycitylong = 0
local keycitylat = 0
local connecteddistance = math.random(4,10)

for i, city in ipairs(myCities) do
      counter = 0
      DrawWhiteboardCross(myCities[i]:GetLongitude(), myCities[i]:GetLatitude(), 0.5)
      YieldLongTask()
      
      for j, city in ipairs(myCities) do
         if GetRealDistance(myCities[i]:GetLongitude(), myCities[i]:GetLatitude(), myCities[j]:GetLongitude(), myCities[j]:GetLatitude() ) < connecteddistance then
          WhiteboardDraw(myCities[i]:GetLongitude(), myCities[i]:GetLatitude(), myCities[j]:GetLongitude(), myCities[j]:GetLatitude())
         counter = counter + 1
         end
      end
      table.insert(myMostConnectedCities, thiscounter)
      -- SendChat(i .. "-" .. counter)
      if counter > runningcounter then
      runningcounter = counter
      keycitylong = myCities[i]:GetLongitude()
      keycitylat = myCities[i]:GetLatitude()
      keycity = i
      end
   YieldLongTask()
end

-- show the 1 most connected city
SendChat("Key City - " .. keycity .. " - " .. keycitylong .. " - " .. keycitylat )

-- find a starting location for silos that isnt within 20 distance units from enemy territory
keycitylat = keycitylat + 1.8
dx = 0
dy = 0
tooclosetoenemyradar = true

repeat
    SendChat("Start at " ..  dx .. " - " .. dy)
   DrawRadiatingSpokes(keycitylong , keycitylat , 21.8)
   -- DrawRadiatingSpokes(keycitylong , keycitylat , 20)
   YieldLongTask()
   keycitylong = keycitylong - dx /12
   keycitylat = keycitylong - dy/12
until tooclosetoenemyradar == false
SendChat("ok")

SendChat("Erasing Whiteboard")
WhiteboardClear ()


-- where we are at is close to our cities and far from enemry radar
-- so start trying to place silos

silos = {}

SendChat(keycitylong .. " - " .. keycitylat)


if IsValidPlacementLocation (keycitylong, keycitylat, "Silo") then
PlaceStructure (keycitylong, keycitylat, "Silo")
end
YieldLongTask()

   end)

 

-- loop to output Defcon Level as it changes
  local DefconLevel

  StartLongTask(function()
    repeat
      local Level = GetDefconLevel()
      if Level ~= DefconLevel then
--        SendChat(("it's DEFCON %i already!"):format(Level), "public")
        DefconLevel = Level
      end
      YieldLongTask()
      YieldLongTask()
      YieldLongTask()
      YieldLongTask()
    until Level == 1
    SendChat("Prepare to feel the wrath of my nuclear weaponry!", "public")
  end)
end

function OnTickReal()
  WorkOnLongTasks()
  if GetGameTick() % 60 == 0 then
--     SendChat("Tick" .. GetGameTick())
   end
end

function OnEvent(eventType, sourceID, targetID, unitType, longitude, latitude)
  print(eventType, ",", tostring(sourceID), ",", tostring(targetID), ",", unitType, (", %.3f , %.3f"):format(longitude, latitude))
end

function OnShutdown()
end

-- Redefine print to write to the alliance chat channel
function print(...)
  local args = {...}
  local n = select('#', ...)
  local tostring = tostring
  local txt = {}
  for i = 1, n do
    if i ~= 1 then
      txt[#txt + 1] = " "
    end
    txt[#txt + 1] = tostring(args[i])
  end
  SendChat(table.concat(txt), "alliance")
end

-- Simple coroutine management functions
local co, pairs, assert = coroutine, pairs, assert
local long_tasks_in_progress = {}

function StartLongTask(f)
  long_tasks_in_progress[co.create(f)] = true
end

function WorkOnLongTasks(...)
  for c in pairs(long_tasks_in_progress) do
    if co.status(c) == "dead" then
      long_tasks_in_progress[c] = nil
    else
      assert(co.resume(c, ...))
    end
  end
end

YieldLongTask = co.yield


-- Extra whiteboard functions
function DrawWhiteboardCross(x, y, size)
   WhiteboardDraw(x - size, y - size, x + size, y + size)
   WhiteboardDraw(x - size, y + size, x + size, y - size)
end

function DrawWhiteboardSquare(x, y, size)
   WhiteboardDraw(x - size, y - size, x + size, y - size)
   WhiteboardDraw(x + size, y - size, x + size, y + size)
   WhiteboardDraw(x + size, y + size, x - size, y + size)
   WhiteboardDraw(x - size, y + size, x - size, y - size)
end

   function DrawBadWhiteboardCircle(x, y, radius)
     local mrandom, msin, mcos, pi = math.random, math.sin, math.cos, math.pi
     local segments = mrandom(7, 14)
     local theta_step = pi * 2 / segments
     local sin, cos = msin(theta_step), mcos(theta_step)
     local irot = mrandom() * 2 * pi
     local dx = mcos(irot) * radius
     local dy = msin(irot) * radius
      for i = 1, segments + mrandom(2, segments - 2) do
         local nx = cos * dx - sin * dy + mrandom(-2, 2) / 10
         local ny = sin * dx + cos * dy + mrandom(-2, 2) / 10
         WhiteboardDraw(x + dx, y + dy, x + nx, y + ny)
         dx, dy = nx, ny
      end
   end   

   function DrawGoodWhiteboardCircle(x, y, radius)
     local segments = 20
     local theta_step = math.pi * 2 / segments
     local sin, cos = math.sin(theta_step), math.cos(theta_step)
     local dx = radius
     local dy = 0
      for i = 1, segments do
         local nx = cos * dx - sin * dy
         local ny = sin * dx + cos * dy
         WhiteboardDraw(x + dx, y + dy, x + nx, y + ny)
         dx, dy = nx, ny
      end
   end
 
function GetRealDistance(x1,y1,x2,y2)
  dist = math.sqrt((x2-x1)^2 + (y2-y1)^2)
  return dist
  end


-- find if position is too close to enemy
   function DrawRadiatingSpokes(x, y, radius)
     DrawWhiteboardSquare(x,y,5)
     tooclosetoenemyradar = false
     -- local segments = 24
     local segments = 40
     local theta_step = math.pi * 2 / segments
     local sin, cos = math.sin(theta_step), math.cos(theta_step)
     dx = radius
     dy = 0
    
      for i = 1, segments do
         local nx = cos * dx - sin * dy
         local ny = sin * dx + cos * dy
         WhiteboardDraw(x,y ,x + dx, y + dy)
         
         if GetTerritoryName(x + dx, y + dy) ~= nil and GetTerritoryName(x + dx, y + dy) ~= myTerritoryName then
            if string.find(enemyTerritories, GetTerritoryName(x + dx, y + dy) )  ~= nil then
            tooclosetoenemyradar = true
            -- SendChat("... too close to " .. GetTerritoryName(x + dx, y + dy) .. " - dx = " .. dx .. " and dy = " .. dy)
            return tooclosetoenemyradar, dx, dy
            end
         end
      dx, dy = nx, ny
      end
       -- return tooclosetoenemyradar, dx, dy
    end
 
 
User avatar
Ace Rimmer
level5
level5
Posts: 10803
Joined: Thu Dec 07, 2006 9:46 pm
Location: The Multiverse

Postby Ace Rimmer » Fri Feb 19, 2010 12:06 am

I'll say that I don't agree with (but understand) your starting point ideology, although I'm curious to see how it works.

As for my distance > 1.8, it's pretty simple (unless I misunderstand exactly what you're referring to):

You don't want to place any ground unit (Radar, Airbase, or Silo) within a radius of 1.8 of any city. If you do, you take the risk of having that unit damaged or destroyed when the other player strikes the city, even if they don't know there's a unit there. If they do know, they can just target the city, get the points for population, and damage/kill the unit as an intended bonus. Side note: you get less points by targeting the unit and not the city as splash damage is lower than direct damage.

So, the whole point of this thread was for me to figure out how to tell the bot where not to place, regardless of who the enemy is. That is, don't place a unit inside the blast radius of any city. I'll post some before and after placement pics once I work out how to incorporate the code above (top of this page) into my existing placement code.

Does that help, or did I just explain what you already knew?
User avatar
roflamingo
level3
level3
Posts: 404
Joined: Fri Jan 19, 2007 10:25 am

Postby roflamingo » Fri Feb 19, 2010 12:21 am

Ace Rimmer wrote:Does that help, or did I just explain what you already knew?


I believe I understood the intent since the start of the thread. I'm trying to absorb the logic in the LUA code to see if I can jig it into mine.

I want to be able to drop in my silos in places that A. best defend the greatest # of cities B. are not locatable through enemy ground radar and C. are close enough together for group defense and group strikes. D. won't be hit with splash damage (dist to any city > 1.8)

I have A and B down and the logic for C. I just need D.



As for the initial placement, I could basically have said "start here" for 6 continents but I believe placement decisions need to also revolve around A. where are my cities (potential random start, not just the same 25 cities as always) B. are my neighbors allies, enemies, or neither. E.g. your ground positions in Europe or Russia change depending if the other is an enemy or an ally. And also depend if Africa or Asia are allies. Or enemies. Or don't exist. (You can more readily silo-protect Moscow if there's no Europe or Asian radar).

If you boot up my code and watch the whiteboard you will see what happens. I have this feeling for a lot of combinations of # of players, allies, enemies it will end up pretty close to "competitive-Defcon optimal". Obviously for some it won't (notably Asia and S.America), but it will get there.
User avatar
Ace Rimmer
level5
level5
Posts: 10803
Joined: Thu Dec 07, 2006 9:46 pm
Location: The Multiverse

Postby Ace Rimmer » Fri Feb 19, 2010 12:35 am

I have tried and can't get it to load. When I put it in an existing file and just point to then functions, it does some fancy whiteboard drawing but doesn't place anything. About to leave so I'll have to trouble shoot later. :roll:
Smoke me a kipper, I'll be back for breakfast...
User avatar
roflamingo
level3
level3
Posts: 404
Joined: Fri Jan 19, 2007 10:25 am

Postby roflamingo » Fri Feb 19, 2010 12:39 am

Ace Rimmer wrote:I have tried and can't get it to load. When I put it in an existing file and just point to then functions, it does some fancy whiteboard drawing but doesn't place anything. About to leave so I'll have to trouble shoot later. :roll:


-- Remove the whiteboard erase line from the code.

1. The first lines are figuring out who is the most connected city
2. The starbursts are now finding a point close to that most connected city that is outside of radar range of all potential opponents.
a. At this point theis initial position might be in the water. Don't let the bot be EU or SA at this point and it should all work out.

Ya I think you are 7 hours ahead of me... so more later.
User avatar
Ace Rimmer
level5
level5
Posts: 10803
Joined: Thu Dec 07, 2006 9:46 pm
Location: The Multiverse

Postby Ace Rimmer » Fri Feb 19, 2010 2:58 am

Ok, so I didn't change anything (except the whiteboard clear) and I did see it place in one combination. Pretty nice. I'm sure you're aware that it does some strange things though (e.g., starburst in the black above arctic). :?:

This might be just right for six player FFA (with some retro-coding for suisilos). :D

For not, my bot will only be 1v1. Once I beta test it in the field, I'll 'level up' to 2v2 . That is, while live 1v1 trials are going on, I'll be working with 2v2 code (alliances, *interactive commands, chat, etc.)

*I haven't fully thought this out, but I'm guessing the bot would be able to read player chat through some combination of dedcon settings and io command? Big assumptions on my part I'm sure.

Either way, very nice code. I'm sure I'll examine it thoroughly, at least for coding technique if nothing else. It sure helps to see coding that's context relative and not just random examples from other programs (Google). :wink:
Smoke me a kipper, I'll be back for breakfast...
User avatar
roflamingo
level3
level3
Posts: 404
Joined: Fri Jan 19, 2007 10:25 am

Postby roflamingo » Fri Feb 19, 2010 7:11 am

I spotted some errors in the code and made some changes. It should only starburst close to land!
Maybe the changes I have made will correct that.

At any rate, it will be time to try to drop in a 6 pack of silos such that none of them are within 1.8 of a city....

Thanks for the compliment... I don't work on this full time, maybe an hour a night!

Code: Select all


-- Make require look in this folder
package.path = [[AI\luabot\?.lua;"]] .. package.path

function OnInit()
  SendChat "/name [Bot]ROFLbot"
  SendChat("I am ROFLbot, written in lua version of defcon API")
  SendChat("contact ROFLamingo via the forums or email (scallbe1@hotmail.com)")
end
 
function OnTick()
  OnFirstTick()
  OnTick = OnTickReal
  return OnTick()
end


--enumerate our cities, opponent cities, position, population
function OnFirstTick()

StartLongTask(function()

-- Put Cities and Territories in Tables
myCities ={}
enemyCities = {}
enemyTerritories = ""

local allCities = GetCityIDs()
local us = GetOwnTeamID()

   for i, city in next, allCities do
     if city:GetTeamID() == us then
        table.insert(myCities, city)
         myTerritoryName = GetTerritoryName(city:GetLongitude(), city:GetLatitude() )
      YieldLongTask()
   else
        table.insert(enemyCities, city)
      enemyTerritories = enemyTerritories .. GetTerritoryName(city:GetLongitude(), city:GetLatitude() )
      YieldLongTask()
 end
 end
  YieldLongTask()

-- List out the Enemy Territories
SendChat(enemyTerritories)

-- find the 4 cities that are most connected to other cities (city that has the most close neighbors) 
myMostConnectedCities ={}
local runningcounter = 0
local keycitylong = 0
local keycitylat = 0
local connecteddistance = math.random(4,10)

for i, city in ipairs(myCities) do
      counter = 0
      DrawWhiteboardCross(myCities[i]:GetLongitude(), myCities[i]:GetLatitude(), 0.5)
      YieldLongTask()
      
      for j, city in ipairs(myCities) do
         if GetRealDistance(myCities[i]:GetLongitude(), myCities[i]:GetLatitude(), myCities[j]:GetLongitude(), myCities[j]:GetLatitude() ) < connecteddistance then
          WhiteboardDraw(myCities[i]:GetLongitude(), myCities[i]:GetLatitude(), myCities[j]:GetLongitude(), myCities[j]:GetLatitude())
         counter = counter + 1
         end
      end
      table.insert(myMostConnectedCities, thiscounter)
      -- SendChat(i .. "-" .. counter)
      if counter > runningcounter then
      runningcounter = counter
      keycitylong = myCities[i]:GetLongitude()
      keycitylat = myCities[i]:GetLatitude()
      keycity = i
      end
   YieldLongTask()
end

-- show the 1 most connected city
SendChat("Key City - " .. keycity .. " - " .. keycitylong .. " - " .. keycitylat )

-- find a starting location for silos that isnt within 20 distance units from enemy territory
keycitylat = keycitylat + 1.8
dx = 0
dy = 0
tooclosetoenemyradar = true

repeat
    SendChat("Start at " ..  dx .. " - " .. dy)
   DrawRadiatingSpokes(keycitylong , keycitylat , 21.8)
   -- DrawRadiatingSpokes(keycitylong , keycitylat , 20)
   YieldLongTask()
   
   -- SendChat(dx .. " - " .. dy)
   

   keycitylong = keycitylong - dx /12
   keycitylat = keycitylat - dy /12
   --keycitylong = keycitylong - 0.5 * dx/math.pow(dx,0)
   --keycitylat = keycitylat - 0.5 * dy/math.pow(dy,0)
until tooclosetoenemyradar == false
SendChat("ok")

-- SendChat("Erasing Whiteboard")
-- WhiteboardClear ()


-- where we are at is close to our cities and far from enemy radar
-- so start trying to place silos

silos = {}

SendChat(keycitylong .. " - " .. keycitylat)

DrawWhiteboardCross(keycitylong, keycitylat, 2)
DrawWhiteboardSquare(keycitylong, keycitylat, 2)


if not IsValidPlacementLocation (keycitylong, keycitylat, "Silo") then
PlaceStructure (keycitylong, keycitylat, "Silo")
end
YieldLongTask()

   end)

 

-- loop to output Defcon Level as it changes
  local DefconLevel

  StartLongTask(function()
    repeat
      local Level = GetDefconLevel()
      if Level ~= DefconLevel then
--        SendChat(("it's DEFCON %i already!"):format(Level), "public")
        DefconLevel = Level
      end
      YieldLongTask()
      YieldLongTask()
      YieldLongTask()
      YieldLongTask()
    until Level == 1
    SendChat("Prepare to feel the wrath of my nuclear weaponry!", "public")
  end)
end

function OnTickReal()
  WorkOnLongTasks()
  if GetGameTick() % 60 == 0 then
--     SendChat("Tick" .. GetGameTick())
   end
end

function OnEvent(eventType, sourceID, targetID, unitType, longitude, latitude)
  print(eventType, ",", tostring(sourceID), ",", tostring(targetID), ",", unitType, (", %.3f , %.3f"):format(longitude, latitude))
end

function OnShutdown()
end

-- Redefine print to write to the alliance chat channel
function print(...)
  local args = {...}
  local n = select('#', ...)
  local tostring = tostring
  local txt = {}
  for i = 1, n do
    if i ~= 1 then
      txt[#txt + 1] = " "
    end
    txt[#txt + 1] = tostring(args[i])
  end
  SendChat(table.concat(txt), "alliance")
end

-- Simple coroutine management functions
local co, pairs, assert = coroutine, pairs, assert
local long_tasks_in_progress = {}

function StartLongTask(f)
  long_tasks_in_progress[co.create(f)] = true
end

function WorkOnLongTasks(...)
  for c in pairs(long_tasks_in_progress) do
    if co.status(c) == "dead" then
      long_tasks_in_progress[c] = nil
    else
      assert(co.resume(c, ...))
    end
  end
end

YieldLongTask = co.yield


-- Extra whiteboard functions
function DrawWhiteboardCross(x, y, size)
   WhiteboardDraw(x - size, y - size, x + size, y + size)
   WhiteboardDraw(x - size, y + size, x + size, y - size)
end

function DrawWhiteboardSquare(x, y, size)
   WhiteboardDraw(x - size, y - size, x + size, y - size)
   WhiteboardDraw(x + size, y - size, x + size, y + size)
   WhiteboardDraw(x + size, y + size, x - size, y + size)
   WhiteboardDraw(x - size, y + size, x - size, y - size)
end

   function DrawBadWhiteboardCircle(x, y, radius)
     local mrandom, msin, mcos, pi = math.random, math.sin, math.cos, math.pi
     local segments = mrandom(7, 14)
     local theta_step = pi * 2 / segments
     local sin, cos = msin(theta_step), mcos(theta_step)
     local irot = mrandom() * 2 * pi
     local dx = mcos(irot) * radius
     local dy = msin(irot) * radius
      for i = 1, segments + mrandom(2, segments - 2) do
         local nx = cos * dx - sin * dy + mrandom(-2, 2) / 10
         local ny = sin * dx + cos * dy + mrandom(-2, 2) / 10
         WhiteboardDraw(x + dx, y + dy, x + nx, y + ny)
         dx, dy = nx, ny
      end
   end   

   function DrawGoodWhiteboardCircle(x, y, radius)
     local segments = 20
     local theta_step = math.pi * 2 / segments
     local sin, cos = math.sin(theta_step), math.cos(theta_step)
     local dx = radius
     local dy = 0
      for i = 1, segments do
         local nx = cos * dx - sin * dy
         local ny = sin * dx + cos * dy
         WhiteboardDraw(x + dx, y + dy, x + nx, y + ny)
         dx, dy = nx, ny
      end
   end
 
function GetRealDistance(x1,y1,x2,y2)
  dist = math.sqrt((x2-x1)^2 + (y2-y1)^2)
  return dist
  end


-- find if position is too close to enemy
   function DrawRadiatingSpokes(x, y, radius)
     DrawWhiteboardSquare(x,y,5)
     tooclosetoenemyradar = false
     local segments = 24
     -- local segments = 40
     local theta_step = math.pi * 2 / segments
     local sin, cos = math.sin(theta_step), math.cos(theta_step)
     dx = radius
     dy = 0
    
      for i = 1, segments do
         local nx = cos * dx - sin * dy
         local ny = sin * dx + cos * dy
         WhiteboardDraw(x,y ,x + dx, y + dy)
         
         if GetTerritoryName(x + dx, y + dy) ~= nil and GetTerritoryName(x + dx, y + dy) ~= myTerritoryName then
            if string.find(enemyTerritories, GetTerritoryName(x + dx, y + dy) )  ~= nil then
            tooclosetoenemyradar = true
            SendChat("... too close to " .. GetTerritoryName(x + dx, y + dy) .. " - dx = " .. dx .. " and dy = " .. dy)
            return tooclosetoenemyradar, dx, dy
            end
         end
      dx, dy = nx, ny
      end
      
       if tooclosetoenemyradar == false then
      dx = 0
      dy = 0
      return tooclosetoenemyradar, dx, dy
      end
    end
 

Return to “AI Bots”

Who is online

Users browsing this forum: No registered users and 0 guests