Battle of Midway VS Edits
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
;;========================================================== ;; BATTLE OF MIDWAY - Agent-Based Model ;; INTA-6742 | Group 28 ;; ;; WORLD : 100 x 100 patches (wrapping OFF in View settings) ;; 1 patch = 10 nautical miles ;; TIME : 1 tick = 15 minutes ;; ;; DESIGN PRINCIPLE: ;; Carriers hold roughly fixed positions (historically accurate - ;; carriers launched aircraft while steaming slowly). ;; Only RECON and STRIKE PLANES move meaningfully across the map. ;; This avoids all boundary / oscillation problems. ;; ;; STARTING POSITIONS: ;; US carriers x=+30, spread vertically (NE of Midway) ;; Japan carriers x=-30, spread vertically (NW of Midway) ;; Midway Atoll x=0, y=0 ;; Distance between fleets ~ 60 patches = 600 nm ;; ;; SPEEDS (patches / tick): ;; Recon 2.0 (~120 kts PBY Catalina) ;; Strike 4.0 (~240 kts SBD Dauntless) ;; Carrier 0.2 (slow drift only) ;; ;; HISTORICAL MECHANISMS: ;; 1. US INTEL - US recon sectors cover 170-310 deg (NW arc) ;; where Japan is known to approach. ;; 2. TONE DELAY - Japan recon planes 0-1 delayed 4 ticks ;; (Tone catapult malfunction, ~1 hr late). ;; 3. JAPAN REARM - When Japan first detects US fleet, ;; all Japan carriers enter REARM for 8 ticks: ;; yellow colour, no launches, 2x bomb damage. ;; 4. WAVES - Strike planes return, refuel, and relaunch ;; continuously until their carrier sinks. ;; ;; SLIDERS (create in Interface tab, do NOT add to globals): ;; num-us-recon 0-36 default 18 ;; num-japan-recon 0-28 default 14 ;; ;; MONITORS (create in Interface tab): ;; us-carriers-alive japan-carriers-alive ;; avg-us-health avg-japan-health ;; ticks first-hit-tick ;; rearm-ticker contacts ;;========================================================== breed [ carriers one-carrier ] breed [ recons one-recon ] breed [ strikers one-striker ] carriers-own [ fside ;; "US" or "JAPAN" cname hp ;; 0-100; sinks at 0 cstate ;; "active" "rearm" "sunk" rearm-timer ;; countdown ticks for REARM state ] recons-own [ fside rstate ;; "out" "home" "refuel" "dead" rfuel smax-fuel route ;; outbound compass heading for this plane late-start ;; Tone delay: ticks before this plane can fly spotted? ;; has found enemy fleet base-x base-y ] strikers-own [ fside sstate ;; "deck" "flying" "returning" "dead" sfuel smax-fuel home-ship ;; home carrier agent target-ship ;; current attack target ] ;; Only internal state here - slider names must NOT be listed globals [ us-found? ;; US has located Japan fleet japan-found? ;; Japan has located US fleet message-queue ;; List of pending detection messages japan-in-rearm? rearm-length first-hit-tick contacts ] ;;========================================================== ;; SETUP ;;========================================================== to setup clear-all set us-found? false set japan-found? false set japan-in-rearm? false set rearm-length 8 set first-hit-tick -1 set contacts 0 set message-queue [] set recon-max-detect recon-max-detect set comm-delay comm-delay ;; Large world so agents have room to maneuver resize-world -50 50 -50 50 set-patch-size 5 ;; Ocean ask patches [ set pcolor 96 ] ;; Midway Atoll ask patches with [ distancexy 0 0 < 2 ] [ set pcolor 66 ] make-carriers make-recon make-strikers reset-ticks end to make-carriers ;; US Task Force - NE of Midway, historical ambush position let us-names (list "Enterprise" "Hornet" "Yorktown") let us-ys (list 5 0 10 ) let i 0 repeat 3 [ create-carriers 1 [ set fside "US" set cname item i us-names set hp 100 set cstate "active" set rearm-timer 0 setxy 30 (item i us-ys) set shape "airplane" set color blue set size 4 set label cname set label-color white ] set i i + 1 ] ;; Japan Kido Butai - NW of Midway let jp-names (list "Akagi" "Kaga" "Soryu" "Hiryu") let jp-ys (list 8 2 14 -4 ) set i 0 repeat 4 [ create-carriers 1 [ set fside "JAPAN" set cname item i jp-names set hp 100 set cstate "active" set rearm-timer 0 setxy -30 (item i jp-ys) set shape "airplane" set color red set size 4 set label cname set label-color white ] set i i + 1 ] end to make-recon ;; US PBY Catalinas - based at Midway (0,0) ;; Intel advantage: sectors biased 170-310 deg (NW arc toward Japan) if num-us-recon > 0 [ let arc-step 140.0 / num-us-recon create-recons num-us-recon [ let slot (who mod num-us-recon) set fside "US" set rstate "out" set smax-fuel 35 set rfuel smax-fuel set route 170 + (slot * arc-step) set late-start 0 set spotted? false set base-x 0 set base-y 0 setxy 0 0 set shape "airplane" set color 107 set size 2 ] ] ;; Japan E13A floatplanes - launched from carriers if num-japan-recon > 0 [ let arc-step 360.0 / num-japan-recon let jp-positions [] ask carriers with [ fside = "JAPAN" ] [ set jp-positions lput (list xcor ycor) jp-positions ] create-recons num-japan-recon [ let slot (who mod num-japan-recon) let pos item (slot mod length jp-positions) jp-positions set fside "JAPAN" set rstate "out" set smax-fuel 28 set rfuel smax-fuel set route (slot * arc-step) ;; Tone catapult failure: first 2 planes wait 4 ticks set late-start ifelse-value (slot < 2) [4] [0] set spotted? false set base-x item 0 pos set base-y item 1 pos setxy base-x base-y set shape "airplane" set color 25 set size 2 ] ] end to make-strikers ;; Collect carrier info at observer level (create is observer-only) let cdata [] ask carriers [ set cdata lput (list fside xcor ycor self) cdata ] foreach cdata [ row -> let s item 0 row let cx item 1 row let cy item 2 row let c item 3 row ;; 6 strike planes per carrier create-strikers 6 [ set fside s set sstate "deck" set smax-fuel 20 set sfuel smax-fuel set home-ship c set target-ship nobody setxy cx cy set shape "airplane" set color ifelse-value (s = "US") [97] [135] set size 1.5 ] ] end to process-messages let new-queue [] foreach message-queue [ msg -> let side item 0 msg let delay item 1 msg - 1 if delay <= 0 [ if side = "US" [ set us-found? true ] if side = "JAPAN" and not japan-found? [ set japan-found? true start-rearm ] ] if delay > 0 [ set new-queue lput (list side delay) new-queue ] ] set message-queue new-queue end ;;========================================================== ;; GO ;;========================================================== to go if not any? carriers with [ fside = "US" and hp > 0 ] [ stop ] if not any? carriers with [ fside = "JAPAN" and hp > 0 ] [ stop ] process-messages tick-carriers tick-recon tick-strikers draw tick end ;;========================================================== ;; CARRIERS ;; Carriers drift very slowly. Their main job is to exist as ;; targets and launch strike planes. They do NOT chase each other. ;;========================================================== to tick-carriers ask carriers with [ hp > 0 ] [ ;; REARM countdown if cstate = "rearm" [ set rearm-timer rearm-timer - 1 if rearm-timer <= 0 [ set cstate "active" set japan-in-rearm? any? carriers with [ fside = "JAPAN" and cstate = "rearm" ] ;; Rearm done - launch all deck planes immediately launch-all-deck-planes self ] ;; Slow drift while rearming clamp-drift 0.1 stop ] ;; ACTIVE: slow drift toward enemy zone, launch strikes when enemy known ;; US holds NE position until Japan detected; then holds to launch ops ;; Japan advances toward Midway; turns to face US when detected ifelse fside = "US" [ ;; US: hold position with tiny drift (historical - held launch position) set heading (270 + random 20 - 10) mod 360 clamp-drift 0.1 if us-found? [ launch-all-deck-planes self ] ] [ ;; Japan: advance SE toward Midway until US detected ifelse not japan-found? [ set heading (120 + random 20 - 10) mod 360 clamp-drift 0.2 ] [ ;; Japan detected US - turn toward US fleet let us-fleet carriers with [ fside = "US" and hp > 0 ] if any? us-fleet [ face min-one-of us-fleet [ distance myself ] set heading (heading + random 16 - 8) mod 360 ] clamp-drift 0.2 if cstate = "active" [ launch-all-deck-planes self ] ] ] ;; Direct visual detection: spot enemy fleet within 15 patches let enemy-side ifelse-value (fside = "US") ["JAPAN"] ["US"] let visible carriers in-radius 15 with [ fside = enemy-side and hp > 0 ] if any? visible [ if fside = "US" [ set us-found? true ] if fside = "JAPAN" and not japan-found? [ set japan-found? true start-rearm ] ] ] end ;; Move forward by step but never leave world bounds to clamp-drift [ step ] forward step if xcor > 48 [ set xcor 48 ] if xcor < -48 [ set xcor -48 ] if ycor > 48 [ set ycor 48 ] if ycor < -48 [ set ycor -48 ] end to launch-all-deck-planes [ carr ] let enemy-side ifelse-value ([fside] of carr = "US") ["JAPAN"] ["US"] let targets carriers with [ fside = enemy-side and hp > 0 ] if not any? targets [ stop ] ask strikers with [ home-ship = carr and sstate = "deck" ] [ set target-ship min-one-of targets [ distance myself ] set sstate "flying" set sfuel smax-fuel ] end to start-rearm set japan-in-rearm? true ask carriers with [ fside = "JAPAN" and cstate != "sunk" ] [ set cstate "rearm" set rearm-timer rearm-length ] end to do-sink set cstate "sunk" set hp 0 set shape "x" set size 5 set color gray set label (word cname " SUNK") set label-color red ask strikers with [ home-ship = myself ] [ set sstate "dead" set color gray ] end ;;========================================================== ;; RECON ;;========================================================== to tick-recon ask recons with [ rstate != "dead" ] [ ;; Refueling on ground if rstate = "refuel" [ set rfuel rfuel + 5 if rfuel >= smax-fuel [ set rfuel smax-fuel set spotted? false set rstate "out" set color ifelse-value (fside = "US") [107] [25] ] stop ] ;; Tone delay: Japan planes 0 and 1 sit on deck if late-start > 0 [ set late-start late-start - 1 stop ] set rfuel rfuel - 1 if rfuel <= 0 [ set rstate "dead" set color gray stop ] let fuel-threshold smax-fuel * 0.35 if rfuel < fuel-threshold and rstate = "out" [ set rstate "home" ] if rstate = "out" [ recon-outbound ] if rstate = "home" [ recon-return ] ] end to recon-outbound set heading route ;; Simple wall bounce - only flip heading, small margin if xcor > 47 or xcor < -47 [ set heading (360 - heading) mod 360 set xcor clamp-coord xcor -47 47 ] if ycor > 47 or ycor < -47 [ set heading (180 - heading) mod 360 set ycor clamp-coord ycor -47 47 ] forward 2.0 ;; Scan for enemy carriers within 12 patches if not spotted? [ let opp ifelse-value (fside = "US") ["JAPAN"] ["US"] let found-carriers carriers in-radius 12 with [ fside = opp and hp > 0 ] if any? found-carriers [ let tc one-of found-carriers ;; Detection probability: exponential decay with distance let d distance tc let p recon-max-detect * exp(-0.012 * d * 10) let delay comm-delay if random-float 1.0 < p [ set spotted? true set color green set rstate "home" set contacts contacts + 1 ;; Trigger detection for this faction set message-queue lput (list fside delay) message-queue ] ] ] end to recon-return ;; Japan recon follows its carrier home if fside = "JAPAN" [ let nearest-carrier min-one-of carriers with [ fside = "JAPAN" and hp > 0 ] [ distance myself ] if nearest-carrier != nobody [ set base-x [xcor] of nearest-carrier set base-y [ycor] of nearest-carrier ] ] facexy base-x base-y forward 2.0 if distancexy base-x base-y < 2 [ set rstate "refuel" set color gray setxy base-x base-y ] end to-report clamp-coord [ val lo hi ] if val > hi [ report hi ] if val < lo [ report lo ] report val end ;;========================================================== ;; STRIKE PLANES ;; Simple three-state machine: deck -> flying -> returning ;; They fly DIRECTLY to target - no wall logic needed because ;; the target is always somewhere in the middle of the world. ;;========================================================== to tick-strikers ask strikers with [ sstate != "dead" ] [ ;; On deck: just sit on carrier if sstate = "deck" [ if home-ship != nobody and [hp] of home-ship > 0 [ setxy [xcor] of home-ship [ycor] of home-ship ] stop ] ;; Fuel burn while airborne set sfuel sfuel - 1 let fuel-threshold smax-fuel * 0.35 if sfuel <= 0 [ set sstate "dead" set color gray stop ] if sfuel < fuel-threshold and sstate = "flying" [ set sstate "returning" ] if sstate = "flying" [ striker-fly ] if sstate = "returning" [ striker-return ] ] end to striker-fly ;; If target sank, find next nearest if target-ship = nobody or [hp] of target-ship <= 0 [ let opp ifelse-value (fside = "US") ["JAPAN"] ["US"] let remaining carriers with [ fside = opp and hp > 0 ] ifelse any? remaining [ set target-ship min-one-of remaining [ distance myself ] ] [ set sstate "returning" stop ] ] ;; Close on target - resolve attack when within 3 patches let dist-to-target distance target-ship if dist-to-target < 3 [ resolve-attack stop ] face target-ship forward 4.0 ;; If we overshot (moved past target), resolve attack if distance target-ship < 3 [ resolve-attack ] end to resolve-attack if target-ship = nobody or [hp] of target-ship <= 0 [ set sstate "returning" stop ] ;; AA fire: carrier defense may shoot down attacker let aa ifelse-value ([fside] of target-ship = "US") [aa-fire-us] [aa-fire-japan] if random-float 1.0 < aa [ set sstate "dead" set color gray stop ] ;; Hit roll let hit ifelse-value (fside = "US") [hit-us] [hit-japan] if random-float 1.0 < hit [ let dmg ifelse-value (fside = "US") [25] [35] ;; REARM VULNERABILITY: 2x damage when Japan carrier is rearming ;; Models Akagi/Kaga/Soryu caught with armed planes and fuel ;; hoses on deck - destroyed in the "fatal five minutes" 1020-1025 if fside = "US" and [cstate] of target-ship = "rearm" [ set dmg dmg * 2 ] ask target-ship [ set hp hp - dmg if hp < 0 [ set hp 0 ] if hp <= 0 [ do-sink ] ] if first-hit-tick = -1 [ set first-hit-tick ticks ] ] set sstate "returning" end to striker-return if home-ship = nobody or [hp] of home-ship <= 0 [ ;; Home carrier sunk - ditch at sea set sstate "dead" set color gray stop ] face home-ship forward 4.0 if distance home-ship < 2 [ ;; Back on deck - rearm and relaunch immediately if enemy still exists set sfuel smax-fuel set sstate "deck" set target-ship nobody setxy [xcor] of home-ship [ycor] of home-ship let opp ifelse-value (fside = "US") ["JAPAN"] ["US"] let can-launch false if fside = "US" [ set can-launch us-found? ] if fside = "JAPAN" [ set can-launch (japan-found? and [cstate] of home-ship = "active") ] if can-launch [ let targets carriers with [ fside = opp and hp > 0 ] if any? targets [ set target-ship min-one-of targets [ distance myself ] set sstate "flying" ] ] ] end ;;========================================================== ;; DISPLAY ;;========================================================== to draw ask patches [ set pcolor 96 ] ask patches with [ distancexy 0 0 < 2 ] [ set pcolor 66 ] ask carriers with [ hp > 0 ] [ if fside = "US" [ set color ifelse-value (hp > 50) [blue] [ ifelse-value (hp > 25) [105] [15]] ] if fside = "JAPAN" [ set color ifelse-value (cstate = "rearm") [yellow] [ ifelse-value (hp > 50) [red] [ ifelse-value (hp > 25) [25] [15]]] ] set label (word cname " " hp "hp") ] ask strikers [ if sstate = "flying" [ set color ifelse-value (fside = "US") [white] [yellow] set size 2 ] if sstate = "deck" [ set size 1.2 ] ] end ;;========================================================== ;; MONITORS ;;========================================================== to-report us-carriers-alive report count carriers with [ fside = "US" and hp > 0 ] end to-report japan-carriers-alive report count carriers with [ fside = "JAPAN" and hp > 0 ] end to-report avg-us-health let a carriers with [ fside = "US" and hp > 0 ] if not any? a [ report 0 ] report precision mean [hp] of a 1 end to-report avg-japan-health let a carriers with [ fside = "JAPAN" and hp > 0 ] if not any? a [ report 0 ] report precision mean [hp] of a 1 end to-report rearm-ticker let r carriers with [ fside = "JAPAN" and cstate = "rearm" ] if not any? r [ report 0 ] report max [rearm-timer] of r end
There are 2 versions of this model.
Attached files
| File | Type | Description | Last updated | |
|---|---|---|---|---|
| Battle of Midway VS Edits.png | preview | Preview for 'Battle of Midway VS Edits' | 15 days ago, by Vineet Sood | Download |
This model does not have any ancestors.
This model does not have any descendants.
Download this model