Ants At War

No preview image

1 collaborator

Default-person John Thomas (Author)

Tags

Visible to everyone | Changeable by the author
Model was written in NetLogo 5.2.0 • Viewed 739 times • Downloaded 42 times • Run 0 times
Download the 'Ants At War' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Info tab cannot be displayed because of an encoding error

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

globals
[
  tick-delta          ;; how much we advance the tick counter this time through
  max-tick-delta      ;; the largest tick-delta is allowed to be
  box-edge            ;; distance of box edge from axes
  divider             ;; how wide is the divider/hole
  
  channel-size        ;;size of the channel that lets the combatants engage--set by user
  channel-interval    ;;Interval between two channels--set by program/uniform..can be random
  
  
  
  lpar-kills       ;; total count of lpar kills
  lneg-kills       ;; total count of lneg kills
  lneg-to-lpar-kill-ratio ;; ration of lneg/lpar kills (0 floor)
  
  war-status?     ;;tracks status of war (war: T; no war: F)

]

breed [ lpars lpar ]
breed [ lnegs lneg ] 

lpars-own
[
  step-size
  speed
  tick-count ;; helps switch between strategies in case of war
]

lnegs-own
[
  step-size
  speed
  tick-count ;; helps switch between strategies in case of war
]

patches-own
[
  lpar_phero
  lneg_phero
]
;;===============================================
;; SETUP
;;===============================================

to setup
  clear-all
  set war-status? FALSE
  ask patches 
   [
     set pcolor white
     set lpar_phero 0 ; initialize pheromone levels at the patch to 0
     set lneg_phero 0 ; initialize pheromone levels at the patch to 0
     ]
  set-default-shape lpars "bug" 
  set-default-shape lnegs "bug" 
  
  set max-tick-delta 0.1073 ; the max tick-delta we can simulate
  
  ;--Create a square box that contains two chambers that refelects
  set box-edge (round (max-pxcor * box-size / 100) - 1) 
  set divider (round (max-pxcor * divider-width / 100))
   
  make-box
  
  ;--Create the warring swarms, each behind its dividing line
  make-ants
  
  set lpar-kills 0
  set lneg-kills 0
  set lneg-to-lpar-kill-ratio 0
  reset-ticks
end 


;;===============================================
;; GO
;;===============================================

to go
  
  ask lpars [
    set step-size speed * tick-delta ;distance traveled at each tick
    bounce
    wiggle
    set tick-count tick-count + 1
    chase-ln
    
    jump (speed * tick-delta)
    set lpar_phero lpar_phero + 1
  ] 
  
  ask lnegs [
    set step-size speed * tick-delta ;distance traveled at each tick
    bounce
    wiggle
    set tick-count tick-count + 1
    chase-lp 
    
    
    jump (speed * tick-delta)
    set lneg_phero lneg_phero + 1
  ] 
  

  tick-advance tick-delta ;update tick counter by custom amount

  
  calculate-tick-delta lnegs lpars

  diffuse lpar_phero (lp-diffusion-rate / 100) ;observer command
  diffuse lneg_phero (ln-diffusion-rate / 100) ;observer command
  
  ask patches
  [ 
    if (pcolor = black) 
    [
      set lpar_phero 0
      set lneg_phero 0  
    ] 
    set lpar_phero lpar_phero * (100 - lp-evaporation-rate) / 100  ;; slowly evaporate chemical
    set lneg_phero lneg_phero * (100 - ln-evaporation-rate) / 100  ;; slowly evaporate chemical
    recolor-patch ;; let the patch color help visualize the pheromone dominance
                  ;; ultimately, the war is really a chemical-war 
    
    killing-zone
  ]
  
  if lpar-kills != 0
  [
    set lneg-to-lpar-kill-ratio lneg-kills / lpar-kills
  ]
  
  update-plots
  display ;update the view immediately
  
  ;;no point simulating beyond this...
  if (lpar-kills = num-lps) or (lneg-kills = num-lns) [ stop ] 
end 


;;===============================================
;; DRAW THE BOUNDING BOX
;;===============================================

