The CLIPS adapter
CLIPS rules run in process through clipspy, on the installed Python binding.
The robot core owns parsing, tracking, helpers and acts. Match templates and
field tables are generated from protocol/v2/schema.json; every canonical
query and control is a cy-* foreign function generated from
protocol/v2/api.json. Install with make install SDK=/opt/clunkyard/sdk
after installing Python. Run with
PYTHONPATH=/opt/clunkyard/sdk/bindings/clips:/opt/clunkyard/sdk/bindings/python python3 bot.py.
(cy-me-heading) reads a property; (cy-gun-shot-speed 2.0) calls a query.
A record is a multifield in its declared field order, nested records inline.
A list starts with its count, followed by its records. An absent result is
nil; booleans are TRUE and FALSE. A control takes its canonical field
name and value: (cy-drive-set "throttle" 0.5). Bare fire uses
(cy-gun-fire); getters take the field name. The generated reference gives
record layouts and every callable name.
Compatibility facts include game, me, state, contact, cue, zone,
storm, pickup, hill and the match's mechanics. The adapter resets the
environment for each state, restores hello facts, asserts state facts and
runs your rules. Globals persist between turns. Output facts drive,
forces, aim, scan, fire, status, extra and forfeit remain available;
later facts override earlier fields. The familiar geometry functions forward
to the core. shot-damage includes the core's current damage scale and uses
the current tick. Direct cy-* calls preserve canonical core semantics.
A tiny robot
Save these rules as tiny.clp:
(defrule tiny
(state)
=>
(bind ?target (cy-sensors-nearest))
(if (eq ?target nil)
then
(cy-drive-set "throttle" 0.75)
(cy-drive-set "turn" 0.25)
(cy-scanner-set "heading" (cy-me-heading))
(cy-scanner-set "arc" 40)
(cy-status-set "text" "SEARCH")
(cy-status-set "value" (nth$ 3 (cy-scanner-last)))
else
(bind ?range (nth$ 3 ?target))
(bind ?bearing (nth$ 4 ?target))
(bind ?elevation (nth$ 5 ?target))
(bind ?power (cy-gun-power-for-flight-time ?range 1))
(bind ?aim (cy-gun-lead (expand$ ?target) ?power))
(cy-gun-aim "heading" (if (eq ?aim nil) then ?bearing else (nth$ 1 ?aim)))
(cy-gun-aim "pitch" (if (eq ?aim nil) then ?elevation else (nth$ 2 ?aim)))
(if (eq (cy-gun-can-fire ?power 10) TRUE) then (cy-gun-fire "power" ?power))
(cy-drive-set "throttle" 0.5)
(cy-drive-set "turn" (cy-angles-clamp (cy-angles-angle-diff ?bearing (cy-me-heading)) -1 1))
(cy-scanner-set "heading" ?bearing)
(cy-scanner-set "arc" 10)
(cy-status-set "text" "TRACK")
(cy-status-set "value" ?range)))
Save the launcher as bot.py:
import clunkyard_clips
clunkyard_clips.run("tiny.clp")
run and play use Python's core session. Foreign call errors are reported
after rules run; user errors preserve controls set so far. Raise a forfeit
fact to give up a match. make test exercises the actual CLIPS function
surface against every API vector. Non-finite inputs cannot be represented
by CLIPS. Complete names.
Names
Every entry of the robot API 2.0.0 in CLIPS. names.md has every language side by side.
| Canonical | Form | CLIPS |
|---|---|---|
match.mode |
property | (cy-match-mode ...) |
match.ruleset |
property | (cy-match-ruleset ...) |
match.control |
property | (cy-match-control ...) |
match.robots |
property | (cy-match-robots ...) |
match.is_3d |
property | (cy-match-is-3d ...) |
match.tick_rate |
property | (cy-match-tick-rate ...) |
match.max_ticks |
property | (cy-match-max-ticks ...) |
match.robot_id |
call | (cy-match-robot-id ...) |
clock.tick |
property | (cy-clock-tick ...) |
clock.seconds |
property | (cy-clock-seconds ...) |
clock.remaining_ticks |
property | (cy-clock-remaining-ticks ...) |
arena.size |
property | (cy-arena-size ...) |
arena.gravity |
property | (cy-arena-gravity ...) |
arena.terrain_kind |
property | (cy-arena-terrain-kind ...) |
arena.ground_height |
call | (cy-arena-ground-height ...) |
me.health |
property | (cy-me-health ...) |
me.position |
property | (cy-me-position ...) |
me.velocity |
property | (cy-me-velocity ...) |
me.heading |
property | (cy-me-heading ...) |
me.pitch |
property | (cy-me-pitch ...) |
me.roll |
property | (cy-me-roll ...) |
me.angular_velocity |
property | (cy-me-angular-velocity ...) |
me.attitude |
property | (cy-me-attitude ...) |
me.grounded |
property | (cy-me-grounded ...) |
me.altitude |
property | (cy-me-altitude ...) |
me.applied |
property | (cy-me-applied ...) |
battery.charge |
property | (cy-battery-charge ...) |
battery.capacity |
property | (cy-battery-capacity ...) |
battery.regen |
property | (cy-battery-regen ...) |
battery.sustainable_drive |
property | (cy-battery-sustainable-drive ...) |
battery.compute |
property | (cy-battery-compute ...) |
battery.drive_cost |
call | (cy-battery-drive-cost ...) |
drive.hover_lift |
property | (cy-drive-hover-lift ...) |
drive.set |
control | (cy-drive-set ...) |
drive.forces |
control | (cy-drive-forces ...) |
drive.get |
call | (cy-drive-get ...) |
gun.aim_now |
property | (cy-gun-aim-now ...) |
gun.cooldown_ticks |
property | (cy-gun-cooldown-ticks ...) |
gun.spread |
property | (cy-gun-spread ...) |
gun.max_power |
property | (cy-gun-max-power ...) |
gun.damage_scale |
property | (cy-gun-damage-scale ...) |
gun.can_fire |
call | (cy-gun-can-fire ...) |
gun.shot_speed |
call | (cy-gun-shot-speed ...) |
gun.shot_cost |
call | (cy-gun-shot-cost ...) |
gun.reload_ticks |
call | (cy-gun-reload-ticks ...) |
gun.shot_damage |
call | (cy-gun-shot-damage ...) |
gun.power_for_speed |
call | (cy-gun-power-for-speed ...) |
gun.power_for_flight_time |
call | (cy-gun-power-for-flight-time ...) |
gun.lead |
call | (cy-gun-lead ...) |
gun.lead_point |
call | (cy-gun-lead-point ...) |
gun.aim |
control | (cy-gun-aim ...) |
gun.fire |
control | (cy-gun-fire ...) |
gun.get |
call | (cy-gun-get ...) |
scanner.last |
property | (cy-scanner-last ...) |
scanner.proximity_range |
property | (cy-scanner-proximity-range ...) |
scanner.reach |
call | (cy-scanner-reach ...) |
scanner.arc_for_reach |
call | (cy-scanner-arc-for-reach ...) |
scanner.set |
control | (cy-scanner-set ...) |
scanner.get |
call | (cy-scanner-get ...) |
sensors.contacts |
property | (cy-sensors-contacts ...) |
sensors.nearest |
property | (cy-sensors-nearest ...) |
sensors.cues |
property | (cy-sensors-cues ...) |
sensors.contact |
call | (cy-sensors-contact ...) |
sensors.position_of |
call | (cy-sensors-position-of ...) |
tracker.cue |
property | (cy-tracker-cue ...) |
tracker.nearest_bearing_rate |
property | (cy-tracker-nearest-bearing-rate ...) |
tracker.velocity |
call | (cy-tracker-velocity ...) |
tracker.position |
call | (cy-tracker-position ...) |
tracker.last_seen |
call | (cy-tracker-last-seen ...) |
tracker.configure |
call | (cy-tracker-configure ...) |
nav.zone |
property | (cy-nav-zone ...) |
nav.zone.margin |
call | (cy-nav-zone-margin ...) |
nav.zone.contains |
call | (cy-nav-zone-contains ...) |
nav.zone.distance_from |
call | (cy-nav-zone-distance-from ...) |
nav.storm |
property | (cy-nav-storm ...) |
nav.storm.margin |
call | (cy-nav-storm-margin ...) |
nav.storm.contains |
call | (cy-nav-storm-contains ...) |
nav.storm.distance_from |
call | (cy-nav-storm-distance-from ...) |
nav.hill |
property | (cy-nav-hill ...) |
nav.hill.margin |
call | (cy-nav-hill-margin ...) |
nav.hill.contains |
call | (cy-nav-hill-contains ...) |
nav.hill.distance_from |
call | (cy-nav-hill-distance-from ...) |
nav.pickups |
property | (cy-nav-pickups ...) |
nav.nearest_pickup |
call | (cy-nav-nearest-pickup ...) |
nav.field_distance |
call | (cy-nav-field-distance ...) |
score.me |
property | (cy-score-me ...) |
score.best |
property | (cy-score-best ...) |
score.armour |
property | (cy-score-armour ...) |
angles.normalize |
call | (cy-angles-normalize ...) |
angles.angle_diff |
call | (cy-angles-angle-diff ...) |
angles.bearing_to |
call | (cy-angles-bearing-to ...) |
angles.elevation_to |
call | (cy-angles-elevation-to ...) |
angles.direction |
call | (cy-angles-direction ...) |
angles.distance |
call | (cy-angles-distance ...) |
angles.clamp |
call | (cy-angles-clamp ...) |
status.set |
control | (cy-status-set ...) |
status.get |
call | (cy-status-get ...) |
raw.number |
call | (cy-raw-number ...) |
raw.text |
call | (cy-raw-text ...) |
raw.has |
call | (cy-raw-has ...) |
raw.flag |
call | (cy-raw-flag ...) |
raw.count |
call | (cy-raw-count ...) |
raw.line |
call | (cy-raw-line ...) |
raw.extra |
call | (cy-raw-extra ...) |
session.event |
property | (cy-session-event ...) |
session.next |
call | (cy-session-next ...) |
session.send |
call | (cy-session-send ...) |
session.forfeit |
call | (cy-session-forfeit ...) |
session.log |
call | (cy-session-log ...) |
session.feed |
call | (cy-session-feed ...) |
session.reply |
call | (cy-session-reply ...) |