diff --git a/ai.nls b/ai.nls new file mode 100644 index 0000000..77e9104 --- /dev/null +++ b/ai.nls @@ -0,0 +1,149 @@ +;; lobo: Logo Bolo +;; (c) Ben Kurtovic, 2011-2012 + +to ai-do-cycle + if ai-objective = "nothing" [ + set ai-objective ai-get-objective + ] + if ai-objective = "base-run" [ + ai-do-base-run + ] + if ai-objective = "place-pill" [ + ai-do-place-pill + ] + if ai-objective = "refuel" [ + ai-do-refuel + ] + if ai-objective = "capture-pill" [ + ai-do-capture-pill + ] + if ai-objective = "capture-base" [ + ai-do-capture-base + ] + if ai-objective = "attack-player" [ + ai-do-attack-player + ] +end + +to-report ai-get-objective + if any? bases with [team = -1] [ + report "base-run" + ] + if number-of-pills > 0 [ + report "place-pill" + ] + if any? pillboxes with [team != 1] and ammunition > 4 and armor > 6 [ + report "capture-pill" + ] + if any? bases with [team = 0] and ammunition > (max-ammo / 2) and armor > 2 [ + report "capture-base" + ] + if player != nobody and ammunition > (max-ammo / 2) and armor > 2 [ + report "attack-player" + ] + if any? bases with [team = 1] and (ammunition < max-ammo or armor < max-armor) [ + report "refuel" + ] + if player != nobody [ + report "attack-player" + ] + report "nothing" +end + +to ai-do-base-run + let mxcor xcor + let mycor ycor + let target min-one-of (bases with [team = -1]) [distancexy mxcor mycor] + let dist ai-approach-target target 0.1 + if dist < 0.1 [ + set ai-objective "nothing" + ] +end + +to ai-do-place-pill + let mxcor xcor + let mycor ycor + let target min-one-of bases [distancexy mxcor mycor] + let dist ai-approach-target target 1 + if dist < 2 [ + place-pill + ] + set ai-objective "nothing" +end + +to ai-do-refuel + let mxcor xcor + let mycor ycor + let target min-one-of (bases with [team = 1]) [distancexy mxcor mycor] + let dist ai-approach-target target 0.1 + if dist < 1 and ammunition > (max-ammo / 2) and armor > (max-armor / 2) [ + set ai-objective "nothing" + ] +end + +to ai-do-capture-pill + let mxcor xcor + let mycor ycor + let target min-one-of (pillboxes with [team != 1]) [distancexy mxcor mycor] + let dist ai-approach-target target 2 + ifelse number-of-pills > 0 or ammunition = 0 [ + set ai-objective "nothing" + ] [ + if dist < 5 and [armor] of target > 0 [ + fire + ] + if [armor] of target = 0 [ + set dist ai-approach-target target 0.1 + ] + ] +end + +to ai-do-capture-base + let mxcor xcor + let mycor ycor + let target min-one-of (bases with [team != 1]) [distancexy mxcor mycor] + let dist ai-approach-target target 2 + ifelse target = nobody or ammunition = 0 [ + set ai-objective "nothing" + ] [ + if dist < 5 and [armor] of target > 0 [ + fire + ] + if [armor] of target = 0 [ + set dist ai-approach-target target 0.1 + ] + ] +end + +to ai-do-attack-player + let mxcor xcor + let mycor ycor + ifelse player = nobody [ + set ai-objective "nothing" + ] [ + let dist ai-approach-target player 1 + if ammunition = 0 [ + set ai-objective "nothing" + ] + if dist < 5 [ + fire + ] + ] +end + +to-report ai-approach-target [target min-dist] + if target != nobody [ + tank-facexy ([xcor] of target) ([ycor] of target) + set is-accelerating? true + let dist distancexy ([xcor] of target) ([ycor] of target) + if dist < 2 and speed > 0.075 [ + decelerate friction * 5 + ] + if dist < min-dist [ + set is-accelerating? false + set speed speed / 2 + ] + report dist + ] + report 0 +end diff --git a/bullet.nls b/bullet.nls index 27cc36d..30a4422 100644 --- a/bullet.nls +++ b/bullet.nls @@ -57,7 +57,7 @@ to do-bullet-logic let shootable-pills-here pillboxes-here with [alive? = true] let targets (turtle-set tanks-here shootable-pills-here) if is-shooter-tank? [ ; Only tanks can shoot at bases - let shootable-bases-here bases-here with [armor > 0 and team != -1 and team != team-of-shooter] + let shootable-bases-here bases-here with [armor > 0 and team != -1 and team != [team-of-shooter] of myself] set targets (turtle-set targets shootable-bases-here) ] let target min-one-of targets [distancexy mxcor mycor] diff --git a/lobo.nlogo b/lobo.nlogo index 7fb94b6..b3ab610 100644 --- a/lobo.nlogo +++ b/lobo.nlogo @@ -5,6 +5,7 @@ ;; __includes [ + "ai.nls" "base.nls" "bullet.nls" "explosion.nls" @@ -452,6 +453,17 @@ TEXTBOX 0.0 1 +MONITOR +59 +466 +187 +511 +Current AI Routine +[ai-objective] of one-of tanks with [not is-player?] +17 +1 +11 + @#$#@#$#@ LOBO ---- @@ -501,7 +513,9 @@ CREDITS / MISC * My dad for introducing me to Bolo many years ago, and for helping me simplify the original Bolo game into something possible with NetLogo. -* Josh Hofing for advice on implementing certain features and emotional support. +* Josh Hofing for advice on implementing certain features and positive encouragement. + +* Chain Algorithm - I wrote the entire AI routine in less than an hour immediately before the project was due (ha!), and I don't think it would be possible if I hadn't been listening to your music on loop the entire time. Really gets your blood pumping, y'know? Yeah. This project is available on GitHub at https://github.com/earwig/lobo. I used it for syncing code between my netbook and my desktop when working on the project away from home. diff --git a/pillbox.nls b/pillbox.nls index d80bb51..2d58e15 100644 --- a/pillbox.nls +++ b/pillbox.nls @@ -43,6 +43,7 @@ to set-pill-vars [p-team] set color get-pill-color set shape (word "pillbox-alive-" armor) set size 1.1 + setxy pxcor pycor end to do-pill-logic diff --git a/tank.nls b/tank.nls index 18e4298..78d658a 100644 --- a/tank.nls +++ b/tank.nls @@ -19,6 +19,7 @@ tanks-own [ number-of-pills speed team + ai-objective ] ;; ========== @@ -47,6 +48,7 @@ to set-tank-vars [player? tteam theading] set number-of-pills 0 set speed 0 set team tteam + set ai-objective "nothing" set color get-tank-color set heading theading @@ -55,6 +57,9 @@ to set-tank-vars [player? tteam theading] end to do-tank-logic + if not is-player? [ + ai-do-cycle + ] if is-accelerating? [ accelerate acceleration ] @@ -147,6 +152,16 @@ to kill-tank ask max-one-of tanks [who] [ ; Tank that was just spawned play-sound "spawn" ] + if number-of-pills > 0 [ + ask patch ((3 - random 6) + xcor) ((3 - random 6) + ycor) [ + spawn-pillbox + ask max-one-of pillboxes [who] [ + set armor 0 + set alive? false + set shape "pillbox-dead" + ] + ] + ] die end