Clojure on the Java binding
Clojure calls the arena's generated Java core binding through normal Java
interop. Import the classes from clunkyard.jar; there is no copied SDK or
separate protocol, tracking or geometry implementation.
Run with java --enable-native-access=ALL-UNNAMED -cp /opt/clunkyard/sdk/bindings/java/clunkyard.jar:/usr/share/java/clojure.jar clojure.main bot.clj. The binding loads libclunkyard.so.2, or the file
named by CLUNKYARD_LIB.
A robot subclasses clunkyard.Robot. Subsystems and facts are Java
methods; absent values are Java optionals. Controls take their fields in
order or builders such as (Drive/throttle 0.5); only supplied fields
change in the turn. Throw clunkyard.Forfeit to forfeit. Other exceptions
are logged and send the controls already set. Clunkyard/play plays lines
in memory for tests.
A tiny robot
(import '[clunkyard Robot Clunkyard Drive Contact Solution])
(defn turn [^Robot bot]
(let [gun (.gun bot), drive (.drive bot), scanner (.scanner bot), angles (.angles bot), self (.me bot), status (.status bot)
^Contact target (.orElse (.nearest (.sensors bot)) nil)]
(if (nil? target)
(do (.set drive (.turn (Drive/throttle 0.75) 0.25))
(.set scanner (.heading self) 40.0)
(.set status "SEARCH" (.arc (.last scanner))))
(let [power (.powerForFlightTime gun (.range target) 1.0), ^Solution aim (.orElse (.lead gun target power) nil)]
(if (nil? aim) (.aim gun (.bearing target) (.elevation target)) (.aim gun (.heading aim) (.pitch aim)))
(when (.canFire gun power 10.0) (.fire gun power))
(.set drive (.turn (Drive/throttle 0.5) (.clamp angles (.angleDiff angles (.bearing target) (.heading self)))))
(.set scanner (.bearing target) 10.0)
(.set status "TRACK" (.range target))))))
(let [robot (atom nil), bot (proxy [Robot] [] (onTurn [] (turn @robot)))]
(reset! robot bot)
(Clunkyard/run bot))
make test SDK=... loads the Clojure entry point against the shared binding
and runs its full API conformance transcript. The example also participates
in the cross-language act identity check.
Names
Every entry of the robot API 2.0.0 in Clojure. names.md has every language side by side.
| Canonical | Form | Clojure |
|---|---|---|
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().zone().margin() |
nav.zone.contains |
call | nav().zone().contains() |
nav.zone.distance_from |
call | nav().zone().distanceFrom() |
nav.storm |
property | nav().storm() |
nav.storm.margin |
call | nav().storm().margin() |
nav.storm.contains |
call | nav().storm().contains() |
nav.storm.distance_from |
call | nav().storm().distanceFrom() |
nav.hill |
property | nav().hill() |
nav.hill.margin |
call | nav().hill().margin() |
nav.hill.contains |
call | nav().hill().contains() |
nav.hill.distance_from |
call | nav().hill().distanceFrom() |
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() |