Commit Graph

202 Commits

Author SHA1 Message Date
Karl Ostmo
936b30d22a
extensible terrain (#1775)
Closes #1641

The `data/terrain.yaml` file is now the authoritative source of terrains, though `BlankT` is still a hard-coded special case.

I have not changed the underlying integer representation of terrain in the world function, which means that the `terrainIndexByName` Map in the `TerrainMap` record is needed for translating between `Int` and `TerrainType`.

# Demo

    scripts/play.sh -i data/scenarios/Testing/1775-custom-terrain.yaml

![Screenshot from 2024-02-22 16-51-53](https://github.com/swarm-game/swarm/assets/261693/1d263c8b-4e9c-40bf-bdc8-bf5ba8e33c4d)

# Changes

* There used to be a function called `integrateScenarioEntities` that combined the `EntityMap` stored in the `Scenario` record with the global entity map.  However, the global entity map is accessible at parse time of the `Scenario`, so we do the combining there and only ever store the combined map in the `Scenario` record.
* JSON Schema for terrain
* Removed the distinction between "World" attributes and "Terrain" attributes
* Unit tests for scenario-defined terrain and related validations
    * Validate existence of referenced terrain at scenario parse time
    * Validate attributes referenced by terrains at parse time
2024-02-29 06:22:21 +00:00
Karl Ostmo
95a90147a5
fishing scenario (#1628)
This scenario makes use of several relatively recent features/commands:
* structure placement
* structure queries (for goal checking)
* density command (for goal checking)
* combustion
* tags
* goal prerequisites with boolean expressions

## Demo

    scripts/play.sh -i Challenges/Ranching/fishing.yaml --autoplay

![image](https://github.com/swarm-game/swarm/assets/261693/a9f932a2-7481-4ee4-992a-a4dcd8b7cfd5)
2024-02-19 20:19:39 +00:00
Brent Yorgey
a1bab6d16c
Dependency updates (#1765)
Some dependency updates, to allow:
- `vty-6.2`
- `brick-2.3`
- `warp-3.4`
- `bytestring-0.12`
- `text-2.1`
2024-02-12 20:04:28 +00:00
Karl Ostmo
bce45cc0fe
gallery scenario (#1760)
![Screenshot from 2024-02-04 22-25-24](https://github.com/swarm-game/swarm/assets/261693/6541523c-4279-4fdf-a8fe-c3c8af1aa169)

    scripts/play.sh -i data/scenarios/Challenges/gallery.yaml --autoplay

## Code changes

In addition to the new scenario, this PR includes a code change to allow the order of items returned by the `tagmembers` to be specified by the scenario author.
2024-02-05 17:17:33 +00:00
Karl Ostmo
0c45811755
tweak benchmarks (#1754)
In support of #1598 (for #1739).

Runs the `idle` benchmark for many more ticks and with many more robots to try to emphasize the effect of regressions and  mitigate jitter.

Also factors out common code from the `benchmark-against-parent.sh` script.
2024-01-29 18:38:57 +00:00
Karl Ostmo
a18258c20d
extract scene renderer to its own binary (#1752)
Closes #1715

Extract scene renderer to its own binary with `swarm-scenario` as its only dependency.

This was mainly enabled by moving the `Landscape` sub-record out of the `swarm-engine` sublibrary and into `swarm-scenario`, and refactoring rendering functions to only depend on `Landscape` rather than the entire `GameState`.

# Demo

    stack build --fast swarm:swarm-scene && stack exec swarm-scene -- data/scenarios/Fun/horton.yaml --png -w 180 -h 150

![output](https://github.com/swarm-game/swarm/assets/261693/e2df3aad-3b65-46bf-8485-352facdffc76)
2024-01-29 18:01:56 +00:00
Karl Ostmo
42d4e54797
volume command (#1747)
Measures the volume of an enclosed space.
A useful alternative to the `path` command for goal checking.

## Demo

    scripts/play.sh -i data/scenarios/Testing/1747-volume-command.yaml --autoplay --speed 2
2024-01-28 01:02:08 +00:00
Karl Ostmo
aacdbf3473
Remove Benchmark dependence on AppState and TUI (#1746)
`stack bench` is now independent of the TUI and `AppState`.
2024-01-26 17:56:39 +00:00
Karl Ostmo
101b17c882
Improve separation of engine and scenario sublibraries (#1743)
Closes #1741

Remaining blocker was to move logging to concrete robot.

Most notably, the `swarm-scenario` sublibrary has been purged of its temporal component, corroborated by the removal of the `time` package dependency.
2024-01-26 00:48:20 +00:00
Karl Ostmo
3720e94c0a
move activity counts into swarm-engine (#1742)
Towards #1741
2024-01-24 23:47:44 +00:00
Karl Ostmo
05613dfba4
split scenario construction into separate sublibrary (#1719)
Towards #1715 and #1043

Creates a new `swarm-scenario` sublibrary intended for scenario data that is independent of game state.

# Planned follow-ups

This PR is already pretty large, but there is still more that can be done regarding sublibrary reorganization/splitting.

* May want to pare-down a sublibrary exclusively for world-generation without all the other baggage of scenarios.
* `Swarm.Game.ScenarioInfo`, `Swarm.Game.Tick`, and `Swarm.Game.Scenario.Status` could probably be moved from `swarm-scenario` to `swarm-engine`.
2024-01-24 21:11:14 +00:00
Karl Ostmo
9320a985e4
Use type family for RobotContext field (#1732)
Continuation of #1731.

Towards #1715 and #1043.

This refactoring step is a prerequisite for #1719 to extricate references to the `CESK` module from the base `RobotR` definition.

# In this PR:

* Extracts the `RobotContext` type to a new module
* Introduces a type family for the `RobotContext` field
2024-01-20 21:35:27 +00:00
Karl Ostmo
40ea471686
Remove superfluous trobotContext lens (#1731)
# Motivation

Want to remove dependence of `TRobot` on the `RobotContext` record.  However, a lens `trobotContext` had been added in #817 to fix #394.

# Test

    scripts/run-tests.sh --test-arguments '--pattern "394-build-drill"'
2024-01-16 17:36:36 +00:00
Karl Ostmo
3d87e71939
Use type family for robot CESK machine field (#1729)
Towards #1715 and #1043.

This refactoring step is a prerequisite for #1719 to extricate references to the `CESK` module from the base `RobotR` definition.

In this PR:
* `Swarm.Game.CESK` is imported qualified to more easily track usages
* A new `RobotMachine` type family is added to parameterize the `_machine` field.
* `CESK` is a new parameter to `addTRobot`
2024-01-14 20:11:44 +00:00
Karl Ostmo
a11fa43344
enhance styling test, fix yaml syntax (#1712)
YAML syntax in this file was actually fixed in #1672, which is not yet merged.
Cherry-pick that fix as well as enhancements to the scenario.
Towards #845.

Aside from fixing the syntax for https://github.com/swarm-game/swarm/pull/1706#discussion_r1442273107, this provides a good "before" example to showcase the fix in #1672.

    scripts/run-tests.sh --test-arguments '--pattern "1034-custom-attributes"'

and

    scripts/play.sh -i data/scenarios/Testing/1034-custom-attributes.yaml --autoplay --speed 1

![Screenshot from 2024-01-04 16-46-53](https://github.com/swarm-game/swarm/assets/261693/5e5a4435-1a36-4f59-bd6f-639c065baf2d)
2024-01-05 17:08:07 +00:00
Karl Ostmo
ea2863334a
snake game (#1699)
Demos use of a string to maintain a queue of coordinates.

![Screenshot from 2024-01-02 10-34-05](https://github.com/swarm-game/swarm/assets/261693/eaa24d48-40dc-4294-8243-2977caf4b79f)
2024-01-03 17:46:16 +00:00
Karl Ostmo
53e6f35c0e
dim sum restaurant (#1686)
scripts/play.sh -i scenarios/Challenges/dimsum.yaml --autoplay

![Screenshot from 2023-12-13 22-39-53](https://github.com/swarm-game/swarm/assets/261693/d3039776-c819-4b1c-acfe-dbd0265e9cb0)
2023-12-15 04:49:54 +00:00
Karl Ostmo
b158251a20
pushable property (#1683)
Closes #1681
2023-12-13 21:32:55 +00:00
Karl Ostmo
13ae996306
recognize structures with rotation (#1678)
Closes #1644.

The `"recognize"` property in scenario `.yaml` files is changed from a boolean to a list of "up" directions.

The structure recognizer adds a rotated copy of each supported orientation to its automaton.  Rotational symmetry is accounted for to avoid duplicate work in the recognizer.

Also in this PR:
* Add cardinal directions to the JSON schema
* Tetromino packing challenge scenario

## Demos

    scripts/run-tests.sh --test-arguments '--pattern "1644-rotated"'

### Structures dialog

![Screenshot from 2023-12-10 18-47-01](https://github.com/swarm-game/swarm/assets/261693/3904b66e-dd22-455b-8b68-5913021f806a)

### Tetromino packing

    scripts/play.sh -i data/scenarios/Challenges/pack-tetrominoes.yaml --autoplay

![Screenshot from 2023-12-09 23-11-00](https://github.com/swarm-game/swarm/assets/261693/0ad7c0ce-3553-4ad5-a927-82bbfdbe63d8)
2023-12-13 21:21:08 +00:00
Karl Ostmo
1bcd050780
Inventory requirements for child robots of system robots (#1677)
Towards #1664.

This PR adds a failing unit test.
2023-12-13 16:49:33 +00:00
Karl Ostmo
36a0046ece
unit test for recipe coverage (#1676)
Towards #1268

## Demo

    scripts/run-tests.sh --test-arguments '--pattern "Recipe coverage"'
2023-12-12 15:32:38 +00:00
Karl Ostmo
b8d37a9364
extract doc generator to separate executable (#1671)
Closes #1443.

Also added `-Wunused-packages` to clean up dependencies.

## Demo

This still works as usual:

    stack run

Output editor keywords:

    stack run swarm-docs -- editors --emacs
2023-12-04 03:45:07 +00:00
Karl Ostmo
3094abd565
Offload subrecords of GameState to other modules (#1667)
This is a continuation of #1652.

Most of the sub-records are bundled into `Swarm.Game.State.Substate`, but we create a `Swarm.Game.State.Robot` module just for robots.

We introduce a `zoomRobots` function so that applicable functions can operate directly on `Robots` state instead of `GameState`.

## Size comparison

### Before

| File | Lines |
| --- | --- |
| `State.hs` | 1569 |

### After

| File | Lines |
| --- | --- |
| `State.hs` | 812 |
| `Substate.hs` | 497 |
| `Robot.hs` | 395 |
| `Config.hs` | 21 |
## For follow-up PR:
- [ ]  Remove exports of `_viewCenter` and `_focusedRobotID` from `Swarm.Game.State.Robot`
2023-11-30 21:57:39 +00:00
Karl Ostmo
e03251cc0b
beekeeping scenario (#1599)
Builds upon #1579

Requires player to constuct beehives to attract bees and make honey, which is then brewed as mead.

## Demo

    scripts/play.sh -i scenarios/Challenges/Ranching/beekeeping.yaml --autoplay

![image](https://github.com/swarm-game/swarm/assets/261693/f8c5c898-d865-4fe7-954d-c9e5b5f9a5c8)

Map:
![map](https://github.com/swarm-game/swarm/assets/261693/9c288edb-e71f-4a59-bd32-e1ecfdb1b60e)

## References

Mead hall inspiration: https://cartographyassets.com/assets/13507/the-mead-hall-of-the-clan-ulfgar-50-x-50/

![Mead-Hal-v1-No-Light-or-Shadow-with-grid-copy-scaled](https://github.com/swarm-game/swarm/assets/261693/a2d276f1-a522-499e-9a4b-7ce1df754107)
2023-11-28 03:39:28 +00:00
Karl Ostmo
3c970c19ff
group robot info into subrecord (#1652)
Add another subrecord to `GameState` dedicated to robot fields.  This shrinks the size of `GameState` by 8 more fields.  It's getting reasonable now!

The `_viewCenter*` fields were put there too, for now, because the manually-defined `setter` of the `viewCenterRule` lens needs access to the `robotMap` field.
2023-11-22 18:06:13 +00:00
Karl Ostmo
e43ff3e915
Structure recognition with encroaching entities (#1637)
Structure recognition already supports overlapping bounding boxes between two structures (where one of the structure templates has vacant cells).  This PR adds test coverage for this.

More importantly, this PR makes sure that structures can be recognized even with non-participating entities within their bounding box.  The same integration test (`1575-bounding-box-overlap.yaml`) covers this case as well.

A "non-participating entity" is an entity that is not an ingredient to any structures participating in structure recognition.  Such entities are "masked out" when the world cells (i.e. the "haystack") are queried to apply the Aho-Corasick matcher to.

## Example

Given a structure defined as `boulder`s (`@`) in a backwards "L" shape, it will be recognized despite a `mountain` (`A`) within its bounding box:

![image](https://github.com/swarm-game/swarm/assets/261693/1c559a50-e9bd-4f97-87a1-20d4f964cfa9)

This is because `mountain` is not a member of any recognizable structures.

## Caveats

This PR strictly increases the situations in which valid structures may be recognized.

However, it is still the case that encroaching entities that **are** members of some structure template will thwart structure recognition.  One consequence of this is that the order in which structures are completed can matter.

If some partially-built but incomplete structure lies within the bounding box of another candidate structure, the candidate structure will not be recognized as "complete" unless (1) the offending entities are removed first, or (2) the other structure is completed first.
2023-11-20 04:21:14 +00:00
Karl Ostmo
37cae2ac15
Implement entity tags and commands (#1635)
Closes #1631

## Design

* Entities have a new property: a `Set` of textual tags.
* Two new commands are introduced:
    * `HasTag` checks whether a single entity has a given tag
    * `TagMembers` allows cycling through all members with a given tag
* `TagMembers` may be considered more powerful than `HasTag`, so has its own separate capability (`CTagmembers`).
* A map is computed at scenario initialization to facilitate `TagMembers` lookups.
* Tag names are highlighted in yellow in markdown.

## Demo

    scripts/play.sh -i scenarios/Testing/1631-tags.yaml --autoplay

## Other changes

* Incidentally, changed `knownEntities` from a list to a `Set` so that `Set.member` can be used instead of `elem`.
2023-11-20 00:01:46 +00:00
persik
a306d05f61
Add TimeEffect effect for getting current time (#1620)
fixes #1502

Add TimeEffect effect for getting current time.
2023-11-15 06:17:09 +00:00
Karl Ostmo
f9ef0094f0
path caching (#1595)
Closes #1569

## Performance

Path cache invalidation upon world modifications (i.e. entities inserted or removed) entails iterating over all of the previously-cached paths [here](https://github.com/swarm-game/swarm/pull/1595/files#r1390158411).  For efficiency's sake, we avoid iterating over "all existing robots".

Any scenario that does not use the `path` command is entirely unaffected by this change.

## Demo

Previously, this demo was virtually unplayable, since when moving between widely-spaced "clusters" of flowers, an expensive A-star search was invoked at almost every tick.  Now, the vast majority of moves utilize the cache, and the demo exhibits minimal stuttering (e.g. when a single A-star search is performed when moving between distant clusters).

    scripts/play.sh -i scenarios/Fun/horton.yaml --autoplay --speed 7

### Event log

An event log specific to the path cache is maintained with its own ring buffer:

    scripts/play.sh -i scenarios/Testing/1569-pathfinding-cache/1569-harvest-batch.yaml --autoplay

 and view http://localhost:5357/paths/log
2023-11-14 21:15:00 +00:00
Karl Ostmo
bd2de6c9b0
structure recognition enhancements (#1618)
* Highlight occurrences of structures in markdown in red
* Add a new `blueprint` entity to provide `floorplan` and `structure` commands
* new `floorplan` command to get the dimensions of a structure
* structure location is southwest instead of northwest corner
* handle structures with "holes"  for statically-recognized structures and when modifying interior cells post-recognition

Each of these is its own commit for reviewability's sake.
2023-11-14 18:08:02 +00:00
Karl Ostmo
d63e7d81ef
Structure browser and recognizer (#1579)
Closes #1575

Implements structure recognition.

## Features

* Structure browsing dialog (`F6`) that becomes available if a scenario declares any recognizable structures
* Automatically recognizes statically-placed structures upon scenario initialization, accounting for occlusion by other entity/structure placement
* New `structure` command for querying location of recognized structures (primarily intended for system robots and goal checking)
* Efficiently recognizes structures immediately upon completion
* Accounts for removal of structures
* Several new integration tests
* Structured web-interface log to help understand/debug the recognition process
* Re-uses much of the functionality built previously for defining structures (#1332)

Other changes:
* Improved validation for static structure placement (ensure valid structure names instead of failing silently)
* Moved a few functions (`getNeighborLocs`, `zoomWorld`, `entityAt`, `robotWithID`, `robotWithName`) out of `Step.Util` and into `State` so that recognizer initialization, which becomes a field in `GameState`, could use them
* split `scenarioToGameState` into pure and non-pure functions

## Optimizations

Scenarios that do not make use of structure recognition are entirely unaffected, performance-wise.

Some optimizations include:

* Structure definitions must "opt-in" to participate in automatic recognition
* Aho-Corasick automatons optimized by:
    * only initiate structure search if a placed entity exists on a participating structure template
    * initializing different automatons for each type of "placed entity"
    * pruning inapplicable row candidates for 2-D search

The row-level structure recognition cache described in #1575 was not implemented; it's probably not worth the complexity cost.

# UI Demo

    scripts/play.sh -i scenarios/Testing/1575-structure-recognizer/1575-browse-structures.yaml --autoplay

1. Press `F6` for Structure Browser dialog
2. View http://localhost:5357/recognize/log and http://localhost:5357/recognize/found

![image](https://github.com/swarm-game/swarm/assets/261693/e32d3572-7e53-42d6-84cd-393c57a8aeac)

# Future improvements

* Refactor `State.hs` so that the new helper functions can live elsewhere
* Support non-rectangular recognizable structures
* Allow flip/rotate of recognizable structures
* Structure ownership by robots
* Consolidate code between the Goals and Structures modal dialogs, and the Achievements browser
* Enforce minimum/maximum dimensions for structure definitions
2023-11-08 06:44:27 +00:00
Karl Ostmo
4f21fd89e0
combination locks scenario (#1591)
![image](https://github.com/swarm-game/swarm/assets/261693/4229e45e-5c9c-4c15-b82e-0d5a28472798)

# Demo

    scripts/play.sh -i data/scenarios/Challenges/combo-lock.yaml --autoplay
2023-10-22 05:06:19 +00:00
Ondřej Šebek
2c3fc525c9
Add wave program to benchmarks (#1576)
* add wave program and parametrise it to compare inlined/generic version
* use [`tasty-bench`](https://hackage.haskell.org/package/tasty-bench) library to show comparison
* move benchmarks to test folder as they can now share tasty code
* closes #1574 

Using the recursive definition with ifs leads to a 3x slowdown:
```
wavesInlined
  10: OK
    361  ms ±  29 ms
  20: OK
    718  ms ±  35 ms
  30: OK
    1.066 s ±  28 ms
  40: OK
    1.437 s ±  37 ms
wavesWithDef
  10: OK
    1.052 s ±  51 ms, 2.92x
  20: OK
    2.117 s ±  34 ms, 2.95x
  30: OK
    3.144 s ±  80 ms, 2.95x
  40: OK
    4.191 s ±  91 ms, 2.92x
```
But if we just inline and simplify the code, we can remove the runtime overhead completely.
2023-10-09 04:45:27 +00:00
Ondřej Šebek
694e00b678
Make function chains pretty (#1479)
- closes #1473
2023-10-07 21:04:01 +00:00
Karl Ostmo
c1d0fdd3ad
robot wave scenario (#1556)
![image](https://github.com/swarm-game/swarm/assets/261693/5952ccb9-02fe-47af-9a22-b45b130316e2)

# Demo

    scripts/play.sh -i data/scenarios/Challenges/wave.yaml --autoplay
2023-10-01 14:49:54 +00:00
Karl Ostmo
93bbbe3dd0
ping command (#1541)
Closes #1535
# Demo

    scripts/play.sh -i scenarios/Testing/1535-ping/1535-in-range.yaml --autoplay
2023-09-24 07:49:48 +00:00
Karl Ostmo
e06e04f622
Pathfinding command (#1523)
Closes #836

# Tests
    scripts/run-tests.sh  --test-arguments '--pattern "Pathfinding"'

# Demo

    scripts/play.sh -i data/scenarios/Testing/836-pathfinding/836-automatic-waypoint-navigation.yaml --autoplay
2023-09-19 06:21:03 +00:00
Brent Yorgey
85b33ef5c9
Refactor LogEntry type (#1513)
In preparation for #1483.   `LogEntry` started life as something specific to robot logs.  It then evolved to be used in the system log as well (see #1039 and #652), but in a sort of hacky way.  This PR refactors `LogEntry` to be more generic.

- Move `Swarm.Game.Log` -> `Swarm.Log` since it's not specific to gameplay.
- Rename `ErrorLevel` to `Severity`, add a new `Info` level, and add a top-level `leSeverity` field
- Rename `leRobotName` to just `leName`, since it was already being used to name both robots and system components anyway
- Move robot-specific fields (*e.g.* robot ID) into the new `RobotLogSource` type, and add `LogSource` to differentiate between robot and system logs
- Various other minor improvements and tweaks
2023-09-15 03:08:25 +00:00
Brent Yorgey
932bc45696
Lengthen timeout for Challenges/ice-cream (#1522)
It seems like I have seen a few spurious failures where this scenario timed out, so make the timeout longer to add some buffer.
2023-09-13 22:42:23 +00:00
Gagan Chandan
c150b05fb0
Add syntax highlighting and LSP configuration for Vim/Neovim (#1518)
This adds two files. The first is the syntax file responsible for basic highlighting. The highlight categories are based roughly on those seen in the Emacs file ([swarm-mode.el](https://github.com/swarm-game/swarm/blob/main/editors/emacs/swarm-mode.el)). The second is the file for configuring the language server. Since it is based on Neovim's native LSP client, it only works with Neovim and not Vim.

`README.md` in the `editor` folder has also been updated to include instructions for setting these up.
2023-09-13 22:11:29 +00:00
Karl Ostmo
bb31126c75
Decompose GameState into sub-records (#1510)
Towards #872

Previously, the `GameState` record had `41` toplevel members.  It now has `22`.   Logical grouping of the fields makes it easier to peruse the code and paves the way to split `State.hs` into smaller modules.  Some functions now may even be able to operate exclusively on subsets of the game state, rather than having to pass in `GameState` as a whole.

There is potential to go even farther, by extracting view-related and robot-related members to their own records, but I figured I'd pursue this refactoring incrementally.
2023-09-11 18:25:45 +00:00
Brent Yorgey
41c94f1dc1
Grant RobotIntoWater achievement (#1504)
Towards #1435.  Some refactoring, + grant `RobotIntoWater` achievement when a robot dies in the water.
2023-09-11 14:49:54 +00:00
Brent Yorgey
096251d9cb
generalize variables bound by <- (#1501)
Closes #351.

I sat down with @ccasin today to look at #351. He convinced me that it is actually fine to return `forall a. a -> a` as the type of `r` in `r <- return (\i.i)`, even though `return (\i.i)` has type `forall a. cmd (a -> a)` and we can never have a type `cmd (forall a. a -> a)`. Basically, in a Hindley-Milner-style system it is always safe to generalize at any time.

The real problem --- which I was very close to discovering in https://github.com/swarm-game/swarm/issues/351#issuecomment-1146274801 --- is simply that we need to generalize the type of variables bound by `<-`.  However, we need to make sure to do so before putting that variable in the context, which I apparently failed to do when I tried fixing this before.
2023-09-09 17:36:43 +00:00
Brent Yorgey
8ffd05665b
Add solution for world101 tutorial (#1498)
Closes #1450.

## Demo

    scripts/play.sh -i data/scenarios/Tutorials/world101.yaml --autoplay
2023-09-09 05:55:58 +00:00
Karl Ostmo
98ebf74cfe
more documentation tweaks (#1493)
Also:
* adds a script to view locally-generated Haddocks.
* Describes module organization as per https://github.com/swarm-game/swarm/pull/1069#issue-1565024308 in the toplevel cabal package description
2023-09-07 07:00:44 +00:00
Karl Ostmo
1aa92d01ea
Robot activity counts in F2 menu (#1484)
Towards #1341.

    scripts/play.sh -i data/scenarios/Testing/1341-command-count.yaml --autoplay --speed 1

![image](https://github.com/swarm-game/swarm/assets/261693/f658bb9c-6bb8-494c-b204-6d5bb0106b92)
2023-09-07 06:00:07 +00:00
Ondřej Šebek
64fe02892b
Fix lambda precedence (#1470)
- give lambdas lower precedence (9) then application (10)
- closes #1468

Before (with #1459):
```
❯ cabal run swarm -O0 -- format <(echo '\\m. case m (\\x. x + 1) (\\y. y * 2)')
\m. case m \x. x + 1 \y. y * 2
```

After:
```
❯ cabal run swarm -O0 -- format <(echo '\\m. case m (\\x. x + 1) (\\y. y * 2)')
\m. case m (\x. x + 1) (\y. y * 2)
```
2023-08-26 17:18:13 +00:00
Ondřej Šebek
61df42e7b9
Test runtime log does not contain errors (#1457)
- closes #1449
2023-08-26 13:29:05 +00:00
Ondřej Šebek
98a6b75ea1
Make pretty Terms format prettier (#1464)
- improve layout of terms:
  - break lines on binds, unless it fits on one line
  - lambdas go on same line, but the body _can_ go to next line
  - def and let can have long body on next line (indented for def)
  - parens and braces have body indented if it does not fit on line
- closes #11

Example using `--format` from #1459:

```
> cabal run swarm -O0 -- format scenarios/Challenges/_blender/patrol-clockwise.sw                          
def forever = \c. c; force forever c end;
def encircle = \lDir. \rDir.
  turn lDir;
  b <- blocked;
  if b {turn rDir} {wait 1};
  fwBlocked <- blocked;
  if fwBlocked {turn rDir} {move}
end;
def patrolCW = force forever (force encircle right left) end;
force patrolCW
```
2023-08-25 21:08:32 +00:00
Ondřej Šebek
8ed5b92edc
Add robot ownership to integration test suite (#1451)
- followup to #1431
- remove the warning seen in #1449
2023-08-23 13:03:10 +00:00