Grobots Wiki
Register
Advertisement
Land-Grab vs Wild-Men

Cowboys protecting the Longhorns from a Wild Man who wandered too close

Land Grab

Author

Mike Anderson

Strategy

Starting with a small circle, steadily increase the control zone

Land Grab was begun in July 2012 and is author Mike Anderson's first serious effort. The first version released was version 3. It is currently at version 4 and version 5 is planned but not currently being worked on.

Land Grab uses a western theme in its naming, and attempts to take over the map in a way similar to how the cattle barons of the early West took over vast portions of the frontier.

Its strategy is to pick a safe spot to fortify and then send the cattle out to graze. The cattle come running home when they meet resistance, often leading chasers into the teeth of the massed perimeter guns. As the population goes up, so does the amount of land it attempts to control.

The Cowboy types patrol the edge of the control zone, stopping when they meet opposition. With their long-range guns and constant movement, this tends to make them congregate in the areas they are needed most. Docs run around a smaller perimeter doing triage and lending energy where appropriate.

Version 1 did not have roaming perimeter, nor did it let the cattle leave the range of the Cowboy's guns. It included a "Fence" type that was supposed to block enemy shots but was never fully implemented. Version 2 was much more successful, mostly because it removed those limitations and the Fence. It fared well against mid-to-high level opposition but poorly when included against the truly elite sides.

Version 3 added a massive initial Cattle Baron cell to the side in an attempt to reduce its high early death rate against the top sides. The Cattle Baron is a modified Massive Beast cell. This side was much more successful and placed 8th in a simulated Top-n tournament run by Devon on August 9, 2012 and almost removed Move! Zig from the Top 9 list.

Version 4 is an optimized Version 3. The code is more streamlined and efficient, and benefits from several bugs and unimplemented features being removed. The side is smarter about where it places the initial control zone, and also incorporates Active 9's circle-while-eating routine for its eaters. In this version, the early death problems of versions 2 and 3 are gone and the limitations of the Cowboy type are brought to the fore. Improvements to the Cowboy will be the focus of version 5.

File[]

Version 4[]

#side    Land Grab v4
#author    Mike Anderson
#date    Aug 10, 2012

#Seed 4 1

#Code

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Global Memory Map Setup			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Global memory to build food map.
;Food is stored by its Y-value and verified by the cell id.  This can lead to conflicts
;but they should be rare and only result in 2 robots bumping each other for a little while.
#Const Food-Mem-Start 200
#Const Food-Slot-Size 2

;Global Food Memory Structure:
;Slot Number = Floor(y)
; 0 = Last time someone updated this slot
; 1 = ID of claiming robot

#const home-position-addr 1
#const control-radius-addr 3
#const type-to-build-addr 4

#const longhorn-type 1
#const cowboy-type 2
#const doc-type 3
#const baron-type 4

;Timers
#const food-reserved-duration 400  ;Number of turns before reserved food is free again
#const posse-call-duration 50  ;Number of turns a posse will stay together
#const doc-call-interval 50  ;How often to repeat a doc call if needed
#const resync-interval 100   ;How often to redo synchronization
#const new-position-interval 20   ;How often to check your position on the perimeter (too much movement wastes energy)
#const new-position-duration 200   ;How long it takes to get there, max.  Longer than this and something's in the way.
#const wall-dist 5   ;How far away from the wall to build the ranch

#const doc-channel 1  ;My-loc time
#const posse-channel 2  ;Target-loc time
#const sync-channel 3   ;home-pos control-radius time

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		Common Local Variables		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;General-purpose nonpermanent storage locations
#var scratch
#vector vscratch
;Saved values from the last time we looked
#var last-armor
#var last-radius
#var last-sync-time
#var last-doc-time
#var last-new-position-time
#vector last-home
;Variables to control perimeter position
#var radius-multiple 1
#var radius-offset 0
#var pos-shift-dir 1
#var angle-from-home
;Movement control variables
#var doing-special-move  ;doing something besides <location> destination! destination seek-location
#vector destination

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		Global Properties			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
home-position:
	home-position-addr vread
return

control-radius:
	control-radius-addr read
return

set-control-radius:
	cowboy-type type-population doc-type type-population + 10 max ;population min 
	control-radius-addr write
return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		Global Functions			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

loc-on-map:   ;Checks whether the given coordinate is on the map or not.  Returns boolean
	50 - abs 50 < swap 50 - abs 50 < and
return

do-circling:
;Adapted from Active 9
	mass sqrt 80 / radius 3 / position destination v- angle 1 + polar-to-rect destination v+ position v- angle polar-to-rect engine-velocity!
return

check-sync:
	sync-channel messages if
		sync-channel receive drop
		last-sync-time!
		last-radius!
		last-home!
	then
	time last-sync-time - resync-interval > if
		set-control-radius
		home-position control-radius time 4 sync-channel send
		home-position last-home! control-radius last-radius! 
	then
return

increment-angle-from-home: ;Delta angle
	pos-shift-dir * angle-from-home + reorient angle-from-home! 
return

