the little Ants sim
Posted: Wed May 20, 2009 5:55 pm
just a small simulation of the behavior of ants 
ants trying to eat
if ants find food, it leaves a trail of pheromones, for others, and began to take food to the nest
if an ant finds the trail of pheromone, it gets down to work too!
in brown , the ants
in blue, the house of the ants
in yellow , the food

ants trying to eat
if ants find food, it leaves a trail of pheromones, for others, and began to take food to the nest
if an ant finds the trail of pheromone, it gets down to work too!
in brown , the ants
in blue, the house of the ants
in yellow , the food
Code: Select all
; Dobro Version 12
Declare.f RotationX(x.f, angle.f, dist.f)
Declare.f RotationY(y.f, angle.f, dist.f)
Declare.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) ; DEGREE
Structure fourmi
x.f
y.f
direction.b
memoire_nid_x.f
memoire_nid_y.f
memoire_bouffe_x.f
memoire_bouffe_y.f
mode.s ; determinera si la fourmi est en mode recherche,rapatriement de bouffe, ou pondeuse de pheromone
tictac.b ; ceci va dire a la fourmis dans quel sens elle doit aller
angle.f
memoire_coul.l
memoire_phero.l
quantite_bouffe.l ; retiens ce qu'il reste de quantité de bouffe (fourmi super inteligente LOL)
EndStructure
Structure pheromone
x.l
y.l
memoire_bouffe_x.f ; chaque pheromones contien la coordoné de la bouffe
memoire_bouffe_y.f; comme ça si une fourmis tombe dessus, elle saura ou ce trouve la bouffe
coul.l
id.l
EndStructure
Structure nid
x.f
y.f
EndStructure
Structure bouffe
x.f
y.f
quantite.l ; servira a diminuer la taille de la bouffe au fur et a mesure
id.l
EndStructure
Enumeration 1 Step 1000
#window
#sprite_fond
#fourmi ; image de la fourmi
#fourmi3D
#fourmi_bouffe ; petite boule de bouffe
#bouffe ; image de la bouffe
#nid ; image du nid
#pheromone ; image des phero
#retour
EndEnumeration
; Test
Global EcranX = 800
Global EcranY = 600
; ************* variables initialisations **************************
;- tableau de bord reglages
Global nbr_fourmi=20
Global nbr_bouffe = 5
Global nbr_pheromone=nbr_bouffe
Global nbr_nid=0
Global Dim bouffe.bouffe(nbr_bouffe)
Global Dim nId.nid(nbr_nid)
Global Dim pheromone.pheromone(nbr_bouffe) ; le nombre de piste de pheromone doit etre egale au nombre de bouffe
Global Dim fourmi.fourmi(nbr_fourmi)
Global aaa
; *********************************
; ***********************************************************
InitSprite(): InitKeyboard():InitSprite3D()
OpenWindow(#window,0,0,EcranX,EcranY,"les fourmis")
OpenWindowedScreen ( WindowID(#window),0,0, EcranX,EcranY,1,0,0)
; *********** ce sprite sert a effacer le fond ! ****************************
CreateSprite(#sprite_fond,EcranX,EcranY)
StartDrawing(SpriteOutput(#sprite_fond))
Box(0,0,EcranX,EcranY,RGB(0,0,0))
StopDrawing()
; ***************************************************************************
; *********** cree le sprite nid *****************
nid(0)\x=EcranX /2 ; coordoné du nid
nid(0)\y=EcranY/2
CreateSprite(#nid, 32, 32) ;
; dessine le sprite
StartDrawing(SpriteOutput(#nid))
Circle(16,16,16, RGB($0,$80,$FF))
StopDrawing()
; ***********************************************
; *********** cree le sprite fourmi*****************
; prepare les fourmis en leur chargeant en "rom" les coordonée de leur nid
; et en leur indiquant leur mode a la naissance !! "recherche"
For i=0 To nbr_fourmi
fourmi(i)\x=nid(0)\x : fourmi(i)\y=nid(0)\y
fourmi(i)\memoire_nid_x=nid(0)\x ; on donne a la fourmi la memoire de la coordonné de son nid
fourmi(i)\memoire_nid_y=nid(0)\y ; de cette façon elle saura ou se trouve celui-ci
fourmi(i)\mode="recherche"
fourmi(i)\angle = Random(360) ; ICI
Next i
CreateSprite(#fourmi, 8, 16,#PB_Sprite_Texture) ; c'est la meme image qui est employé
; dessine le sprite
StartDrawing(SpriteOutput(#fourmi))
Box(2,0,4,16, RGB($D6,$74,$3F))
StopDrawing()
CreateSprite3D(#fourmi3D, #fourmi)
; ******************* create sprite fourmis_bouffe *****************
CreateSprite(#fourmi_bouffe, 8, 8) ; c'est la meme image qui est employé
; dessine le sprite
StartDrawing(SpriteOutput(#fourmi_bouffe))
Circle(4,4,4, RGB($FF,$FF,$0))
StopDrawing()
; ***********************************************
; *********** cree le sprite pheromonone de retour *****************
CreateSprite(#retour, 4, 4) ; c'est la meme image qui est employé
; dessine le sprite
StartDrawing(SpriteOutput(#retour))
Circle(2,2,2, RGB($FF,0,0))
StopDrawing()
; ***********************************************
; *********** cree le sprite pheromone *****************
For i=0 To nbr_pheromone
CreateSprite(#pheromone+i, 4,4 ) ;
deb:
; dessine le sprite
coul=Random(55)+100
coul1=Random(255)
coul2=Random(255)
StartDrawing(SpriteOutput(#pheromone+i))
Circle(2,2,2,RGB(coul,coul1,coul2))
StopDrawing()
pheromone(i)\coul=RGB(coul,coul1,coul2)
pheromone(i)\id=#pheromone+i
Next i
; ***********************************************
; *********** cree le sprite bouffe *****************
For i=0 To nbr_bouffe
; ****** initialisation bouffe **********
bouffe(i)\x=Random(EcranX-50)+25
bouffe(i)\y=Random(EcranY-50)+25
bouffe(i)\quantite=32
bouffe(i)\id=i
; *****²²****************************
CreateSprite(#bouffe+i, bouffe(i)\quantite, bouffe(i)\quantite) ;
; dessine le sprite
StartDrawing(SpriteOutput(#bouffe+i))
Circle(bouffe(i)\quantite/2,bouffe(i)\quantite/2,bouffe(i)\quantite/2, RGB($FF,$FF,$0))
StopDrawing()
Next i
; ***********************************************
Repeat
WindowEvent()
Delay(2)
DisplaySprite(#sprite_fond,0,0) ; lui il passe son temps a effacer l'ecran , et a retenir les traces de pheromones
For i=0 To nbr_fourmi
For rr=0 To nbr_bouffe
; ; ************* collision fourmi =>bouffe et rapatriement ***************************************
;- rap et fourmi=> bouffe
If SpritePixelCollision(#fourmi,fourmi(i)\x, fourmi(i)\y, #bouffe+rr, bouffe(rr)\x, bouffe(rr)\y)
If fourmi(i)\mode="rap"
If bouffe(rr)>8
fourmi(i)\tictac=1 ; retourne vers le nid
bouffe(rr)\quantite= bouffe(rr)\quantite-1
fourmi(i)\quantite_bouffe=bouffe(rr)\quantite
; *************** reduit la bouffe ***************
StartDrawing(SpriteOutput(#bouffe+rr))
Box(0, 0,bouffe(rr)\quantite+1 , bouffe(rr)\quantite+1 ,RGB(0,0,0))
Circle(bouffe(rr)\quantite/2,bouffe(rr)\quantite/2,bouffe(rr)\quantite/2, RGB($FF,$FF,$0))
StopDrawing()
EndIf
EndIf
EndIf
; ***********************************************************************
; *************** collision fourmi => bouffe et mode recherche *********************************
If SpritePixelCollision(#fourmi,fourmi(i)\x, fourmi(i)\y, #bouffe+rr, bouffe(rr)\x, bouffe(rr)\y) And bouffe(rr)\quantite>8
If fourmi(i)\mode="recherche"
fourmi(i)\memoire_bouffe_x=bouffe(rr)\x ; la fourmis recupere les cordonné de la bouffe
fourmi(i)\memoire_bouffe_y=bouffe(rr)\y ; la fourmis recupere les cordonné de la bouffe
fourmi(i)\mode="pondre" ; et passe en mode pondre des pheromones
fourmi(i)\memoire_phero=pheromone(rr)\id; autant de phero que de bouffe
fourmi(i)\quantite_bouffe=bouffe(rr)\quantite
EndIf
EndIf
; ************************************************************************
; ************* collision fourmi => nid et mode pondre ***************************************
If SpritePixelCollision(#fourmi,fourmi(i)\x, fourmi(i)\y, #nid, nid(0)\x, nid(0)\y)
If fourmi(i)\mode="pondre"
fourmi(i)\mode="rap"
fourmi(i)\tictac=0
EndIf
EndIf
; ***********************************************************************
; ************* collision fourmi => nid et rapatriement***************************************
;-rap et fourmi=> nid
If SpritePixelCollision(#fourmi,fourmi(i)\x, fourmi(i)\y, #nid, nid(0)\x, nid(0)\y)
For bbb=0 To nbr_bouffe
If fourmi(i)\mode="rap"
fourmi(i)\tictac=0 ; retourne vers la bouffe
; ************************************************
; Debug "bouffe "+Str(bbb)+" "+Str(bouffe(bbb)\quantite)
If bouffe(bbb)\quantite<8
; passe en mode recherche si plus de bouffe
bouffe(bbb)\quantite=8 ;
;bouffe(bbb)\x=-1000
;bouffe(bbb)\y=-1000
uuu=i
; If fourmi(uuu)\mode="rap"
If fourmi(i)\quantite_bouffe<=8
fourmi(i)\quantite_bouffe=0
fourmi(i)\tictac=0
fourmi(i)\mode="recherche"
fourmi(i)\memoire_bouffe_x=0 ; efface la memoire de la fourmis
fourmi(i)\memoire_bouffe_y=0
EndIf
;EndIf
EndIf
EndIf
Next bbb
EndIf
; ************* collision fourmi => pheromone et que bouffe valable***************************************
;- fourmi =>phero
;
If fourmi(i)\mode="recherche"
StartDrawing(ScreenOutput())
For xxxx=0 To nbr_pheromone
; If SpritePixelCollision(#fourmi,fourmi(i)\x, fourmi(i)\y,pheromone(xxxx)\id, pheromone(xxxx)\x,pheromone(xxxx)\y)
;Debug "touche"
; on regarde si collision entre fourmis et couleur de phero existante
If Point(fourmi(i)\x+2,fourmi(i)\y+2)=pheromone(xxxx)\coul ; si oui
fourmi(i)\memoire_bouffe_x=pheromone(xxxx)\memoire_bouffe_x;
fourmi(i)\memoire_bouffe_y=pheromone(xxxx)\memoire_bouffe_y
fourmi(i)\memoire_coul=pheromone(xxxx)\coul ; met en memoire la couleur
fourmi(i)\memoire_phero=pheromone(xxxx)\id
fourmi(i)\mode="rap"
fourmi(i)\tictac=0 ; va ver la bouffe
EndIf
Next xxxx
StopDrawing()
EndIf
; ***********************************************************************
Select fourmi(i)\mode
;-mode recherche
;{ mode recherche
Case"recherche"
fourmi(i)\quantite_bouffe=0
StartDrawing(SpriteOutput(#fourmi))
Box(2,0,4,16, RGB($0,$FF,$0))
; Circle(8,8,8, RGB($0,$FF,$0))
StopDrawing()
temp=Random(50)
If temp=25
; fourmi(i)\direction=Random(7)+1; choix de la direction
fourmi(i)\angle + Random(91) - 45 ; choix de la direction ; Encore ICI
EndIf
Select fourmi(i)\direction
Case 1 ; nord:
fourmi(i)\angle.f=0
Case 2 ; nord/est:
fourmi(i)\angle.f=45
Case 3 ; est:
fourmi(i)\angle.f=90
Case 4 ; sud/est:
fourmi(i)\angle.f=135
Case 5 ; sud:
fourmi(i)\angle.f=180
Case 6 ; sud/ouest:
fourmi(i)\angle.f=-135
Case 7 ; ouest
fourmi(i)\angle.f=-90
Case 8 ; nord/ouest:
fourmi(i)\angle.f=-45
EndSelect
;- mode rapatriement
Case "rap"
If fourmi(i)\tictac=0 ; va ver la bouffe
boubouffe=0
StartDrawing(SpriteOutput(#fourmi))
Box(2,0,4,16, RGB($0,$0,$FF))
StopDrawing()
fourmi(i)\angle.f=ReturnDegAngle(fourmi(i)\x,fourmi(i)\y,fourmi(i)\memoire_bouffe_x,fourmi(i)\memoire_bouffe_y) ; DEGREE
; va vers la bouffe (trace du retour )x,y
;- trace retour
; StartDrawing(SpriteOutput(fourmi(i)\memoire_phero))
; Circle(2,2,2, fourmi(i)\memoire_coul )
; StopDrawing()
UseBuffer(#sprite_fond)
DisplayTransparentSprite(fourmi(i)\memoire_phero,fourmi(i)\x+2,fourmi(i)\y+2)
UseBuffer(#PB_Default)
EndIf
If fourmi(i)\tictac=1 ; va ver le nid
fourmi(i)\angle.f=ReturnDegAngle(fourmi(i)\x,fourmi(i)\y,fourmi(i)\memoire_nid_x,fourmi(i)\memoire_nid_y) ; DEGREE
StartDrawing(SpriteOutput(#fourmi))
Box(2,0,4,16, RGB($0,$0,$FF))
StopDrawing()
boubouffe=1
EndIf
;- mode pondre
Case "pondre"
; va vers le nid x,y
fourmi(i)\angle.f=ReturnDegAngle(fourmi(i)\x,fourmi(i)\y,fourmi(i)\memoire_nid_x,fourmi(i)\memoire_nid_y) ; DEGREE
pheromone(rr)\x=fourmi(i)\x+2 ; la pheromone recupere la coordoné de la fourmis
pheromone(rr)\y=fourmi(i)\y+2
pheromone(rr)\memoire_bouffe_x =fourmi(i)\memoire_bouffe_x ; et recupere la coordoné de la bouffe
pheromone(rr)\memoire_bouffe_y =fourmi(i)\memoire_bouffe_y ; et recupere la coordoné de la bouffe
UseBuffer(#sprite_fond)
DisplayTransparentSprite( fourmi(i)\memoire_phero,pheromone(rr)\x,pheromone(rr)\y)
UseBuffer(#PB_Default)
EndSelect
; *************************************************************************************
;}
; une fois que le sens est aquis: déplacement
fourmi(i)\x=RotationX( fourmi(i)\x, fourmi(i)\angle.f, 1)
fourmi(i)\y= RotationY( fourmi(i)\y, fourmi(i)\angle.f, 1)
If fourmi(i)\x < 10
fourmi(i)\x = 10
If fourmi(i)\angle > 180
fourmi(i)\angle = 270
Else
fourmi(i)\angle = 90
EndIf
EndIf
If fourmi(i)\x > EcranX - 20
fourmi(i)\x = EcranX - 20
If fourmi(i)\angle > 0
fourmi(i)\angle = 90
Else
fourmi(i)\angle = 270
EndIf
EndIf
If fourmi(i)\y < 10
fourmi(i)\y = 10
If fourmi(i)\angle > 90
fourmi(i)\angle = 180
Else
fourmi(i)\angle = 0
EndIf
EndIf
If fourmi(i)\y > EcranY - 20 ; 768
fourmi(i)\y = EcranY - 20
If fourmi(i)\angle > 270
fourmi(i)\angle = 0
Else
fourmi(i)\angle = 180
EndIf
EndIf
For iii=0 To nbr_fourmi
If fourmi(iii)\mode="rap"
If fourmi(iii)\quantite_bouffe<8
fourmi(iii)\quantite_bouffe=0 ;
fourmi(iii)\tictac=1
fourmi(iii)\mode="recherche"
fourmi(iii)\memoire_bouffe_x=0 ; efface la memoire de la fourmis
fourmi(iii)\memoire_bouffe_y=0
EndIf
EndIf
Next iii
;- affichage
Start3D()
; DisplayTransparentSprite(#fourmi,fourmi(i)\x,fourmi(i)\y) ; toujour la meme image qui est affiché
RotateSprite3D(#fourmi3D, fourmi(i)\angle.f+110,0)
DisplaySprite3D(#fourmi3D,fourmi(i)\x,fourmi(i)\y)
Stop3D()
If boubouffe=1 And fourmi(i)\mode="rap" And fourmi(i)\tictac=1
DisplayTransparentSprite(#fourmi_bouffe,fourmi(i)\x+2,fourmi(i)\y)
EndIf
DisplayTransparentSprite(#nid,nid(0)\x,nid(0)\y ); affiche le nid (1 pour commencer)
DisplayTransparentSprite(#bouffe+rr,bouffe(rr)\x,bouffe(rr)\y) ; affiche la bouffe (1 pour commencer)
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
End
EndIf
Next rr
dede=Random(2)
If dede=1
; ************ les pheromones qui s'efface progressivement sur tout le terrain
UseBuffer(#sprite_fond)
xplo=Random(EcranX-2)+1
yplo=Random(EcranY-2)+1
xplo2=Random(EcranX-2)+1
yplo2=Random(EcranY-2)+1
StartDrawing(SpriteOutput(#sprite_fond))
LineXY(xplot,yplo, xplo2, yplo2,RGB(0,0,0))
StopDrawing()
UseBuffer(#PB_Default)
; ************************************************************
EndIf
Next i
FlipBuffers()
ForEver
;²
Procedure.f RotationX(x.f, angle.f, dist.f)
ProcedureReturn x + Cos(angle*#PI/180)*dist
EndProcedure
Procedure.f RotationY(y.f, angle.f, dist.f)
ProcedureReturn y + Sin(angle*#PI/180)*dist
EndProcedure
Procedure.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) ; DEGREE
; cpl-Bator
A.f = x1-x2
b.f = y1-y2
c.f = -Sqr(A*A+b*b)
angle.f = ACos(A/c)*180/#PI
If y1 < y2 : angle=360-angle : EndIf
ProcedureReturn Abs(angle - 360)
EndProcedure