INTA6742 Modeling v1.1

INTA6742 Modeling v1.1 preview image

1 collaborator

Default-person Ji Young Seo (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 7.0.3 • Viewed 34 times • Downloaded 2 times • Run 0 times
Download the 'INTA6742 Modeling v1.1' modelDownload this modelEmbed this model

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


WHAT IS IT?

(a general understanding of what the model is trying to show or explain)

HOW IT WORKS

(what rules the agents use to create the overall behavior of the model)

HOW TO USE IT

(how to use the model, including a description of each of the items in the Interface tab)

THINGS TO NOTICE

(suggested things for the user to notice while running the model)

THINGS TO TRY

(suggested things for the user to try to do (move sliders, switches, etc.) with the model)

EXTENDING THE MODEL

(suggested things to add or change in the Code tab to make the model more complicated, detailed, accurate, etc.)

NETLOGO FEATURES

(interesting or unusual features of NetLogo that the model uses, particularly in the Code tab; or where workarounds were needed for missing features)

RELATED MODELS

(models in the NetLogo Models Library and elsewhere which are of related interest)

CREDITS AND REFERENCES

(a reference to the model's URL on the web if it has one, as well as any other necessary credits, citations, and links)

Comments and Questions

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

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SNODGRASS HILL MODEL - 5 MINUTE TICK VERSION (FINAL CALIBRATION)
;;
;; Time scale:
;; 1 tick = 5 minutes
;;
;; Historical mapping:
;; 11:00 AM = tick 0
;; 1:00 PM  = tick 24
;; 1:30 PM  = tick 30
;; 2:00 PM  = tick 36
;; 5:30 PM  = tick 78
;; 6:00 PM  = tick 84
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

breed [union-defenders union-defender]
breed [confederate-attackers confederate-attacker]
breed [union-reinforcements union-reinforcement]

globals [
  breakthrough?
  breakthrough-tick
  breakthrough-reason
  retreat-outcome
  current-phase

  granger-arrival-tick
  reinforcement-arrived?

  ridge-occupancy-threshold
  ridge-occupancy-duration-threshold
  frontline-ammo-threshold
  assault-distance-threshold
  engagement-range

  consecutive-crest-occupancy-ticks

  union-frontline-ammo-avg
  union-total-ammo-avg
  union-frontline-count
  union-density-current
  confederates-on-crest
  active-union-count
  active-confederate-count

  total-union-removed
  total-confederate-removed
]

patches-own [
  terrain-type
  elevation
  movement-cost
  cover-value
  visibility-modifier
  ridge-bonus
  uphill-fire-penalty
  is-ridge-crest?
  is-union-line?
  is-confederate-entry?
  is-reinforcement-entry?
  weak-sector-score
]

turtles-own [
  health
  ammo
  morale-state
  fatigue
  combat-status
  base-hit-prob
  removal-prob-if-hit
  fire-rate
  effective-range
  cohesion
  is-frontline?
  shots-fired-this-tick
  assault-wave
  active-wave?
  rallied-this-tick?
]

to setup
  clear-all
  setup-globals
  setup-patches
  setup-union-defenders
  setup-confederate-attackers
  setup-reinforcements
  update-frontline-status
  update-derived-metrics
  reset-ticks
end 

to setup-globals
  set breakthrough? false
  set breakthrough-tick -1
  set breakthrough-reason "none"
  set retreat-outcome "none"
  set current-phase "pre-major-assault"

  set granger-arrival-tick 33
  set reinforcement-arrived? false

  set ridge-occupancy-threshold 18
  set ridge-occupancy-duration-threshold 4
  set frontline-ammo-threshold 3
  set assault-distance-threshold 3
  set engagement-range 6

  set consecutive-crest-occupancy-ticks 0

  set union-frontline-ammo-avg 0
  set union-total-ammo-avg 0
  set union-frontline-count 0
  set union-density-current 0
  set confederates-on-crest 0
  set active-union-count 0
  set active-confederate-count 0

  set total-union-removed 0
  set total-confederate-removed 0
end 

to setup-patches
  ask patches [
    set terrain-type "open"
    set elevation 0
    set movement-cost 1.0
    set cover-value 1.0
    set visibility-modifier 1.0
    set ridge-bonus 1.0
    set uphill-fire-penalty 1.0
    set is-ridge-crest? false
    set is-union-line? false
    set is-confederate-entry? false
    set is-reinforcement-entry? false
    set weak-sector-score 0
    set pcolor 37
  ]

  ask patches with [pycor <= -13] [
    set terrain-type "open"
    set is-confederate-entry? true
    set pcolor 33
  ]

  ask patches with [pycor > -13 and pycor <= -4] [
    set terrain-type "open"
    set elevation 1
    set movement-cost 1.0
    set cover-value 1.0
    set visibility-modifier 1.0
    set pcolor 35
  ]

  ask patches with [
    pycor > -10 and pycor <= 4 and
    (pxcor mod 6 = 0 or pxcor mod 7 = 0)
  ] [
    set terrain-type "woods"
    set movement-cost 1.18
    set cover-value 1.15
    set visibility-modifier 0.94
    set pcolor 53
  ]

  ask patches with [pycor > -4 and pycor <= 5] [
    set terrain-type "ridge-slope"
    set elevation 2
    set movement-cost 1.25
    set cover-value 1.03
    set visibility-modifier 0.97
    set uphill-fire-penalty 0.90
    set pcolor 57
  ]

  ask patches with [
    pycor >= 6 and pycor <= 9 and
    abs (pycor - (7 + 0.08 * pxcor - 0.004 * pxcor * pxcor)) <= 1.5
  ] [
    set terrain-type "ridge-crest"
    set elevation 3
    set movement-cost 1.08
    set cover-value 1.20
    set visibility-modifier 1.02
    set ridge-bonus 1.12
    set is-ridge-crest? true
    set is-union-line? true
    set pcolor green
  ]

  ask patches with [is-ridge-crest? and pxcor < -6] [
    set cover-value 1.28
    set pcolor 58
  ]

  ask patches with [pycor >= 10] [
    set terrain-type "rear"
    set elevation 2
    set movement-cost 1.0
    set cover-value 1.0
    set visibility-modifier 1.0
    set is-reinforcement-entry? true
    set pcolor 105
  ]
end 

to setup-union-defenders
  create-union-defenders initial-union-defenders [
    move-to one-of patches with [is-union-line?]
    set shape "person"
    set color blue
    set size 0.8

    set health 1
    set ammo union-initial-ammo
    set morale-state "steady"
    set fatigue 0
    set combat-status "holding"
    set base-hit-prob 0.24
    set removal-prob-if-hit 0.20
    set fire-rate 1.0
    set effective-range engagement-range
    set cohesion 1.0
    set is-frontline? true
    set shots-fired-this-tick 0
    set assault-wave 0
    set active-wave? true
    set rallied-this-tick? false

    if random-float 1.0 < 0.10 [
      set fire-rate 1.6
    ]
  ]
end 

to setup-confederate-attackers
  create-confederate-attackers initial-confederates [
    move-to one-of patches with [is-confederate-entry?]
    set shape "person"
    set color red
    set size 0.8

    set health 1
    set ammo confederate-initial-ammo
    set morale-state "steady"
    set fatigue 0
    set combat-status "holding"
    set base-hit-prob 0.21
    set removal-prob-if-hit 0.20
    set fire-rate 0.95
    set effective-range engagement-range
    set cohesion 1.0
    set is-frontline? false
    set shots-fired-this-tick 0
    set rallied-this-tick? false

    let r random 4
    if r = 0 [ set assault-wave 1 ]
    if r = 1 [ set assault-wave 2 ]
    if r = 2 [ set assault-wave 3 ]
    if r = 3 [ set assault-wave 4 ]

    set active-wave? false
    hide-turtle
  ]
end 

to setup-reinforcements
  create-union-reinforcements reinforcement-size [
    move-to one-of patches with [is-reinforcement-entry?]
    hide-turtle
    set shape "person"
    set color cyan
    set size 0.8

    set health 1
    set ammo reinforcement-initial-ammo
    set morale-state "steady"
    set fatigue 0
    set combat-status "holding"
    set base-hit-prob 0.24
    set removal-prob-if-hit 0.20
    set fire-rate 1.0
    set effective-range engagement-range
    set cohesion 1.0
    set is-frontline? false
    set shots-fired-this-tick 0
    set assault-wave 0
    set active-wave? false
    set rallied-this-tick? false
  ]
end 

to go
  if breakthrough? = true [ stop ]
  if not any? turtles with [breed != confederate-attackers and health = 1] [ stop ]

  update-battle-phase
  activate-assault-waves
  activate-reinforcements
  reset-tick-state

  update-frontline-status
  move-confederates
  reposition-union
  reposition-reinforcements
  resolve-combat
  update-ammo
  update-morale
  rally-broken-units
  handle-retreat-logic
  process-removals

  update-frontline-status
  update-derived-metrics
  check-breakthrough

  tick
end 

to update-battle-phase
  if ticks < 24 [ set current-phase "pre-major-assault" ]
  if ticks >= 24 and ticks < 36 [ set current-phase "initial-major-assaults" ]
  if ticks >= 36 and ticks < 78 [ set current-phase "sustained-pressure" ]
  if ticks >= 78 [ set current-phase "withdrawal-phase" ]
end 

to activate-assault-waves
  if ticks = 24 [
    ask confederate-attackers with [assault-wave = 1 and active-wave? = false] [
      set active-wave? true
      show-turtle
      set combat-status "advancing"
    ]
  ]

  if ticks = 30 [
    ask confederate-attackers with [assault-wave = 2 and active-wave? = false] [
      set active-wave? true
      show-turtle
      set combat-status "advancing"
    ]
  ]

  if ticks = 42 [
    ask confederate-attackers with [assault-wave = 3 and active-wave? = false] [
      set active-wave? true
      show-turtle
      set combat-status "advancing"
    ]
  ]

  if ticks = 54 [
    ask confederate-attackers with [assault-wave = 4 and active-wave? = false] [
      set active-wave? true
      show-turtle
      set combat-status "advancing"
    ]
  ]
end 

to activate-reinforcements
  if ticks >= granger-arrival-tick and reinforcement-arrived? = false [
    ask union-reinforcements [
      set active-wave? true
      show-turtle
      set combat-status "advancing"
      move-to one-of patches with [is-reinforcement-entry?]
    ]
    set reinforcement-arrived? true
  ]
end 

to reset-tick-state
  ask turtles with [health = 1] [
    set shots-fired-this-tick 0
    set rallied-this-tick? false
  ]
end 

to update-frontline-status
  ask turtles with [health = 1] [
    if breed = confederate-attackers [
      set is-frontline? false
    ]
    if breed != confederate-attackers [
      set is-frontline? false
      if [is-ridge-crest?] of patch-here = true [
        set is-frontline? true
      ]
      if any? confederate-attackers with [health = 1 and active-wave? = true and distance myself <= 3] [
        set is-frontline? true
      ]
    ]
  ]
end 

to move-confederates
  ask confederate-attackers with [health = 1 and active-wave? = true] [
    if morale-state = "broken" [
      set combat-status "routing"
      set heading 180
      fd 0.20
    ]

    if morale-state != "broken" [
      let enemy-nearby? any? (turtle-set union-defenders union-reinforcements) with
        [health = 1 and distance myself <= [effective-range] of myself]

      if enemy-nearby? [
        set combat-status "firing"
      ]

      if not enemy-nearby? [
        let target-patch min-one-of patches with [is-ridge-crest? = true] [distance myself]
        if target-patch != nobody [
          face target-patch
          let step-size 1 / ([movement-cost] of patch-ahead 1)

          if [terrain-type] of patch-ahead 1 = "woods" [
            set step-size step-size * 0.95
          ]
          if [terrain-type] of patch-ahead 1 = "ridge-slope" [
            set step-size step-size * 0.92
          ]
          if fatigue > 12 [
            set step-size step-size * 0.90
          ]

          fd step-size
          set combat-status "advancing"
          set fatigue fatigue + 0.18
        ]
      ]
    ]
  ]
end 

to reposition-union
  calculate-weak-sectors

  ask union-defenders with [health = 1 and morale-state != "broken"] [
    set combat-status "holding"

    if not any? confederate-attackers with [health = 1 and active-wave? = true and distance myself <= effective-range] [
      let target-patch max-one-of patches with [is-union-line? = true] [weak-sector-score - distance myself]
      if target-patch != nobody and target-patch != patch-here [
        face target-patch
        rt (random 21 - random 21)
        fd 0.15
      ]
    ]
  ]
end 

to reposition-reinforcements
  ask union-reinforcements with [health = 1 and active-wave? = true and hidden? = false] [
    let target-patch max-one-of patches with [is-union-line? = true] [weak-sector-score]
    if target-patch != nobody [
      face target-patch
      if distance target-patch > 1 [ fd 0.7 ]
      if distance target-patch <= 2 [
        set combat-status "holding"
        ask union-defenders with [health = 1 and distance myself <= 3] [
          set ammo ammo + 6
          if morale-state = "shaken" [ set morale-state "steady" ]
        ]
      ]
    ]
  ]
end 

to calculate-weak-sectors
  ask patches with [is-union-line? = true] [
    let enemy-pressure count confederate-attackers with [health = 1 and active-wave? = true and distance myself <= 5]
    let defender-support count (turtle-set union-defenders union-reinforcements) with [health = 1 and distance myself <= 3]
    set weak-sector-score enemy-pressure - defender-support
  ]
end 

to resolve-combat
  ask turtles with [health = 1 and active-wave? = true] [
    let target-agent choose-target
    if target-agent != nobody and ammo > 0 and morale-state != "broken" [
      set combat-status "firing"
      perform-fire target-agent
    ]
  ]
end 

to-report choose-target
  if breed = confederate-attackers [
    let enemies (turtle-set union-defenders union-reinforcements) with
      [health = 1 and distance myself <= [effective-range] of myself]
    if any? enemies [
      report min-one-of enemies [distance myself]
    ]
  ]

  if breed = union-defenders or breed = union-reinforcements [
    let enemies confederate-attackers with
      [health = 1 and active-wave? = true and distance myself <= [effective-range] of myself]
    if any? enemies [
      report min-one-of enemies [distance myself]
    ]
  ]

  report nobody
end 

to perform-fire [target-agent]
  let p-hit compute-hit-probability target-agent
  let shots fire-rate
  set shots-fired-this-tick shots-fired-this-tick + shots

  if random-float 1.0 < p-hit [
    ask target-agent [
      let p-remove [compute-removal-probability myself] of myself
      if random-float 1.0 < p-remove [
        set health 0
      ]
      if health = 1 and random-float 1.0 < 0.24 [
        if morale-state = "steady" [ set morale-state "shaken" ]
        if morale-state = "shaken" [ set morale-state "broken" ]
      ]
    ]
  ]
end 

to-report compute-hit-probability [target-agent]
  let p base-hit-prob
  let target-patch [patch-here] of target-agent
  let my-patch patch-here
  let d distance target-agent

  set p p * (1 / [cover-value] of target-patch)
  set p p * [visibility-modifier] of my-patch
  set p p * [visibility-modifier] of target-patch

  if (breed = union-defenders or breed = union-reinforcements) and [is-ridge-crest?] of my-patch = true [
    set p p * ridge-defense-bonus
  ]

  if breed = confederate-attackers [
    if [terrain-type] of my-patch = "ridge-slope" [
      set p p * [uphill-fire-penalty] of my-patch
    ]
    if [is-ridge-crest?] of target-patch = true [
      set p p * attacker-uphill-penalty
    ]
  ]

  if morale-state = "shaken" [ set p p * 0.88 ]
  if morale-state = "broken" [ set p p * 0.60 ]

  if ammo < low-ammo-threshold [
    set p p * 0.82
  ]

  if fatigue > 14 [
    set p p * 0.92
  ]

  if d > 3 [ set p p * 0.93 ]
  if d > 4 [ set p p * 0.87 ]
  if d > 5 [ set p p * 0.80 ]

  if p < 0 [ set p 0 ]
  if p > 1 [ set p 1 ]
  report p
end 

to-report compute-removal-probability [attacker-agent]
  let p [removal-prob-if-hit] of attacker-agent
  let d distance attacker-agent

  if d <= 2 [
    set p p * 1.08
  ]

  if morale-state = "broken" [
    set p p * 1.10
  ]
  if morale-state = "shaken" [
    set p p * 1.04
  ]

  if [is-ridge-crest?] of patch-here = true [
    set p p * 0.96
  ]

  if p < 0 [ set p 0 ]
  if p > 1 [ set p 1 ]
  report p
end 

to update-ammo
  ask turtles with [health = 1 and active-wave? = true] [
    if shots-fired-this-tick > 0 [
      set ammo ammo - shots-fired-this-tick
      if ammo < 0 [ set ammo 0 ]
    ]
  ]
end 

to update-morale
  ask turtles with [health = 1 and active-wave? = true] [
    if ammo < low-ammo-threshold and morale-state = "steady" [
      set morale-state "shaken"
    ]

    let local-losses count other turtles with [health = 0 and distance myself <= 2]
    if local-losses >= 2 and morale-state = "steady" [
      set morale-state "shaken"
    ]
    if local-losses >= 3 and morale-state = "shaken" [
      set morale-state "broken"
    ]

    if breed != confederate-attackers [
      let nearby-confeds count confederate-attackers with [health = 1 and active-wave? = true and distance myself <= 2]
      if nearby-confeds >= 4 and morale-state = "shaken" [
        set morale-state "broken"
      ]
    ]

    if breed = confederate-attackers [
      if [terrain-type] of patch-here = "ridge-slope" and fatigue > 12 and morale-state = "steady" [
        if random-float 1.0 < 0.05 [
          set morale-state "shaken"
        ]
      ]
    ]

    if breed = union-defenders and reinforcement-arrived? = true [
      if any? union-reinforcements with [health = 1 and active-wave? = true and distance myself <= 3] [
        if morale-state = "shaken" [ set morale-state "steady" ]
      ]
    ]
  ]
end 

to rally-broken-units
  ask turtles with [health = 1 and morale-state = "broken" and active-wave? = true] [
    set combat-status "rallying"

    if breed = confederate-attackers [
      set heading 180
      fd 0.20
    ]

    if breed != confederate-attackers [
      set heading 0
      fd 0.20
    ]

    let nearby-friends count other turtles with [breed = [breed] of myself and health = 1 and distance myself <= 2]
    if nearby-friends >= 3 and rallied-this-tick? = false [
      if random-float 1.0 < 0.18 [
        set morale-state "shaken"
        set rallied-this-tick? true
      ]
    ]
  ]
end 

to handle-retreat-logic
  if breakthrough? = true [ stop ]

  if ticks >= 78 and union-frontline-count > 0 and union-frontline-ammo-avg < frontline-ammo-threshold [
    let steady-front count (turtle-set union-defenders union-reinforcements)
      with [health = 1 and is-frontline? = true and morale-state = "steady"]
    let all-front count (turtle-set union-defenders union-reinforcements)
      with [health = 1 and is-frontline? = true]

    if all-front > 0 [
      if steady-front / all-front >= 0.40 [
        set retreat-outcome "organized-retreat"
        ask (turtle-set union-defenders union-reinforcements) with [health = 1] [
          set combat-status "retreating"
        ]
      ]
      if steady-front / all-front < 0.40 [
        set retreat-outcome "rout"
        ask (turtle-set union-defenders union-reinforcements) with [health = 1] [
          set morale-state "broken"
          set combat-status "routing"
        ]
      ]
    ]
  ]
end 

to process-removals
  let union-losses count (turtle-set union-defenders union-reinforcements) with [health = 0]
  let confed-losses count confederate-attackers with [health = 0]

  set total-union-removed total-union-removed + union-losses
  set total-confederate-removed total-confederate-removed + confed-losses

  ask turtles with [health = 0] [
    die
  ]
end 

to update-derived-metrics
  let active-union (turtle-set union-defenders union-reinforcements) with [health = 1]
  let frontline-union active-union with [is-frontline? = true]

  set active-union-count count active-union
  set active-confederate-count count confederate-attackers with [health = 1 and active-wave? = true]

  ifelse any? frontline-union
  [ set union-frontline-ammo-avg mean [ammo] of frontline-union ]
  [ set union-frontline-ammo-avg 0 ]

  ifelse any? active-union
  [ set union-total-ammo-avg mean [ammo] of active-union ]
  [ set union-total-ammo-avg 0 ]

  set union-frontline-count count frontline-union

  ifelse count patches with [is-ridge-crest? = true] > 0
  [ set union-density-current union-frontline-count / count patches with [is-ridge-crest? = true] ]
  [ set union-density-current 0 ]

  set confederates-on-crest count confederate-attackers with [health = 1 and [is-ridge-crest?] of patch-here = true]
end 

to check-breakthrough
  if ticks >= 78 [
    if confederates-on-crest >= ridge-occupancy-threshold [
      set consecutive-crest-occupancy-ticks consecutive-crest-occupancy-ticks + 1
    ]
    if confederates-on-crest < ridge-occupancy-threshold [
      set consecutive-crest-occupancy-ticks 0
    ]

    if consecutive-crest-occupancy-ticks >= ridge-occupancy-duration-threshold [
      set breakthrough? true
      set breakthrough-tick ticks
      set breakthrough-reason "ridge-occupied"
    ]
  ]

  let close-confeds count confederate-attackers with [
    health = 1 and
    active-wave? = true and
    any? (turtle-set union-defenders union-reinforcements) with [
      health = 1 and
      is-frontline? = true and
      distance myself <= assault-distance-threshold
    ]
  ]

  if ticks >= 78 [
    if union-frontline-count > 0 and
       union-frontline-ammo-avg < frontline-ammo-threshold and
       close-confeds > 0 [
      set breakthrough? true
      set breakthrough-tick ticks
      set breakthrough-reason "ammo-collapse"
    ]
  ]
end 

There is only one version of this model, created 13 days ago by Ji Young Seo.

Attached files

File Type Description Last updated
INTA6742 Modeling v1.1.png preview Preview for 'INTA6742 Modeling v1.1' 13 days ago, by Ji Young Seo Download

This model does not have any ancestors.

This model does not have any descendants.