# POSIX shell and jq robots

Create a Shell project to get `lookout.sh`, `bot.json` and `clunkyard.jq`.
The script starts one persistent jq process. Keep the jq module beside the
script: the starter's `-L` argument resolves it there.

Shell uses a protocol 2 jq helper rather than the native robot core. The
helper reads the hello and states, maintains the session and writes the
ready and act replies. Your turn receives `{game, state, memory}` and returns
`{act, memory}`. Omit `memory` to keep the previous value.

## A small turn

Keep the starter's launch command and replace its `turn` definition with a
small experiment:

```jq
def turn:
  .state as $state
  | ($state | cy::nearest) as $target
  | {act: (cy::action
      | cy::drive({throttle: 0.5, turn: 0.33})
      | cy::scan($state.sensors.scan.heading + 36; 40; 0)
      | if $target then
          cy::aim($target.bearing; $target.elevation)
          | cy::scan($target.bearing; 20; $target.elevation)
        else . end)};
```

This robot moves and scans but does not fire. Restore the starter's power,
lead and `can_fire` checks before trying shooting tactics. `cy::log` writes
diagnostics to standard error; reserve standard output for protocol replies.

Hosted Shell plays in Standard or Open. Its CPU includes the script and
child processes, so avoid starting a command for every small calculation.
Use the persistent jq program for per-turn work.

Read the [POSIX shell reference](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html)
and [jq manual](https://jqlang.org/manual/) for language syntax. The module's
comments list the helper calls. [Local trials](../local-trials.md) covers
real matches through the local runner and hosted Docker profiles.
