#side Unproductive #color 933 Inspired by Productive, of course. Productive's corner-hiding is very effective, but it often runs into enemies and dies on the way. Unproductive's factories hide next to walls only when the wall is close enough that there won't be anyone in the way. They also run from shots, enemies, and injuries (like MicroAlgae). It keeps a screen of armed gatherers around the factories, so there is usually plenty of warning when enemies approach. Fighting and gathering are combined in one type. This means the fighters are well-fed, and the gatherers aren't helpless. The downside is that every lost battle cripples the economy. The cost pressure of having all this in one type is also annoying. The medium-short range blaster has most of the advantages of very short range: it's cheap, it tends to push enemies away, and it's hard to miss with. It can also hit medium-range opponents more easily (they're common) and can kill Commune's Revenge from a safe distance. There's a minor friendly-fire problem. To do: Food-sharing. Maybe coupled to keeping screen spread out. Reduce engine power when not needed. Remember hostile sides, so we don't ignore incoming Revenges etc. Fighters are too aggressive early, and tend to run off and get killed. This accounts for the bad early score. They should be more skittish (also when hurt). They should also be less agressive when far from their factories. Fighters sometimes ignore an ongoing fight when it's moved. #code ;Channels: #const ouch 4 #const facts 5 #var last-armor check-armor: armor last-armor < if position 2 ouch send then armor last-armor! return #var next-call #const interval 111 call: time next-call < ifr speed ifr position 2 facts send time interval + next-call! return #type invisible factory #color 999 #hardware armor 50 engine .03 solar-cells .35 constructor .8 processor 5 energy 200 0 #code #vector dest #const close-to-wall 20 ;If we're close to a wall, get closer. ;Going to the center because it's never seeded is egregious ; exploitation of an unintended rule, but it's silly so I ; couldn't resist. snuggle: ;x y -- position world-size 2 vs/ world-size + 6 / in-range if world-size 2 / dest! return then over close-to-wall < if nip 0 swap else over world-width close-to-wall - > if nip world-width swap then then dup close-to-wall < if drop 0 else dup world-height close-to-wall - > if drop world-height then then dest! return ;This is quick and sloppy wall-avoidance. It could be much smarter ; about moving along walls and away from corners. #const flee-range 18 #const flee-step 10 #vector threat flee: ;x y -- 2dup threat! position flee-range in-range nifr position threat v- unitize flee-range vs* threat v+ swap 2 max world-width 2 - min swap 2 max world-height 2 - min position v- unitize flee-step vs* position v+ swap 2 max world-width 2 - min swap 2 max world-height 2 - min dest! return #start armor last-armor! population 10 < if position snuggle else position dest! then do constructor-type nif energy max-energy .8 * > and-if 1 type-population 2 type-population > .3 .7 ifev random-bool 1 2 ifev constructor-type! constructor-max-rate constructor-rate! else energy 25 > constructor-max-rate * constructor-rate! then check-armor ouch receive if flee then position dest 3 in-range if 0 engine-power! position dest! else dest seek-location then call^ forever #type sentry #color FF0 #decoration FF0 slash #hardware energy 400 25 eater .8 syphon .7 10 engine .14 blaster 23 4 15 armor 333 robot-sensor 7 shot-sensor 6 food-sensor 6.5 processor 12 #code #vector dest #var delivering #vector sink ;someone to feed #vector factory ;some factory to guard #const edge 5 #var wander-radius 10 new-dest: ;wander to any factory, at an increasing distance wander-radius population 4 / 10 + max wander-radius! do wander-radius random-angle polar-to-rect factory v+ dest! dest dup edge > swap world-height edge - < and swap dup edge > swap world-width edge - < and and until-loop wander-radius 5 + wander-radius! return #start position factory! new-dest eat: do energy max-energy 15 - > if 1 delivering! else energy 200 < if 0 delivering! then then delivering if position sink syphon-range in-range if 0 engine-power! else position sink v- unitize syphon-range vs* sink v+ seek-location then else 53 periodic-food-sensor drop food-found if 10 wander-radius! food-position seek-location else dest seek-location position dest 3 in-range new-dest& ifc then then energy armor min 33 > if 49 periodic-robot-sensor if robot-found and-if robot-bomb robot-reloading or if robot-position 2 ouch send robot-position attack-robot^ else robot-position factory 22 in-range if robot-position attack-robot^ then then then 17 periodic-shot-sensor if shot-found and-if shot-velocity unitize -20 vs* shot-position v+ 2dup 2 ouch send attack^ then energy armor min 100 > if ouch receive and-if 2dup position 30 in-range if attack^ else 2drop then then then ouch clear-messages check-armor facts receive if factory! sink nor factory position dist syphon-range sink position dist max < or if factory sink! then then energy 180 > if position sink syphon-range in-range and-if sink position v- rect-to-polar syphon-direction! syphon-distance! syphon-max-rate negate syphon-rate! sync syphoned nif 0 0 sink! then else 0 syphon-rate! then energy nif call^ then forever ;;Go to a location and kill any enemies seen ;takes target as an argument attack-robot: ; tx ty -- robot-position robot-velocity lead-blaster attack: ; tx ty -- dest! 0 syphon-rate! do robot-found if dest robot-velocity seek-moving-location else dest seek-location then blaster-reload-time periodic-robot-sensor if robot-found if robot-position robot-velocity lead-blaster position robot-position v- unitize 3 vs* robot-position v+ robot-velocity 10 vs* v+ dest! else position dest 2 in-range ifr ; nobody here - give up then then robot-found nif 13 periodic-shot-sensor and-if shot-found and-if shot-velocity unitize -20 vs* shot-position v+ dest! then energy armor min 20 > while-loop ouch clear-messages new-dest return #end