yes, that was the issue I was seeing... but is fixed here, takes into account diagonal movement cost being higher so no more wide arcs - one other 'improvement' could be if there are multiple neighboring tiles with same low heatmap value, then have agent randomly pick which one to use... but not a big issue for the effort to do so, i think.
Was also playing with the world size and the heatmap generation get noticeably slower when you double or triple the world size... just needs some optimization is all, i think.
Code: Select all
const MaxAgents = 45
const MaxMapSize = 31
type agentinfo
as integer x
as integer y
as integer done
end type
dim shared agents(MaxAgents) as agentinfo
type worldinfo
as integer terrain
as single heat
as integer occupied
end type
dim shared worldmap(MaxMapSize,MaxMapSize) as worldinfo
dim shared as single dist(-1 to 1, -1 to 1)
dim shared as single d
for sx as integer = -1 to 1
for sy as integer = -1 to 1
d = 3
if sx = 0 or sy = 0 then d = 2
dist(sx,sy) = d
next sy
next sx
dim shared as integer distance, distance2, frontier
dim shared as integer holder
dim shared chra as string
sub MakeHeatMap
distance = 0
do
frontier = distance
distance += 1
for i as integer = 1 to (MaxMapSize-1)
for j as integer = 1 to (MaxMapSize-1)
if worldmap(i,j).heat = frontier then 'found a frontier tile
' now put all the surrounding tiles into the next frontier
for sx as integer = -1 to 1
for sy as integer = -1 to 1
if sx = 0 and sy = 0 then
' do nothing if center
else
distance2 = frontier + dist(sx,sy)
select case worldmap(i+sx,j+sy).heat
case -1 'empty!
worldmap(i+sx,j+sy).heat = distance2
case 999
'wall, do nothing
case else
if worldmap(i+sx,j+sy).heat > distance2 then
worldmap(i+sx,j+sy).heat = distance2
end if
end select
end if
next sy
next sx
end if
next j
next i
loop until distance >= 120
end sub
' load WorldMap/heatmap
sub LoadMap
restore map
for i as integer = 0 to 31
for j as integer = 0 to 31
read worldmap(i,j).heat
next j
next i
end sub
' set initial positions of agents
sub PlaceAgents
erase agents
randomize
for a as integer = 1 to MaxAgents
do
agents(a).x = int(rnd * 28) + 2
agents(a).y = int(rnd * 28) + 2
loop until worldmap(agents(a).x, agents(a).y).heat <> 999 and worldmap(agents(a).x, agents(a).y).heat <> 0
worldmap(agents(a).x,agents(a).y).occupied = 1
next a
end sub
Const W = 1400, H = 600
ScreenRes W, H, 32
Width W\8, H\8 '' Use 8*8 font
distance = 0
dim tt as integer
cls
erase worldmap
LoadMap
MakeHeatMap
PlaceAgents
' ok all set now for agents to path...
' hit space key to step through pathfinding
do
' cls
' display map
color rgb(255,255,255),rgb(0,0,0)
locate 1, 10 : print using "Number of done agents = ## ";holder
locate 3,1
for i as integer = 0 to MaxMapSize
for j as integer = 0 to MaxMapSize
select case worldmap(i,j).heat
case -1
color rgb(0,0,0),rgb(0,0,0) ' nothing
case 999
color rgb(0,0,255),rgb(0,0,0) ' obstacle/wall
case 0
color rgb(0,255,0),rgb(0,0,0) ' destination
case else
color rgb(0,30,30),rgb(0,0,0) ' heatmap
end select
dim as integer agenthere = 0
for a as integer = 1 to MaxAgents
if (agents(a).x = i) and (agents(a).y = j) then agenthere = a
next a
if agenthere = 0 then
print using "###";worldmap(i,j).heat;
else
if agents(agenthere).done = 1 then ' agent is done
color rgb(255,255,255),rgb(0,0,0) 'if done then make him white
else
color rgb(255,0,0),rgb(0,0,0) ' not done? then make hime red
end if
chra = chr(65+agenthere)
print " ";chra;
end if
'pset (800+j,100+i)
'line (800+j*3,100+i*3) - step (2,2),,BF
next j
print : print ' next line
next i
' sleep
' if tt = 0 then tt = 1 : sleep 'only pause on the first time through to debug map
' move each agent to closest destination
for a as integer = 1 to MaxAgents
'find lowest surrounding tile on heatmap
dim as integer lowX, lowY, lowdist
dim as integer i = agents(a).x
dim as integer j = agents(a).y
lowdist = worldmap(i, j).heat
if lowdist <= 3 then agents(a).done = 1 'if he next to destination then done
if agents(a).done = 1 then
' re-run heatmap, first update with all done agents...
LoadMap
for b as integer = 1 to MaxAgents
if agents(b).done = 1 then worldmap(agents(b).x, agents(b).y).heat = 999
next b
MakeHeatMap
else ' if he is not done...
for sx as integer = -1 to 1
for sy as integer = -1 to 1
' is there a closer tile next to him?
dim as integer lx = i + sx, lY = j + sy
if sx = 0 and sy = 0 then
' his tile, ignore it
else
if worldmap(lX, lY).heat < lowdist then 'if lower and...
if worldmap(lX, lY).occupied = 0 then ' if not occupied...
lowX = lx : lowY = ly
lowdist = worldmap(lowX, lowY).heat
end if
end if
end if
next sy
next sx
if lowdist < worldmap(i, j).heat then 'found a closer square, so move him
worldmap(agents(a).x, agents(a).y).occupied = 0 'erase old location
agents(a).x = lowX : agents(a).y = lowY
worldmap(agents(a).x, agents(a).y).occupied = 1 'move to new location
end if
end if
next a
sleep 1
chra = inkey
holder = 0
'check to see if all agents are done, by totalling up all the 'done' agents
for a as integer = 1 to MaxAgents
holder = holder + agents(a).done
next a
if holder = MaxAgents then chra = "r" ' if all done then reset the map as if user pressed 'R' key...
if ucase(chra) = "R" then 'reset to new map
sleep 1000
cls
erase worldmap
LoadMap
MakeHeatMap
PlaceAgents
end if
loop until chra = chr(27)
end
' world map
' 0 = destination tile, 999 = obstacle
Map:
data 999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999
data 999, 0, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1, -1,999,999,999,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999,999,999,999,999, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1, -1, -1,999, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1,999, -1,999, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1,999, 0,999, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1,999,999,999, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1,999, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1,999,999,999,999,999,999,999,999,999, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1,999,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1,999, -1, -1, -1, -1, -1, -1,999,999,999, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1,999,999,999,999,999,999, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, 0, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,999
data 999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999