The Go binding
The generated Go binding calls the core through cgo. Subsystems are fields
of *Robot; methods return a value and an error. Optional results are
pointers and use nil for absent. Records have public fields with the core's
C layout. Controls take generated structs of optional fields: Num and
Text create pointers for literal values. Later controls merge in the core.
Install with make install SDK=/opt/clunkyard/sdk. A bare starter imports
clunkyard and builds with GO111MODULE=off GOPATH=/opt/clunkyard/sdk/bindings/go go build -trimpath -o bot bot.go.
The installed cgo package links the static core. A project using Go modules
can replace its clunkyard dependency with the installed package directory.
Only the resulting executable goes in the artifact.
Implement Turn(*Robot) error, and optionally Start(*Robot) error, then
call Run(strategy). A returned error or recovered panic is logged and the
turn sends its controls already set. Return &Forfeit{Code, Message} to
forfeit. Play(strategy, lines) plays protocol lines in memory for tests.
A tiny robot
package main
import cy "clunkyard"
type Tiny struct{}
func value[T any](../../sdk/bindings/go/out T,err error)T{if err!=nil{panic(err)};return out}
func check(err error){if err!=nil{panic(err)}}
func(Tiny)Turn(r *cy.Robot)error{
target:=value(r.Sensors.Nearest())
if target==nil{
check(r.Drive.Set(cy.DriveSet{Throttle:cy.Num(0.75),Turn:cy.Num(0.25)}))
check(r.Scanner.Set(cy.ScannerSet{Heading:cy.Num(value(r.Me.Heading())),Arc:cy.Num(40)}))
check(r.Status.Set(cy.StatusSet{Text:cy.Text("SEARCH"),Value:cy.Num(value(r.Scanner.Last()).Arc)}))
return nil
}
power:=value(r.Gun.PowerForFlightTime(target.Range,1));aim:=value(r.Gun.Lead(*target,power))
heading,pitch:=target.Bearing,target.Elevation;if aim!=nil{heading,pitch=aim.Heading,aim.Pitch}
check(r.Gun.Aim(cy.GunAim{Heading:cy.Num(heading),Pitch:cy.Num(pitch)}))
if value(r.Gun.CanFire(power,10)){check(r.Gun.Fire(cy.GunFire{Power:cy.Num(power)}))}
check(r.Drive.Set(cy.DriveSet{Throttle:cy.Num(0.5),Turn:cy.Num(value(r.Angles.Clamp(value(r.Angles.AngleDiff(target.Bearing,value(r.Me.Heading()))),-1,1)))}))
check(r.Scanner.Set(cy.ScannerSet{Heading:cy.Num(target.Bearing),Arc:cy.Num(10)}))
check(r.Status.Set(cy.StatusSet{Text:cy.Text("TRACK"),Value:cy.Num(target.Range)}))
return nil
}
func main(){if err:=cy.Run(Tiny{});err!=nil{panic(err)}}
make test exercises the generated Go methods and record marshalling
against the complete core conformance transcript, including exact numeric
bits and serialized acts.
Names
Every entry of the robot API 2.0.0 in Go. names.md has every language side by side.
| Canonical | Form | Go |
|---|---|---|
match.mode |
property | Match.Mode() |
match.ruleset |
property | Match.Ruleset() |
match.control |
property | Match.Control() |
match.robots |
property | Match.Robots() |
match.is_3d |
property | Match.Is3d() |
match.tick_rate |
property | Match.TickRate() |
match.max_ticks |
property | Match.MaxTicks() |
match.robot_id |
call | Match.RobotId() |
clock.tick |
property | Clock.Tick() |
clock.seconds |
property | Clock.Seconds() |
clock.remaining_ticks |
property | Clock.RemainingTicks() |
arena.size |
property | Arena.Size() |
arena.gravity |
property | Arena.Gravity() |
arena.terrain_kind |
property | Arena.TerrainKind() |
arena.ground_height |
call | Arena.GroundHeight() |
me.health |
property | Me.Health() |
me.position |
property | Me.Position() |
me.velocity |
property | Me.Velocity() |
me.heading |
property | Me.Heading() |
me.pitch |
property | Me.Pitch() |
me.roll |
property | Me.Roll() |
me.angular_velocity |
property | Me.AngularVelocity() |
me.attitude |
property | Me.Attitude() |
me.grounded |
property | Me.Grounded() |
me.altitude |
property | Me.Altitude() |
me.applied |
property | Me.Applied() |
battery.charge |
property | Battery.Charge() |
battery.capacity |
property | Battery.Capacity() |
battery.regen |
property | Battery.Regen() |
battery.sustainable_drive |
property | Battery.SustainableDrive() |
battery.compute |
property | Battery.Compute() |
battery.drive_cost |
call | Battery.DriveCost() |
drive.hover_lift |
property | Drive.HoverLift() |
drive.set |
control | Drive.Set() |
drive.forces |
control | Drive.Forces() |
drive.get |
call | Drive.Get |
gun.aim_now |
property | Gun.AimNow() |
gun.cooldown_ticks |
property | Gun.CooldownTicks() |
gun.spread |
property | Gun.Spread() |
gun.max_power |
property | Gun.MaxPower() |
gun.damage_scale |
property | Gun.DamageScale() |
gun.can_fire |
call | Gun.CanFire() |
gun.shot_speed |
call | Gun.ShotSpeed() |
gun.shot_cost |
call | Gun.ShotCost() |
gun.reload_ticks |
call | Gun.ReloadTicks() |
gun.shot_damage |
call | Gun.ShotDamage() |
gun.power_for_speed |
call | Gun.PowerForSpeed() |
gun.power_for_flight_time |
call | Gun.PowerForFlightTime() |
gun.lead |
call | Gun.Lead() |
gun.lead_point |
call | Gun.LeadPoint() |
gun.aim |
control | Gun.Aim() |
gun.fire |
control | Gun.Fire() |
gun.get |
call | Gun.Get |
scanner.last |
property | Scanner.Last() |
scanner.proximity_range |
property | Scanner.ProximityRange() |
scanner.reach |
call | Scanner.Reach() |
scanner.arc_for_reach |
call | Scanner.ArcForReach() |
scanner.set |
control | Scanner.Set() |
scanner.get |
call | Scanner.Get |
sensors.contacts |
property | Sensors.Contacts() |
sensors.nearest |
property | Sensors.Nearest() |
sensors.cues |
property | Sensors.Cues() |
sensors.contact |
call | Sensors.Contact() |
sensors.position_of |
call | Sensors.PositionOf() |
tracker.cue |
property | Tracker.Cue() |
tracker.nearest_bearing_rate |
property | Tracker.NearestBearingRate() |
tracker.velocity |
call | Tracker.Velocity() |
tracker.position |
call | Tracker.Position() |
tracker.last_seen |
call | Tracker.LastSeen() |
tracker.configure |
call | Tracker.Configure() |
nav.zone |
property | Nav.Zone() |
nav.zone.margin |
call | Nav.ZoneMargin() |
nav.zone.contains |
call | Nav.ZoneContains() |
nav.zone.distance_from |
call | Nav.ZoneDistanceFrom() |
nav.storm |
property | Nav.Storm() |
nav.storm.margin |
call | Nav.StormMargin() |
nav.storm.contains |
call | Nav.StormContains() |
nav.storm.distance_from |
call | Nav.StormDistanceFrom() |
nav.hill |
property | Nav.Hill() |
nav.hill.margin |
call | Nav.HillMargin() |
nav.hill.contains |
call | Nav.HillContains() |
nav.hill.distance_from |
call | Nav.HillDistanceFrom() |
nav.pickups |
property | Nav.Pickups() |
nav.nearest_pickup |
call | Nav.NearestPickup() |
nav.field_distance |
call | Nav.FieldDistance() |
score.me |
property | Score.Me() |
score.best |
property | Score.Best() |
score.armour |
property | Score.Armour() |
angles.normalize |
call | Angles.Normalize() |
angles.angle_diff |
call | Angles.AngleDiff() |
angles.bearing_to |
call | Angles.BearingTo() |
angles.elevation_to |
call | Angles.ElevationTo() |
angles.direction |
call | Angles.Direction() |
angles.distance |
call | Angles.Distance() |
angles.clamp |
call | Angles.Clamp() |
status.set |
control | Status.Set() |
status.get |
call | Status.Get |
raw.number |
call | Raw.Number() |
raw.text |
call | Raw.Text() |
raw.has |
call | Raw.Has() |
raw.flag |
call | Raw.Flag() |
raw.count |
call | Raw.Count() |
raw.line |
call | Raw.Line() |
raw.extra |
call | Raw.Extra() |
session.event |
property | Session.Event() |
session.next |
call | Session.Next() |
session.send |
call | Session.Send() |
session.forfeit |
call | Session.Forfeit() |
session.log |
call | Session.Log() |
session.feed |
call | Session.Feed() |
session.reply |
call | Session.Reply() |