set-new-position:   ;Tells robots who guard the perimeter where to go
	time last-new-position-time - new-position-interval > if
		time last-new-position-time!
		last-radius radius-multiple * radius-offset + pos-shift-dir 2 * + angle-from-home polar-to-rect last-home v+ destination!
		destination loc-on-map nif  ;At the map edge, time to turn around
			pi/2 9 / scratch!
			do
				pos-shift-dir -1 * pos-shift-dir!
				scratch 1.5 * dup scratch! increment-angle-from-home
				last-radius angle-from-home polar-to-rect last-home v+ destination!
				destination loc-on-map
			until-loop
		then
		1 doing-special-move!
	then
return

gen-init:
	home-position last-home!
	control-radius last-radius!
	Armor Last-Armor!
	resync-interval negate last-sync-time!
	doc-call-interval negate last-doc-time!
	position last-home v- angle angle-from-home!
	new-position-interval negate last-new-position-time!
return

Reserve-Food: 		;To be called only when you have food on your scanner	
	;having 300 slots should prevent conflicts and still allow closely-spaced food to be shared
	do		
		food-position 3 * floor food-slot-size * Food-Mem-Start + scratch! drop
		scratch vread dup not rrot id = swap time swap - food-reserved-duration > or or if  			;No one but me has claimed it lately 
			time id scratch vwrite   					;Save the time and my id
			food-position destination!
			1 return
		then
		next-food 
	while-loop
	0 	;It's not yours, hands off!
return
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		  Longhorn Type				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#type    Longhorn
#color    00ffff                    
#decoration 000000 triangle
#hardware
    Processor	20 
	Energy 300 100
	Eater 2
	Food-Sensor 10 3
	Armor 100
	Engine .1
	Constructor 1.5
	repair-rate .2
#code

#var patrol-dir

Find-New-Pasture:	
	do
		patrol-dir pi 60 / + reorient patrol-dir!   ;keep turning slightly; 
		position 10 patrol-dir polar-to-rect v+ Destination! 
		destination loc-on-map
	until-loop
return

check-armor:
	armor last-armor < if
		last-home destination!
		1 doing-special-move!
		last-home position v- angle patrol-dir!  ;when you're done running home, keep going the opposite way
		armor last-armor!
		energy 50 - repair-rate!
		;max-repair-rate repair-rate!
	;else
	;	energy 50 < armor max-armor = or if
	;		0 repair-rate!
	;	then
	then
return

do-food-scan:
	20 periodic-food-sensor if
		food-found if
			energy 30 < if
				food-position destination! destination seek-location  ;Bypass the food reservation system if you're about to starve
			else
				reserve-food nif  
					find-new-pasture
				then
			then
		else
			find-new-pasture
		then
	then
return

check-energy:
	eaten nif
		energy 20 < if  ;I'm starving and I'm pregnant
			constructor-type if
				0 constructor-type!   ;abort and live a little while longer
			then
			energy nif
				time last-doc-time!
				position time 3 doc-channel send 
				do 
					time last-doc-time - doc-call-interval > if
						time last-doc-time! 
						position time 3 doc-channel send 
					then
					energy 20 > sync 
				until-loop				
			then
		then
	else
		;I am eating, juke a little to avoid shots.  
		do-circling
	then
return

#start

gen-init
random-angle patrol-dir!
Find-New-Pasture

Do
	check-sync
	destination position radius in-range nif  ;only move if you're not there yet (otherwise passive dodge while eating fails)
		Destination Seek-Location
	then
	
	doing-special-move if  
		destination position last-radius in-range if
			0 doing-special-move!
		then
		skip& jump
	then
	
	eaten nif
		do-food-scan
	then
	
	constructor-type 0 = if
		.2 doc-type balance-type
		.4 longhorn-type balance-type
		.4 cowboy-type balance-type
	then
	Autoconstruct

skip:	
	check-armor
	check-energy
	
forever

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;			Cowboy Type				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#type    Cowboy
#color    87ceeb                    
#decoration 000000 slash
#hardware
    Processor	20 
	Energy 300 100
    grenades 50 25 50
	Robot-Sensor 25 1
	Armor 400
	Solar-cells .1
	Engine .2
	
#code

#start

