When foraging for food ants don't just walk randomly they meander (like a river) in a systematic way.
To simulate this I made it 50% likely they would step forward and 25% veer left and 25% veer right.
So far the code only implements a kind of search pattern, similar I think to a foraging ant, and the leaving of a scent trail.
The next step is returning to the nest with some of the food to stimulate more ants to help collect the food source using pheromone trails to find where the food is located. In this example a yellow pheromone trail which fades over time is left behind by the ant.
Pheromones are a powerful communication system and is received via an ants antenna. I don't know how much information ants can code in a pheromone but in a theoretical ant there are all sorts of possibilities. They can use scent trails to optimize the shortest path between two points. To simulate this I need to add obstacles around which they can travel by turning left or right on contact.
They do have a rudimentary vision systems as well. In its simplest form they can navigate using the sun and counting how many steps they have taken while travelling.
The nest opening is in the center of the display but not drawn.
Video on how ants follow pheromone trails.
https://youtu.be/3zvBtbBxNiE
https://youtu.be/81GQNPJip2Y
Code: Select all
screenres 640,480,32
color rgb(0,0,0),rgb(255,255,255):cls
function biasedRandom() as integer
dim as double i = rnd()
if i<= 0.4 then
return 1
elseif i <= 0.7 then
return 2
else
return 3
end if
end function
TYPE ANT
as integer x
as integer y
as integer d 'one of eight directions
END TYPE
const NUM_ANTS = 29
dim shared as ANT ants(0 to NUM_ANTS)
'initialize ants
for i as integer = 0 to NUM_ANTS
ants(i).x = 80
ants(i).y = 70
ants(i).d = int(rnd(1)*8)
next i
dim shared as integer food(160,120) 'location of food
dim shared as integer scent(160,120) 'scent trail
'fill world with random food
dim as integer x,y
for i as integer = 0 to 20
x = int(rnd(1)*160)
y = int(rnd(1)*120)
food(x,y)=1
next i
Randomize , 1
sub drawWorld()
screenlock
cls
for j as integer = 0 to 119
for i as integer = 0 to 159
line(i*4,j*4)-(i*4+4,j*4+4),rgb(255,255,255-scent(i,j)),bf
if food(i,j)=1 then
line(i*4,j*4)-(i*4+4,j*4+4),rgb(200,100,0),bf
end if
'line(i*4,j*4)-(i*4+4,j*4+4),rgb(0,0,0),b
'evaporate scent
if scent(i,j)<>0 then
scent(i,j)=scent(i,j)-1
end if
next i
next j
'draw ants
for i as integer = 0 to NUM_ANTS
line (ants(i).x*4,ants(i).y*4)-(ants(i).x*4+3,ants(i).y*4+3),rgb(255,0,0),bf
next i
screenunlock
end sub
dim as integer xd,yd,selection
do
drawWorld()
'move ants
for i as integer = 0 to NUM_ANTS
xd = int(rnd(1)*3)-1
yd = int(rnd(1)*3)-1
'select a random turn left or right or straight ahead
selection = biasedRandom()
if selection = 2 then
ants(i).d = ants(i).d - 1 'turn left
end if
if selection = 3 then
ants(i).d = ants(i).d + 1 'turn right
end if
'keep within boundary
if ants(i).x + xd <= 0 then ants(i).d = 2
if ants(i).x + xd >= 159 then ants(i).d = 6
if ants(i).y + yd <= 0 then ants(i).d = 4
if ants(i).y + yd >= 119 then ants(i).d = 0
if ants(i).d < 0 then ants(i).d = ants(i).d + 8
if ants(i).d > 7 then ants(i).d = ants(i).d - 8
if ants(i).d = 0 then xd = 0:yd =-1
if ants(i).d = 1 then xd = 1:yd =-1
if ants(i).d = 2 then xd = 1:yd = 0
if ants(i).d = 3 then xd = 1:yd = 1
if ants(i).d = 4 then xd = 0:yd = 1
if ants(i).d = 5 then xd =-1:yd = 1
if ants(i).d = 6 then xd =-1:yd = 0
if ants(i).d = 7 then xd =-1:yd =-1
'leave a scent
'scent(ants(i).x,ants(i).y)=scent(ants(i).x,ants(i).y)+4
'if scent(ants(i).x,ants(i).y)>255 then
scent(ants(i).x,ants(i).y)=255
'end if
ants(i).x = ants(i).x + xd
ants(i).y = ants(i).y + yd
draw string (ants(i).x*4,ants(i).y*4),str(i)
next i
sleep 20
loop until multikey(&H01)