to make-box
  ask patches with ;set the partionined black-box
  [ 
    ((abs pxcor = box-edge) and (abs pycor <= box-edge)) or ;left & right edges
    ((abs pycor = box-edge) and (abs pxcor <= box-edge)) or ;top & bottom edges
    ((abs pycor <= box-edge) and (abs pxcor <= divider )) ;= 0)) ; the central vertical demarcator
  ]
  [ set pcolor black ]
  ask patches with ; set universe outside the black-box as grey
  [ 
    (abs pxcor > box-edge) or ;left & right edges
    (abs pycor > box-edge) ; top & bottom
  ]
  [ set pcolor grey ]
end 

;;===============================================
;; MAKE-ANTS: CREATE THE ARMY OF ANTS ON BOTH SIDES
;;===============================================

to make-ants
  create-lnegs num-lns [
    set speed ln-speed
    random-position-left ;this needs to be network based
    set color red + 1.3
    set size 2
    set lneg_phero lneg_phero + 1
  ]
  create-lpars num-lps [
    set speed lp-speed
    random-position-right ;this needs to be erdos based
    set color black ;brown - 0.3
    set size 4
    set lpar_phero lpar_phero + 1
  ]
  
  calculate-tick-delta lnegs lpars
end 


;;===============================================
;; HELPER FUNCTION TO RANDOMLY SET AGENTS AT RIGHT
;;===============================================

to random-position-right
  setxy ( 1 + divider + random-float (box-edge - 2 - divider)) ;2))
        ((1 - box-edge) + random-float (2 * box-edge - 2))
end 

;;===============================================
;; HELPER FUNCTION TO RANDOMLY SET AGENTS AT LEFT
;;===============================================

to random-position-left
  setxy (-1 - divider - random-float (box-edge - 2 - divider)) ;2))
        ((1 - box-edge) + random-float (2 * box-edge -  2))
end 


;;===============================================
;; BOUNCE OFF THE WALL'S BY SETTING heading
;;===============================================

to bounce  ;; turtle procedure
  ;; if we are already on a wall, no need for further checks
  if pcolor = black [stop]
    
  ;; get the coordinates of the patch we'll be on if we go forward 1
  let new-patch patch-ahead step-size
  let new-px [pxcor] of new-patch
  let new-py [pycor] of new-patch
  
  if [pcolor] of new-patch != black ; no need to bounce 
    [       
      stop 
    ]
    
  ;; if hitting left or right extreme wall, reflect heading around x axis
  if abs new-px = box-edge [ set heading (- heading)]
  
  ;; if hitting top or bottom wall, reflect heading around y axis
  if abs new-py = box-edge  [ set heading (180 - heading) ]
  
  ;; if hitting partition, reflect heading around x axis unless near an opening
  if abs new-px <= divider + 1 
  [
    set heading ( - heading)
    if [pcolor] of patch-ahead step-size = black 
      [set heading  (180 - heading)]
  ]
end 

;;===============================================
;; CALCULATE-TICK-DELTA
;;===============================================

to calculate-tick-delta [ agentset1 agentset2 ]
  ;; tick-delta is calculated in such a way that even the fastest
  ;; agent will jump at most 1 patch length in a tick. As
  ;; agents jump (speed * tick-delta) at every tick, making
  ;; tick length the inverse of the speed of the fastest agent
  ;; (1/max speed) assures that. Having each agent advance at most
  ;; one patch-length is necessary for it not to "jump over" a wall.
  ifelse ((any? agentset1 with [speed > 0]) or (any? agentset2 with [speed > 0]))
    [ set tick-delta min (list (1 / (ceiling max [speed] of agentset1)) 
                               (1 / (ceiling max [speed] of agentset1)) 
                               max-tick-delta) ]
    [ set tick-delta max-tick-delta ]
end 

;;===============================================
;; START-WAR/open partition for the attack begin
;;===============================================