cowboy-type type-population 1 = id 1 = or if   ;I'm the only one, so where I stand is now home 
	;Find the nearest wall (going to a corner would be better but we'll probably find someone there)
	position world-height 2 / - abs swap world-width 2 / - abs > if ;Y is closer to a side
		position 50 < if
			wall-dist 
		else	
			world-height wall-dist - 
		then
	else
		position swap 50 < if
			wall-dist swap 
		else	
			world-width wall-dist - swap 
		then
	then
	home-position-addr vwrite
	set-control-radius  ;reset the control radius too
then  
;Figure out current angle from home position. We'll use that and control-radius to determine
;where to position ourselves
gen-init
home-position last-radius angle-from-home v+ destination!

do
main-loop:
	last-radius scratch!
	check-sync
	scratch last-radius = nif
		set-new-position
	then
	
	destination position radius 4 * in-range nif
		energy 100 > if ;Adjust position if you have the energy, otherwise stay put.  This means you'll keep firing and call for docs if there's a target
			destination seek-location 
		else
			0 engine-power!
		then
	else  ;Coast to a stop since your exact position is not critical
		0 doing-special-move! 0 engine-power!
	then

	energy robot-sensor-firing-cost grenades-firing-cost + > if     ;If you have the power, look for something to shoot
		grenades-reload-time 1 - periodic-robot-sensor if
			robot-found if
				robot-position position grenades-range in-range if 
					robot-position robot-velocity lead-grenade
				then
			else	
				doing-special-move nif
					pi/2 18 / increment-angle-from-home set-new-position
				then
			then
		then
	else	;Call a doc, your energy is low
		doc-type type-population if
			time last-doc-time - doc-call-interval > if
				position time 3 doc-channel send 
			then
		then		
	then
	
forever

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;			Doc Type				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#type    Doc
#color    87ceeb                    
#decoration 000000 cross
#hardware
    Processor	50 
	Energy 40 20
    syphon 2 15
	Robot-Sensor 15 10
	Armor 40
	Solar-cells .2
	Engine .05
	Constructor 1
	
#code

#const max-housecall-time 200
#var on-call
#var lowest-robot-energy
#var max-housecall-dist 30

hit-with-syphon:
	robot-position position v- angle syphon-direction! 
	position robot-position dist syphon-distance!
return

answer-phone:
	doc-channel receive if
		time - doc-call-interval < if
			2dup position dist max-housecall-dist < if
				destination!
				1 doing-special-move!
			else
				2drop
			then
		else
			2drop
		then
	then
return

#start
cowboy-type type-population 0 = if   ;No more cowboys.  Uh-oh!
	doc-type type-population 1 = if   ;I'm the last doc too.  Everyone regroup around me!
		position home-position-addr vwrite
		set-control-radius  ;reset the control radius too
	then
then   
;Figure out current angle from home position. We'll use that and control-radius to determine
;where to position ourselves
gen-init
-5 radius-offset! 
1 robot-sensor-sees-friends!
0 robot-sensor-sees-enemies!
do
main-loop:
	last-radius scratch!
	check-sync
	scratch last-radius = nif
		set-new-position
	then

	destination position radius 4 * in-range nif
		destination seek-location 
	else
		0 engine-power! 0 doing-special-move!
	then
	
	10 periodic-robot-sensor if
		0 syphon-rate!
		0 syphon-distance!
		robot-found if   ;cycle through all results and find the one with the lowest energy
			-1 scratch!
			1000 lowest-robot-energy!
			do
				doc-type robot-type  = nif
					robot-energy lowest-robot-energy < if
						robot-energy lowest-robot-energy!
						current-robot-result scratch!
					then
				then
				next-robot
			while-loop
			-1 scratch = nif
				scratch current-robot-result!
				syphon-max-rate negate syphon-rate!
				hit-with-syphon
			else
				doing-special-move nif
					pi/2 18 / increment-angle-from-home set-new-position
				then
			then
		else
			doing-special-move nif
				pi/2 18 / increment-angle-from-home set-new-position
			then
		then
	then
	
	longhorn-type type-population 0 = if   ;we're all hat, no cattle.  Do nothing except make more cows
		0 0 engine-velocity!  ;stop engines
		constructor-type longhorn-type = nif
			longhorn-type constructor-type!
		then
		constructor-max-rate constructor-rate!
		0 syphon-rate!
		do
			longhorn-type type-population sync  ;no sense wasting CPU cycles while we wait for the baby...
		until-loop
	then
	
	answer-phone
	
forever

#type Cattle Baron
;Mostly cribbed from Lunacy's Mobile Command Base
#color    87ceeb                    
#decoration 000000 square
#hardware
  processor 20
  armor 700
  engine 0.2
  eater 5
  energy 800 140
  solar-cells 0.05
  food-sensor 15 1
  blaster 36 25 10
  constructor 3
  robot-sensor 25 1
  repair-rate 0.5
#code

#var repeat-time 20

#start
;This looks like a good spot... let's build a ranch here
position home-position-addr vwrite
position last-home!
10 control-radius-addr write

do
	blaster-range time 5000 / * blaster-range max last-radius!
	time 1000 / 2pi * reorient angle-from-home!

	constructor-progress 0 = if
		longhorn-type constructor-type!
	then	
	
	energy 100 > robot-sensor-time repeat-time + time < and if
		fire-robot-sensor
	then
  
	robot-found if
		5 repeat-time!
		energy 200 > robot-position position dist 15 < or if
			robot-position robot-velocity lead-blaster
		then
	else
		20 repeat-time!
	then
  
	20 periodic-food-sensor if
		last-radius angle-from-home polar-to-rect last-home v+ destination!
		food-found if
			population 1 = if
				food-position destination!
			else
				reserve-food drop
			then
		then
	then
	
	eaten nif
		destination seek-location
	else
		do-circling
	then
	
	energy 400 > if
		constructor-max-rate constructor-rate!
	else
		0 constructor-rate!
	then
  
	energy 300 - repair-rate!

forever

#end

Advertisement