ANT SIMULATIONS

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
BasicCoder2
Posts: 3908
Joined: Jan 01, 2009 7:03
Location: Australia

ANT SIMULATIONS

Post by BasicCoder2 »

Simulating an ant colony first requires learning about how real ants behave. Ants have different behaviors but here I have started with a simple version of a foraging behavior.

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)

badidea
Posts: 2592
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: ANT SIMULATIONS

Post by badidea »

Your random ant movement seems better (less nervous) than mine. I will try it as well, without the diagonal movement.
BasicCoder2
Posts: 3908
Joined: Jan 01, 2009 7:03
Location: Australia

Re: ANT SIMULATIONS

Post by BasicCoder2 »

@badidea

When I watched real ants in the foraging mode (going around and around an area) I marked their paths and saw squiggles. it seems a probability thing where the most probable is forward and varying degrees of veering left or right but the sharper the turn the less likely it happens. When my sim ant hits a border it does a 180 turn. In the code below there is a veer to the right or left or a sharp turn. I was just interested in producing the same squiggle paths I saw real foraging ants make. In this example the fading pheromones are blue.

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.6 then
        return 2
    elseif i <= 0.8 then
        return 3
    elseif i <= 0.9 then
        return 4
    else
        return 5
    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(0,0,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 = int(rnd(1)*5)
        selection = biasedRandom()
        
        if selection = 2 then
            ants(i).d = ants(i).d - 1  'veer left
        end if
        if selection = 3 then
            ants(i).d = ants(i).d + 1  'veer right
        end if
        if selection = 4 then
            ants(i).d = ants(i).d - 2  'hard left
        end if
        if selection = 5 then
            ants(i).d = ants(i).d + 2  'hard 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)

neil
Posts: 594
Joined: Mar 17, 2022 23:26

Re: ANT SIMULATIONS

Post by neil »

It looks great. Well done.
Post Reply