to start-war
  set war-status? TRUE
  set channel-size floor (box-edge * (hole-size / 100))
  set channel-interval 3 * channel-size
  let ydelta channel-size + channel-interval ; this is the begin of each hole
  let patchlist []  ;; patch list to help open the divider and start the war     
  ifelse (many-holes?)
  [
    let y 0 - box-edge + 1

    while [y < box-edge - 1 ] 
    [
      let k 0
      let y1 y
      while [ k < channel-size]
      [
        let l 0 - (divider) ; to find all patches along x-axis to open-up
        while [ l < divider + 1]
        [
          set patchlist lput patch  l  y1  patchlist
          set l  l + 1
        ]
        ;set ylist lput patch  0  y1  ylist
        set y1 y1 + 1
        set k k + 1
      ]
      set y y + ydelta
    ]
    
    foreach patchlist
    [
      ask ?1 
      [
        set pcolor white ;ask flashes-here [die]
      ]
    ]
  ]
  [
    let y  ( 0 - channel-size / 2.0)
    set patchlist []
    while [(y < box-edge - 1) and (y <= channel-size)] 
    [
      let k 0
      let y1 y
      while [ k < channel-size]
      [
        let l 0 - (divider) ; to find all patches along x-axis to open-up
        while [ l < divider + 1]
        [
          set patchlist lput patch  l  y1  patchlist
          set l  l + 1
        ]
        ;set ylist lput patch  0  y1  ylist
        set y1 y1 + 1
        set k k + 1
      ]
      set y y + ydelta
    ]
    
    foreach patchlist
    [
      ask ?1 
      [
        set pcolor white ;ask flashes-here [die]
      ]
    ]
  ]
end 

;;===============================================
;; TRUCE/close partition
;;===============================================

to truce
  set war-status? FALSE
  ask patches with [
    ((abs pycor <= box-edge) and (abs pxcor <= divider ))
  ]
  [ set pcolor black ]
end 

;;===============================================
;; RECOLOR-PATCH to help visualize pheromone trace
;;===============================================

to recolor-patch  ;; patch procedure
    ;; scale color to show chemical concentration
  if ((pcolor != black) and (pcolor != grey) )
    [
      ifelse (abs (lpar_phero - lneg_phero) > 0)
      [
        ifelse (lpar_phero >= lneg_phero)
        [ set pcolor cyan + 3] 
        [ set pcolor yellow + 3] 
      ]
      [
        set pcolor white
      ]
    ]
end 
;;===============================================
;; LP-SCENT-AT-ANGLE to help find lp
;;===============================================

to-report lp-scent-at-angle [angle]
  let p patch-right-and-ahead angle 1
  if p = nobody [ report 0 ]
  report [lpar_phero] of p
end 

;;===============================================
;; LN-SCENT-AT-ANGLE to help find ln
;;===============================================

to-report ln-scent-at-angle [angle]
  let p patch-right-and-ahead angle 1
  if p = nobody [ report 0 ]
  report [lneg_phero] of p
end 



;;===============================================
;; CHASE-LP to find  lp
;;===============================================
;; sniff left and right, and go where the strongest lp smell is

to chase-lp  ;; turtle procedure
  let scent-ahead lp-scent-at-angle   0
  let scent-right lp-scent-at-angle  45
  let scent-left  lp-scent-at-angle -45
  if (scent-right > scent-ahead) or (scent-left > scent-ahead)
  [ ifelse scent-right > scent-left
    [ rt  45 ]
    [ lt  45 ] 
  ]
end 

;;===============================================
;; FLEE-LP to flee lp
;;===============================================
;; sniff left and right, and go away from where the strongest lp smell is

to flee-lp  ;; turtle procedure
  let scent-ahead lp-scent-at-angle   0
  let scent-right lp-scent-at-angle  8
  let scent-left  lp-scent-at-angle -8
  if (scent-right > scent-ahead) or (scent-left > scent-ahead)
  [ ifelse scent-right > scent-left
    [ lt  8 ]
    [ rt  8 ] 
  ]
end 

;;===============================================
;; CHASE-LN to find ln
;;===============================================
;; sniff left and right, and go where the strongest ln smell is

to chase-ln  ;; turtle procedure
  let scent-ahead ln-scent-at-angle   0
  let scent-right ln-scent-at-angle  45
  let scent-left  ln-scent-at-angle -45
  if (scent-right > scent-ahead) or (scent-left > scent-ahead)
  [ ifelse scent-right > scent-left
    [ rt  45 ]
    [ lt  45 ] 
  ]
end 



;;===============================================
;; FLEE-LN to find ln
;;===============================================
;; sniff left and right, and go away from where the strongest ln smell is

to flee-ln  ;; turtle procedure
  let scent-ahead ln-scent-at-angle   0
  let scent-right ln-scent-at-angle  45
  let scent-left  ln-scent-at-angle -45
  if (scent-right > scent-ahead) or (scent-left > scent-ahead)
  [ ifelse scent-right > scent-left
    [ rt  45 ]
    [ lt  45 ] 
  ]
end 
;;===============================================
;; KILLING-ZONE; patches execute the cut
;;===============================================

to killing-zone  ;; terminator patches
  let lncount (count lnegs-here)
  let lpcount (count lpars-here)
  
  if (lpcount >= 1 and lncount >= 1) 
  [
    ifelse ((lncount - lpcount) >= 2) ; RULE 3: advantage ln
    [
      let prey one-of lpars-here
      if prey != nobody
      [ 
        ask prey [ die ]
        set lpar-kills lpar-kills + 1
      ]
    ]
    [
      ifelse ((lncount - lpcount) = 1) ; RULE 2: toss-up
      [
        let i random 1
        ifelse (i = 0) ; advantage lp
        [
          let prey one-of lnegs-here
          if prey != nobody
          [ 
            ask prey [ die ]
            set lneg-kills lneg-kills + 1
          ]
        ]
        [            ; advantage ln   
          let prey one-of lpars-here
          if prey != nobody
          [ 
            ask prey [ die ]
            set lpar-kills lpar-kills + 1
          ]
        ]
      ]
      [                                ;RULE 1: advantage lp
        let prey one-of lnegs-here
        if prey != nobody
        [ 
          ask prey [ die ]
          set lneg-kills lneg-kills + 1
        ]
      ]
    ]
  ]  
  
;  
;  
;  if (lncount >= 3) and (lpcount >= 1) and (lpcount <= 2 ) ; Rule 3: dominance ln
;  [
;    let prey one-of lpars-here
;    if prey != nobody
;    [ 
;      ask prey [ die ]
;      set lpar-kills lpar-kills + 1
;    ]
;  ]  
;  
;  if (lncount = 2) and (lpcount >= 1) and (lpcount <= 2 ) ;equal dominance
;  [
;    let i random 1
;    ifelse (i = 0) ; advantage lp
;    [
;      let prey one-of lnegs-here
;      if prey != nobody
;      [ 
;        ask prey [ die ]
;        set lneg-kills lneg-kills + 1
;      ]
;    ]
;    [            ; advantage ln   
;      let prey one-of lpars-here
;      if prey != nobody
;      [ 
;        ask prey [ die ]
;        set lpar-kills lpar-kills + 1
;      ]
;    ]
;  ]
;  
;  if (lncount <= 1) and (lpcount >= 1) ; dominance lp
;  [
;    let prey one-of lnegs-here
;    if prey != nobody
;    [ 
;      ask prey [ die ]
;      set lneg-kills lneg-kills + 1
;    ]
;  ]  
end 

;;===============================================
;; WIGGLE; let the ants do their natural wiggle
;;===============================================

to wiggle
    if pcolor = black [stop]
    let r random 5
    let l random 5
    let p patch-right-and-ahead r 1
    let q patch-left-and-ahead l 1    
    ifelse ([pcolor] of p = black ) or
       ([pcolor] of q = black ) 
    [stop]
    [
;      print r
;      print l
      rt r
      lt l
    ]
end 

There is only one version of this model, created over 7 years ago by John Thomas.

Attached files

File Type Description Last updated
AntsAtWar.jpg jpeg PreviewImage over 7 years ago, by John Thomas Download

This model does not have any ancestors.

This model does not have any descendants.