mirror of
https://github.com/swarm-game/swarm.git
synced 2024-07-14 18:00:34 +03:00
topography sublibrary (#1836)
Towards #1043. The eventual goal of this sublibrary split is to have a self contained library that can compose 2D grids of arbitrary content (perhaps colored pixels, or boolean values). This could be useful outside of the `swarm` game. I would also like to write unit tests for the structure recognizer that are independent of the `Entity` type. # Major Changes ## Direction module * Moved `Swarm.Language.Syntax.Direction` to `swarm-util`, since both `swarm-lang` and `swarm-topology` depend on it, but not on each other. * Removed the re-export of direction things from `Swarm.Language.Syntax` ## Structure module The `Swarm.Game.Scenario.Topography.Structure` module has been split into two: * `Swarm.Game.Scenario.Topography.Structure` * `Swarm.Game.Scenario.Topography.Structure.Type` The former retains the YAML parsing logic. The latter is agnostic of `Enitiy` type and the palette . At some future point, I might want to move the YAML parsing to this sublibrary while still retaining independence of `Entity` type. ## Structure recognizer The structure recognizer is independent of the content of Cells (i.e. it does not need to know what an `Entity` is), except: 1. during initialization 2. when retrieving the original cell content after recognition Type parameters for three kinds of data have been added to the recognizer: 1. `Cell`/`PCell` 2. `Entity` 3. `EntityName` Eventually it may be possible to eliminate one or two of these type parameters, with some refactoring.
This commit is contained in:
parent
01c45ab968
commit
ca4a2b809d
@ -4,106 +4,124 @@
|
|||||||
<!-- Generated by graphviz version 2.43.0 (0)
|
<!-- Generated by graphviz version 2.43.0 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: plan Pages: 1 -->
|
<!-- Title: plan Pages: 1 -->
|
||||||
<svg width="210pt" height="476pt"
|
<svg width="278pt" height="476pt"
|
||||||
viewBox="0.00 0.00 209.50 476.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 277.50 476.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 472)">
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 472)">
|
||||||
<title>plan</title>
|
<title>plan</title>
|
||||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-472 205.5,-472 205.5,4 -4,4"/>
|
<polygon fill="white" stroke="transparent" points="-4,4 -4,-472 273.5,-472 273.5,4 -4,4"/>
|
||||||
<!-- swarm -->
|
<!-- swarm -->
|
||||||
<g id="node1" class="node">
|
<g id="node1" class="node">
|
||||||
<title>swarm</title>
|
<title>swarm</title>
|
||||||
<path fill="none" stroke="brown" stroke-width="2" d="M122.5,-36C122.5,-36 81.5,-36 81.5,-36 75.5,-36 69.5,-30 69.5,-24 69.5,-24 69.5,-12 69.5,-12 69.5,-6 75.5,0 81.5,0 81.5,0 122.5,0 122.5,0 128.5,0 134.5,-6 134.5,-12 134.5,-12 134.5,-24 134.5,-24 134.5,-30 128.5,-36 122.5,-36"/>
|
<path fill="none" stroke="brown" stroke-width="2" d="M168,-36C168,-36 127,-36 127,-36 121,-36 115,-30 115,-24 115,-24 115,-12 115,-12 115,-6 121,0 127,0 127,0 168,0 168,0 174,0 180,-6 180,-12 180,-12 180,-24 180,-24 180,-30 174,-36 168,-36"/>
|
||||||
<text text-anchor="middle" x="102" y="-14.3" font-family="Times,serif" font-size="14.00">swarm</text>
|
<text text-anchor="middle" x="147.5" y="-14.3" font-family="Times,serif" font-size="14.00">swarm</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-web -->
|
<!-- swarm-web -->
|
||||||
<g id="node2" class="node">
|
<g id="node2" class="node">
|
||||||
<title>swarm-web</title>
|
<title>swarm-web</title>
|
||||||
<path fill="none" stroke="gray" stroke-width="2" d="M139,-108C139,-108 65,-108 65,-108 59,-108 53,-102 53,-96 53,-96 53,-84 53,-84 53,-78 59,-72 65,-72 65,-72 139,-72 139,-72 145,-72 151,-78 151,-84 151,-84 151,-96 151,-96 151,-102 145,-108 139,-108"/>
|
<path fill="none" stroke="gray" stroke-width="2" d="M184.5,-108C184.5,-108 110.5,-108 110.5,-108 104.5,-108 98.5,-102 98.5,-96 98.5,-96 98.5,-84 98.5,-84 98.5,-78 104.5,-72 110.5,-72 110.5,-72 184.5,-72 184.5,-72 190.5,-72 196.5,-78 196.5,-84 196.5,-84 196.5,-96 196.5,-96 196.5,-102 190.5,-108 184.5,-108"/>
|
||||||
<text text-anchor="middle" x="102" y="-86.3" font-family="Times,serif" font-size="14.00">swarm-web</text>
|
<text text-anchor="middle" x="147.5" y="-86.3" font-family="Times,serif" font-size="14.00">swarm-web</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm->swarm-web -->
|
<!-- swarm->swarm-web -->
|
||||||
<g id="edge1" class="edge">
|
<g id="edge1" class="edge">
|
||||||
<title>swarm->swarm-web</title>
|
<title>swarm->swarm-web</title>
|
||||||
<path fill="none" stroke="brown" d="M102,-36.3C102,-44.02 102,-53.29 102,-61.89"/>
|
<path fill="none" stroke="brown" d="M147.5,-36.3C147.5,-44.02 147.5,-53.29 147.5,-61.89"/>
|
||||||
<polygon fill="brown" stroke="brown" points="98.5,-61.9 102,-71.9 105.5,-61.9 98.5,-61.9"/>
|
<polygon fill="brown" stroke="brown" points="144,-61.9 147.5,-71.9 151,-61.9 144,-61.9"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-doc -->
|
<!-- swarm-doc -->
|
||||||
<g id="node3" class="node">
|
<g id="node3" class="node">
|
||||||
<title>swarm-doc</title>
|
<title>swarm-doc</title>
|
||||||
<path fill="none" stroke="gray" stroke-width="2" d="M82,-180C82,-180 12,-180 12,-180 6,-180 0,-174 0,-168 0,-168 0,-156 0,-156 0,-150 6,-144 12,-144 12,-144 82,-144 82,-144 88,-144 94,-150 94,-156 94,-156 94,-168 94,-168 94,-174 88,-180 82,-180"/>
|
<path fill="none" stroke="gray" stroke-width="2" d="M127.5,-180C127.5,-180 57.5,-180 57.5,-180 51.5,-180 45.5,-174 45.5,-168 45.5,-168 45.5,-156 45.5,-156 45.5,-150 51.5,-144 57.5,-144 57.5,-144 127.5,-144 127.5,-144 133.5,-144 139.5,-150 139.5,-156 139.5,-156 139.5,-168 139.5,-168 139.5,-174 133.5,-180 127.5,-180"/>
|
||||||
<text text-anchor="middle" x="47" y="-158.3" font-family="Times,serif" font-size="14.00">swarm-doc</text>
|
<text text-anchor="middle" x="92.5" y="-158.3" font-family="Times,serif" font-size="14.00">swarm-doc</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-web->swarm-doc -->
|
<!-- swarm-web->swarm-doc -->
|
||||||
<g id="edge2" class="edge">
|
<g id="edge2" class="edge">
|
||||||
<title>swarm-web->swarm-doc</title>
|
<title>swarm-web->swarm-doc</title>
|
||||||
<path fill="none" stroke="gray" d="M88.4,-108.3C81.88,-116.61 73.93,-126.72 66.75,-135.86"/>
|
<path fill="none" stroke="gray" d="M133.9,-108.3C127.38,-116.61 119.43,-126.72 112.25,-135.86"/>
|
||||||
<polygon fill="gray" stroke="gray" points="63.87,-133.87 60.44,-143.9 69.37,-138.19 63.87,-133.87"/>
|
<polygon fill="gray" stroke="gray" points="109.37,-133.87 105.94,-143.9 114.87,-138.19 109.37,-133.87"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-tui -->
|
<!-- swarm-tui -->
|
||||||
<g id="node4" class="node">
|
<g id="node4" class="node">
|
||||||
<title>swarm-tui</title>
|
<title>swarm-tui</title>
|
||||||
<path fill="none" stroke="gray" stroke-width="2" d="M189.5,-180C189.5,-180 124.5,-180 124.5,-180 118.5,-180 112.5,-174 112.5,-168 112.5,-168 112.5,-156 112.5,-156 112.5,-150 118.5,-144 124.5,-144 124.5,-144 189.5,-144 189.5,-144 195.5,-144 201.5,-150 201.5,-156 201.5,-156 201.5,-168 201.5,-168 201.5,-174 195.5,-180 189.5,-180"/>
|
<path fill="none" stroke="gray" stroke-width="2" d="M235,-180C235,-180 170,-180 170,-180 164,-180 158,-174 158,-168 158,-168 158,-156 158,-156 158,-150 164,-144 170,-144 170,-144 235,-144 235,-144 241,-144 247,-150 247,-156 247,-156 247,-168 247,-168 247,-174 241,-180 235,-180"/>
|
||||||
<text text-anchor="middle" x="157" y="-158.3" font-family="Times,serif" font-size="14.00">swarm-tui</text>
|
<text text-anchor="middle" x="202.5" y="-158.3" font-family="Times,serif" font-size="14.00">swarm-tui</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-web->swarm-tui -->
|
<!-- swarm-web->swarm-tui -->
|
||||||
<g id="edge3" class="edge">
|
<g id="edge3" class="edge">
|
||||||
<title>swarm-web->swarm-tui</title>
|
<title>swarm-web->swarm-tui</title>
|
||||||
<path fill="none" stroke="gray" d="M115.6,-108.3C122.12,-116.61 130.07,-126.72 137.25,-135.86"/>
|
<path fill="none" stroke="gray" d="M161.1,-108.3C167.62,-116.61 175.57,-126.72 182.75,-135.86"/>
|
||||||
<polygon fill="gray" stroke="gray" points="134.63,-138.19 143.56,-143.9 140.13,-133.87 134.63,-138.19"/>
|
<polygon fill="gray" stroke="gray" points="180.13,-138.19 189.06,-143.9 185.63,-133.87 180.13,-138.19"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-engine -->
|
<!-- swarm-engine -->
|
||||||
<g id="node5" class="node">
|
<g id="node5" class="node">
|
||||||
<title>swarm-engine</title>
|
<title>swarm-engine</title>
|
||||||
<path fill="none" stroke="gray" stroke-width="2" d="M148.5,-252C148.5,-252 55.5,-252 55.5,-252 49.5,-252 43.5,-246 43.5,-240 43.5,-240 43.5,-228 43.5,-228 43.5,-222 49.5,-216 55.5,-216 55.5,-216 148.5,-216 148.5,-216 154.5,-216 160.5,-222 160.5,-228 160.5,-228 160.5,-240 160.5,-240 160.5,-246 154.5,-252 148.5,-252"/>
|
<path fill="none" stroke="gray" stroke-width="2" d="M194,-252C194,-252 101,-252 101,-252 95,-252 89,-246 89,-240 89,-240 89,-228 89,-228 89,-222 95,-216 101,-216 101,-216 194,-216 194,-216 200,-216 206,-222 206,-228 206,-228 206,-240 206,-240 206,-246 200,-252 194,-252"/>
|
||||||
<text text-anchor="middle" x="102" y="-230.3" font-family="Times,serif" font-size="14.00">swarm-engine</text>
|
<text text-anchor="middle" x="147.5" y="-230.3" font-family="Times,serif" font-size="14.00">swarm-engine</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-doc->swarm-engine -->
|
<!-- swarm-doc->swarm-engine -->
|
||||||
<g id="edge4" class="edge">
|
<g id="edge4" class="edge">
|
||||||
<title>swarm-doc->swarm-engine</title>
|
<title>swarm-doc->swarm-engine</title>
|
||||||
<path fill="none" stroke="gray" d="M60.6,-180.3C67.12,-188.61 75.07,-198.72 82.25,-207.86"/>
|
<path fill="none" stroke="gray" d="M106.1,-180.3C112.62,-188.61 120.57,-198.72 127.75,-207.86"/>
|
||||||
<polygon fill="gray" stroke="gray" points="79.63,-210.19 88.56,-215.9 85.13,-205.87 79.63,-210.19"/>
|
<polygon fill="gray" stroke="gray" points="125.13,-210.19 134.06,-215.9 130.63,-205.87 125.13,-210.19"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-tui->swarm-engine -->
|
<!-- swarm-tui->swarm-engine -->
|
||||||
<g id="edge5" class="edge">
|
<g id="edge5" class="edge">
|
||||||
<title>swarm-tui->swarm-engine</title>
|
<title>swarm-tui->swarm-engine</title>
|
||||||
<path fill="none" stroke="gray" d="M143.4,-180.3C136.88,-188.61 128.93,-198.72 121.75,-207.86"/>
|
<path fill="none" stroke="gray" d="M188.9,-180.3C182.38,-188.61 174.43,-198.72 167.25,-207.86"/>
|
||||||
<polygon fill="gray" stroke="gray" points="118.87,-205.87 115.44,-215.9 124.37,-210.19 118.87,-205.87"/>
|
<polygon fill="gray" stroke="gray" points="164.37,-205.87 160.94,-215.9 169.87,-210.19 164.37,-205.87"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-scenario -->
|
<!-- swarm-scenario -->
|
||||||
<g id="node6" class="node">
|
<g id="node6" class="node">
|
||||||
<title>swarm-scenario</title>
|
<title>swarm-scenario</title>
|
||||||
<path fill="none" stroke="gray" stroke-width="2" d="M154.5,-324C154.5,-324 49.5,-324 49.5,-324 43.5,-324 37.5,-318 37.5,-312 37.5,-312 37.5,-300 37.5,-300 37.5,-294 43.5,-288 49.5,-288 49.5,-288 154.5,-288 154.5,-288 160.5,-288 166.5,-294 166.5,-300 166.5,-300 166.5,-312 166.5,-312 166.5,-318 160.5,-324 154.5,-324"/>
|
<path fill="none" stroke="gray" stroke-width="2" d="M200,-324C200,-324 95,-324 95,-324 89,-324 83,-318 83,-312 83,-312 83,-300 83,-300 83,-294 89,-288 95,-288 95,-288 200,-288 200,-288 206,-288 212,-294 212,-300 212,-300 212,-312 212,-312 212,-318 206,-324 200,-324"/>
|
||||||
<text text-anchor="middle" x="102" y="-302.3" font-family="Times,serif" font-size="14.00">swarm-scenario</text>
|
<text text-anchor="middle" x="147.5" y="-302.3" font-family="Times,serif" font-size="14.00">swarm-scenario</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-engine->swarm-scenario -->
|
<!-- swarm-engine->swarm-scenario -->
|
||||||
<g id="edge6" class="edge">
|
<g id="edge6" class="edge">
|
||||||
<title>swarm-engine->swarm-scenario</title>
|
<title>swarm-engine->swarm-scenario</title>
|
||||||
<path fill="none" stroke="gray" d="M102,-252.3C102,-260.02 102,-269.29 102,-277.89"/>
|
<path fill="none" stroke="gray" d="M147.5,-252.3C147.5,-260.02 147.5,-269.29 147.5,-277.89"/>
|
||||||
<polygon fill="gray" stroke="gray" points="98.5,-277.9 102,-287.9 105.5,-277.9 98.5,-277.9"/>
|
<polygon fill="gray" stroke="gray" points="144,-277.9 147.5,-287.9 151,-277.9 144,-277.9"/>
|
||||||
|
</g>
|
||||||
|
<!-- swarm-topography -->
|
||||||
|
<g id="node7" class="node">
|
||||||
|
<title>swarm-topography</title>
|
||||||
|
<path fill="none" stroke="gray" stroke-width="2" d="M139,-396C139,-396 12,-396 12,-396 6,-396 0,-390 0,-384 0,-384 0,-372 0,-372 0,-366 6,-360 12,-360 12,-360 139,-360 139,-360 145,-360 151,-366 151,-372 151,-372 151,-384 151,-384 151,-390 145,-396 139,-396"/>
|
||||||
|
<text text-anchor="middle" x="75.5" y="-374.3" font-family="Times,serif" font-size="14.00">swarm-topography</text>
|
||||||
|
</g>
|
||||||
|
<!-- swarm-scenario->swarm-topography -->
|
||||||
|
<g id="edge7" class="edge">
|
||||||
|
<title>swarm-scenario->swarm-topography</title>
|
||||||
|
<path fill="none" stroke="gray" d="M129.7,-324.3C120.9,-332.86 110.12,-343.34 100.5,-352.7"/>
|
||||||
|
<polygon fill="gray" stroke="gray" points="97.82,-350.42 93.09,-359.9 102.7,-355.43 97.82,-350.42"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-lang -->
|
<!-- swarm-lang -->
|
||||||
<g id="node7" class="node">
|
<g id="node8" class="node">
|
||||||
<title>swarm-lang</title>
|
<title>swarm-lang</title>
|
||||||
<path fill="none" stroke="gray" stroke-width="2" d="M140,-396C140,-396 64,-396 64,-396 58,-396 52,-390 52,-384 52,-384 52,-372 52,-372 52,-366 58,-360 64,-360 64,-360 140,-360 140,-360 146,-360 152,-366 152,-372 152,-372 152,-384 152,-384 152,-390 146,-396 140,-396"/>
|
<path fill="none" stroke="gray" stroke-width="2" d="M257.5,-396C257.5,-396 181.5,-396 181.5,-396 175.5,-396 169.5,-390 169.5,-384 169.5,-384 169.5,-372 169.5,-372 169.5,-366 175.5,-360 181.5,-360 181.5,-360 257.5,-360 257.5,-360 263.5,-360 269.5,-366 269.5,-372 269.5,-372 269.5,-384 269.5,-384 269.5,-390 263.5,-396 257.5,-396"/>
|
||||||
<text text-anchor="middle" x="102" y="-374.3" font-family="Times,serif" font-size="14.00">swarm-lang</text>
|
<text text-anchor="middle" x="219.5" y="-374.3" font-family="Times,serif" font-size="14.00">swarm-lang</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-scenario->swarm-lang -->
|
<!-- swarm-scenario->swarm-lang -->
|
||||||
<g id="edge7" class="edge">
|
<g id="edge8" class="edge">
|
||||||
<title>swarm-scenario->swarm-lang</title>
|
<title>swarm-scenario->swarm-lang</title>
|
||||||
<path fill="none" stroke="gray" d="M102,-324.3C102,-332.02 102,-341.29 102,-349.89"/>
|
<path fill="none" stroke="gray" d="M165.3,-324.3C174.1,-332.86 184.88,-343.34 194.5,-352.7"/>
|
||||||
<polygon fill="gray" stroke="gray" points="98.5,-349.9 102,-359.9 105.5,-349.9 98.5,-349.9"/>
|
<polygon fill="gray" stroke="gray" points="192.3,-355.43 201.91,-359.9 197.18,-350.42 192.3,-355.43"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-util -->
|
<!-- swarm-util -->
|
||||||
<g id="node8" class="node">
|
<g id="node9" class="node">
|
||||||
<title>swarm-util</title>
|
<title>swarm-util</title>
|
||||||
<path fill="none" stroke="gray" stroke-width="2" d="M136.5,-468C136.5,-468 67.5,-468 67.5,-468 61.5,-468 55.5,-462 55.5,-456 55.5,-456 55.5,-444 55.5,-444 55.5,-438 61.5,-432 67.5,-432 67.5,-432 136.5,-432 136.5,-432 142.5,-432 148.5,-438 148.5,-444 148.5,-444 148.5,-456 148.5,-456 148.5,-462 142.5,-468 136.5,-468"/>
|
<path fill="none" stroke="gray" stroke-width="2" d="M182,-468C182,-468 113,-468 113,-468 107,-468 101,-462 101,-456 101,-456 101,-444 101,-444 101,-438 107,-432 113,-432 113,-432 182,-432 182,-432 188,-432 194,-438 194,-444 194,-444 194,-456 194,-456 194,-462 188,-468 182,-468"/>
|
||||||
<text text-anchor="middle" x="102" y="-446.3" font-family="Times,serif" font-size="14.00">swarm-util</text>
|
<text text-anchor="middle" x="147.5" y="-446.3" font-family="Times,serif" font-size="14.00">swarm-util</text>
|
||||||
|
</g>
|
||||||
|
<!-- swarm-topography->swarm-util -->
|
||||||
|
<g id="edge9" class="edge">
|
||||||
|
<title>swarm-topography->swarm-util</title>
|
||||||
|
<path fill="none" stroke="gray" d="M93.3,-396.3C102.1,-404.86 112.88,-415.34 122.5,-424.7"/>
|
||||||
|
<polygon fill="gray" stroke="gray" points="120.3,-427.43 129.91,-431.9 125.18,-422.42 120.3,-427.43"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- swarm-lang->swarm-util -->
|
<!-- swarm-lang->swarm-util -->
|
||||||
<g id="edge8" class="edge">
|
<g id="edge10" class="edge">
|
||||||
<title>swarm-lang->swarm-util</title>
|
<title>swarm-lang->swarm-util</title>
|
||||||
<path fill="none" stroke="gray" d="M102,-396.3C102,-404.02 102,-413.29 102,-421.89"/>
|
<path fill="none" stroke="gray" d="M201.7,-396.3C192.9,-404.86 182.12,-415.34 172.5,-424.7"/>
|
||||||
<polygon fill="gray" stroke="gray" points="98.5,-421.9 102,-431.9 105.5,-421.9 98.5,-421.9"/>
|
<polygon fill="gray" stroke="gray" points="169.82,-422.42 165.09,-431.9 174.7,-427.43 169.82,-422.42"/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 8.1 KiB |
@ -1,7 +1,5 @@
|
|||||||
#!/bin/bash -xe
|
#!/bin/bash -xe
|
||||||
|
|
||||||
|
cd $(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
cabal bench --benchmark-options "--color always $@"
|
||||||
cd $SCRIPT_DIR/..
|
|
||||||
|
|
||||||
STACK_WORK=.stack-work-bench stack bench swarm:benchmark --benchmark-arguments "--color always $@"
|
|
||||||
|
@ -19,7 +19,7 @@ module Swarm.Doc.Keyword (
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Swarm.Doc.Util
|
import Swarm.Doc.Util
|
||||||
import Swarm.Language.Syntax qualified as Syntax
|
import Swarm.Language.Syntax.Direction
|
||||||
import Swarm.Util (quote)
|
import Swarm.Util (quote)
|
||||||
|
|
||||||
-- | An enumeration of the editors supported by Swarm (currently,
|
-- | An enumeration of the editors supported by Swarm (currently,
|
||||||
@ -42,7 +42,7 @@ keywordsCommands e = editorList e $ map constSyntax commands
|
|||||||
|
|
||||||
-- | Get formatted list of directions.
|
-- | Get formatted list of directions.
|
||||||
keywordsDirections :: EditorType -> Text
|
keywordsDirections :: EditorType -> Text
|
||||||
keywordsDirections e = editorList e $ map Syntax.directionSyntax Syntax.allDirs
|
keywordsDirections e = editorList e $ map directionSyntax allDirs
|
||||||
|
|
||||||
-- | A list of the names of all the operators in the language.
|
-- | A list of the names of all the operators in the language.
|
||||||
operatorNames :: Text
|
operatorNames :: Text
|
||||||
|
@ -26,11 +26,12 @@ import Data.Set qualified as S
|
|||||||
import Linear (V2 (..))
|
import Linear (V2 (..))
|
||||||
import Swarm.Game.Entity
|
import Swarm.Game.Entity
|
||||||
import Swarm.Game.Location
|
import Swarm.Game.Location
|
||||||
import Swarm.Game.Scenario.Topography.Structure qualified as Structure
|
import Swarm.Game.Scenario (Cell)
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition
|
import Swarm.Game.Scenario.Topography.Structure.Recognition
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Log
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Log
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type qualified as Structure
|
||||||
import Swarm.Game.State
|
import Swarm.Game.State
|
||||||
import Swarm.Game.State.Substate
|
import Swarm.Game.State.Substate
|
||||||
import Swarm.Game.Universe
|
import Swarm.Game.Universe
|
||||||
@ -124,7 +125,7 @@ getWorldRow participatingEnts cLoc (InspectionOffsets (Min offsetLeft) (Max offs
|
|||||||
registerRowMatches ::
|
registerRowMatches ::
|
||||||
(Has (State GameState) sig m) =>
|
(Has (State GameState) sig m) =>
|
||||||
Cosmic Location ->
|
Cosmic Location ->
|
||||||
AutomatonInfo AtomicKeySymbol StructureSearcher ->
|
AutomatonInfo EntityName (AtomicKeySymbol Entity) (StructureSearcher Cell EntityName Entity) ->
|
||||||
m ()
|
m ()
|
||||||
registerRowMatches cLoc (AutomatonInfo participatingEnts horizontalOffsets sm) = do
|
registerRowMatches cLoc (AutomatonInfo participatingEnts horizontalOffsets sm) = do
|
||||||
entitiesRow <- getWorldRow participatingEnts cLoc horizontalOffsets 0
|
entitiesRow <- getWorldRow participatingEnts cLoc horizontalOffsets 0
|
||||||
@ -150,8 +151,8 @@ checkVerticalMatch ::
|
|||||||
Cosmic Location ->
|
Cosmic Location ->
|
||||||
-- | Horizontal search offsets
|
-- | Horizontal search offsets
|
||||||
InspectionOffsets ->
|
InspectionOffsets ->
|
||||||
Position StructureSearcher ->
|
Position (StructureSearcher Cell EntityName Entity) ->
|
||||||
m [FoundStructure]
|
m [FoundStructure Cell Entity]
|
||||||
checkVerticalMatch cLoc (InspectionOffsets (Min searchOffsetLeft) _) foundRow =
|
checkVerticalMatch cLoc (InspectionOffsets (Min searchOffsetLeft) _) foundRow =
|
||||||
getMatches2D cLoc horizontalFoundOffsets $ automaton2D $ pVal foundRow
|
getMatches2D cLoc horizontalFoundOffsets $ automaton2D $ pVal foundRow
|
||||||
where
|
where
|
||||||
@ -163,9 +164,9 @@ getFoundStructures ::
|
|||||||
Hashable keySymb =>
|
Hashable keySymb =>
|
||||||
(Int32, Int32) ->
|
(Int32, Int32) ->
|
||||||
Cosmic Location ->
|
Cosmic Location ->
|
||||||
StateMachine keySymb StructureWithGrid ->
|
StateMachine keySymb (StructureWithGrid Cell Entity) ->
|
||||||
[keySymb] ->
|
[keySymb] ->
|
||||||
[FoundStructure]
|
[FoundStructure Cell Entity]
|
||||||
getFoundStructures (offsetTop, offsetLeft) cLoc sm entityRows =
|
getFoundStructures (offsetTop, offsetLeft) cLoc sm entityRows =
|
||||||
map mkFound candidates
|
map mkFound candidates
|
||||||
where
|
where
|
||||||
@ -181,8 +182,8 @@ getMatches2D ::
|
|||||||
Cosmic Location ->
|
Cosmic Location ->
|
||||||
-- | Horizontal found offsets (inclusive indices)
|
-- | Horizontal found offsets (inclusive indices)
|
||||||
InspectionOffsets ->
|
InspectionOffsets ->
|
||||||
AutomatonInfo SymbolSequence StructureWithGrid ->
|
AutomatonInfo EntityName (SymbolSequence Entity) (StructureWithGrid Cell Entity) ->
|
||||||
m [FoundStructure]
|
m [FoundStructure Cell Entity]
|
||||||
getMatches2D
|
getMatches2D
|
||||||
cLoc
|
cLoc
|
||||||
horizontalFoundOffsets@(InspectionOffsets (Min offsetLeft) _)
|
horizontalFoundOffsets@(InspectionOffsets (Min offsetLeft) _)
|
||||||
@ -199,7 +200,7 @@ getMatches2D
|
|||||||
-- The largest structure (by area) shall win.
|
-- The largest structure (by area) shall win.
|
||||||
registerStructureMatches ::
|
registerStructureMatches ::
|
||||||
(Has (State GameState) sig m) =>
|
(Has (State GameState) sig m) =>
|
||||||
[FoundStructure] ->
|
[FoundStructure Cell Entity] ->
|
||||||
m ()
|
m ()
|
||||||
registerStructureMatches unrankedCandidates = do
|
registerStructureMatches unrankedCandidates = do
|
||||||
discovery . structureRecognition . recognitionLog %= (newMsg :)
|
discovery . structureRecognition . recognitionLog %= (newMsg :)
|
||||||
|
@ -117,11 +117,11 @@ import Swarm.Game.Robot.Concrete
|
|||||||
import Swarm.Game.Scenario
|
import Swarm.Game.Scenario
|
||||||
import Swarm.Game.Scenario.Objective
|
import Swarm.Game.Scenario.Objective
|
||||||
import Swarm.Game.Scenario.Status
|
import Swarm.Game.Scenario.Status
|
||||||
import Swarm.Game.Scenario.Topography.Structure qualified as Structure
|
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition
|
import Swarm.Game.Scenario.Topography.Structure.Recognition
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Log
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Log
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Precompute
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Precompute
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type qualified as Structure
|
||||||
import Swarm.Game.State.Landscape
|
import Swarm.Game.State.Landscape
|
||||||
import Swarm.Game.State.Robot
|
import Swarm.Game.State.Robot
|
||||||
import Swarm.Game.State.Substate
|
import Swarm.Game.State.Substate
|
||||||
@ -525,7 +525,7 @@ zoomWorld swName n = do
|
|||||||
-- cell is encountered.
|
-- cell is encountered.
|
||||||
ensureStructureIntact ::
|
ensureStructureIntact ::
|
||||||
(Has (State GameState) sig m) =>
|
(Has (State GameState) sig m) =>
|
||||||
FoundStructure ->
|
FoundStructure Cell Entity ->
|
||||||
m Bool
|
m Bool
|
||||||
ensureStructureIntact (FoundStructure (StructureWithGrid _ _ grid) upperLeft) =
|
ensureStructureIntact (FoundStructure (StructureWithGrid _ _ grid) upperLeft) =
|
||||||
allM outer $ zip [0 ..] grid
|
allM outer $ zip [0 ..] grid
|
||||||
@ -541,7 +541,7 @@ ensureStructureIntact (FoundStructure (StructureWithGrid _ _ grid) upperLeft) =
|
|||||||
mkRecognizer ::
|
mkRecognizer ::
|
||||||
(Has (State GameState) sig m) =>
|
(Has (State GameState) sig m) =>
|
||||||
StaticStructureInfo ->
|
StaticStructureInfo ->
|
||||||
m StructureRecognizer
|
m (StructureRecognizer Cell EntityName Entity)
|
||||||
mkRecognizer structInfo@(StaticStructureInfo structDefs _) = do
|
mkRecognizer structInfo@(StaticStructureInfo structDefs _) = do
|
||||||
foundIntact <- mapM (sequenceA . (id &&& ensureStructureIntact)) allPlaced
|
foundIntact <- mapM (sequenceA . (id &&& ensureStructureIntact)) allPlaced
|
||||||
let fs = populateStaticFoundStructures . map fst . filter snd $ foundIntact
|
let fs = populateStaticFoundStructures . map fst . filter snd $ foundIntact
|
||||||
|
@ -100,7 +100,7 @@ import Swarm.Game.Recipe (
|
|||||||
outRecipeMap,
|
outRecipeMap,
|
||||||
)
|
)
|
||||||
import Swarm.Game.Robot
|
import Swarm.Game.Robot
|
||||||
import Swarm.Game.Scenario (GameStateInputs (..))
|
import Swarm.Game.Scenario (Cell, GameStateInputs (..))
|
||||||
import Swarm.Game.Scenario.Objective
|
import Swarm.Game.Scenario.Objective
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition
|
import Swarm.Game.Scenario.Topography.Structure.Recognition
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry (emptyFoundStructures)
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry (emptyFoundStructures)
|
||||||
@ -327,7 +327,7 @@ data Discovery = Discovery
|
|||||||
, _availableCommands :: Notifications Const
|
, _availableCommands :: Notifications Const
|
||||||
, _knownEntities :: S.Set EntityName
|
, _knownEntities :: S.Set EntityName
|
||||||
, _gameAchievements :: Map GameplayAchievement Attainment
|
, _gameAchievements :: Map GameplayAchievement Attainment
|
||||||
, _structureRecognition :: StructureRecognizer
|
, _structureRecognition :: StructureRecognizer Cell EntityName Entity
|
||||||
, _tagMembers :: Map Text (NonEmpty EntityName)
|
, _tagMembers :: Map Text (NonEmpty EntityName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ knownEntities :: Lens' Discovery (S.Set EntityName)
|
|||||||
gameAchievements :: Lens' Discovery (Map GameplayAchievement Attainment)
|
gameAchievements :: Lens' Discovery (Map GameplayAchievement Attainment)
|
||||||
|
|
||||||
-- | Recognizer for robot-constructed structures
|
-- | Recognizer for robot-constructed structures
|
||||||
structureRecognition :: Lens' Discovery StructureRecognizer
|
structureRecognition :: Lens' Discovery (StructureRecognizer Cell EntityName Entity)
|
||||||
|
|
||||||
-- | Map from tags to entities that possess that tag
|
-- | Map from tags to entities that possess that tag
|
||||||
tagMembers :: Lens' Discovery (Map Text (NonEmpty EntityName))
|
tagMembers :: Lens' Discovery (Map Text (NonEmpty EntityName))
|
||||||
|
@ -44,6 +44,7 @@ import Swarm.Language.Context (empty)
|
|||||||
import Swarm.Language.Pipeline (ProcessedTerm)
|
import Swarm.Language.Pipeline (ProcessedTerm)
|
||||||
import Swarm.Language.Pipeline.QQ (tmQ)
|
import Swarm.Language.Pipeline.QQ (tmQ)
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction (Direction)
|
||||||
import Swarm.Language.Text.Markdown qualified as Markdown
|
import Swarm.Language.Text.Markdown qualified as Markdown
|
||||||
import Swarm.Util hiding (both)
|
import Swarm.Util hiding (both)
|
||||||
import System.Clock (TimeSpec)
|
import System.Clock (TimeSpec)
|
||||||
|
@ -94,6 +94,7 @@ import Swarm.Language.Pipeline
|
|||||||
import Swarm.Language.Pretty (prettyText)
|
import Swarm.Language.Pretty (prettyText)
|
||||||
import Swarm.Language.Requirement qualified as R
|
import Swarm.Language.Requirement qualified as R
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction
|
||||||
import Swarm.Language.Text.Markdown qualified as Markdown
|
import Swarm.Language.Text.Markdown qualified as Markdown
|
||||||
import Swarm.Language.Value
|
import Swarm.Language.Value
|
||||||
import Swarm.Log
|
import Swarm.Log
|
||||||
|
@ -48,6 +48,7 @@ import Swarm.Game.Step.Util
|
|||||||
import Swarm.Game.Step.Util.Inspect
|
import Swarm.Game.Step.Util.Inspect
|
||||||
import Swarm.Game.Universe
|
import Swarm.Game.Universe
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction
|
||||||
import Swarm.Util (hoistMaybe)
|
import Swarm.Util (hoistMaybe)
|
||||||
|
|
||||||
-- | Swarm command arguments are converted to idiomatic Haskell
|
-- | Swarm command arguments are converted to idiomatic Haskell
|
||||||
|
@ -42,6 +42,7 @@ import Swarm.Game.World.Modify qualified as WM
|
|||||||
import Swarm.Language.Capability
|
import Swarm.Language.Capability
|
||||||
import Swarm.Language.Requirement qualified as R
|
import Swarm.Language.Requirement qualified as R
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction (Direction)
|
||||||
import Swarm.Util hiding (both)
|
import Swarm.Util hiding (both)
|
||||||
import System.Random (UniformRange, uniformR)
|
import System.Random (UniformRange, uniformR)
|
||||||
import Prelude hiding (Applicative (..), lookup)
|
import Prelude hiding (Applicative (..), lookup)
|
||||||
|
@ -56,6 +56,7 @@ import Data.Text (Text)
|
|||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Swarm.Language.Parser.Core
|
import Swarm.Language.Parser.Core
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction
|
||||||
import Swarm.Language.Types (baseTyName)
|
import Swarm.Language.Types (baseTyName)
|
||||||
import Swarm.Util (failT, listEnums, squote)
|
import Swarm.Util (failT, listEnums, squote)
|
||||||
import Text.Megaparsec
|
import Text.Megaparsec
|
||||||
|
@ -21,6 +21,7 @@ import Swarm.Language.Parser.Lex
|
|||||||
import Swarm.Language.Parser.Record (parseRecord)
|
import Swarm.Language.Parser.Record (parseRecord)
|
||||||
import Swarm.Language.Parser.Type
|
import Swarm.Language.Parser.Type
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction
|
||||||
import Swarm.Language.Types
|
import Swarm.Language.Types
|
||||||
import Swarm.Util (failT, findDup)
|
import Swarm.Util (failT, findDup)
|
||||||
import Text.Megaparsec hiding (runParser)
|
import Text.Megaparsec hiding (runParser)
|
||||||
|
@ -32,6 +32,7 @@ import Swarm.Language.Context
|
|||||||
import Swarm.Language.Kindcheck (KindError (..))
|
import Swarm.Language.Kindcheck (KindError (..))
|
||||||
import Swarm.Language.Parser.Util (getLocRange)
|
import Swarm.Language.Parser.Util (getLocRange)
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction
|
||||||
import Swarm.Language.Typecheck
|
import Swarm.Language.Typecheck
|
||||||
import Swarm.Language.Types
|
import Swarm.Language.Types
|
||||||
import Swarm.Util (number, showEnum, showLowT, unsnocNE)
|
import Swarm.Util (number, showEnum, showLowT, unsnocNE)
|
||||||
|
@ -37,6 +37,7 @@ import Swarm.Language.Capability (Capability (..), constCaps)
|
|||||||
import Swarm.Language.Context (Ctx)
|
import Swarm.Language.Context (Ctx)
|
||||||
import Swarm.Language.Context qualified as Ctx
|
import Swarm.Language.Context qualified as Ctx
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction
|
||||||
|
|
||||||
-- | A /requirement/ is something a robot must have when it is
|
-- | A /requirement/ is something a robot must have when it is
|
||||||
-- built. There are three types:
|
-- built. There are three types:
|
||||||
|
@ -5,15 +5,6 @@
|
|||||||
--
|
--
|
||||||
-- Abstract syntax for terms of the Swarm programming language.
|
-- Abstract syntax for terms of the Swarm programming language.
|
||||||
module Swarm.Language.Syntax (
|
module Swarm.Language.Syntax (
|
||||||
-- * Directions
|
|
||||||
Direction (..),
|
|
||||||
AbsoluteDir (..),
|
|
||||||
RelativeDir (..),
|
|
||||||
PlanarRelativeDir (..),
|
|
||||||
directionSyntax,
|
|
||||||
isCardinal,
|
|
||||||
allDirs,
|
|
||||||
|
|
||||||
-- * Constants
|
-- * Constants
|
||||||
Const (..),
|
Const (..),
|
||||||
allConst,
|
allConst,
|
||||||
@ -104,7 +95,6 @@ module Swarm.Language.Syntax (
|
|||||||
import Swarm.Language.Syntax.AST
|
import Swarm.Language.Syntax.AST
|
||||||
import Swarm.Language.Syntax.Comments
|
import Swarm.Language.Syntax.Comments
|
||||||
import Swarm.Language.Syntax.Constants
|
import Swarm.Language.Syntax.Constants
|
||||||
import Swarm.Language.Syntax.Direction
|
|
||||||
import Swarm.Language.Syntax.Loc
|
import Swarm.Language.Syntax.Loc
|
||||||
import Swarm.Language.Syntax.Pattern
|
import Swarm.Language.Syntax.Pattern
|
||||||
import Swarm.Language.Syntax.Util
|
import Swarm.Language.Syntax.Util
|
||||||
|
@ -31,6 +31,7 @@ import Swarm.Language.Context
|
|||||||
import Swarm.Language.Key (KeyCombo, prettyKeyCombo)
|
import Swarm.Language.Key (KeyCombo, prettyKeyCombo)
|
||||||
import Swarm.Language.Pretty (prettyText)
|
import Swarm.Language.Pretty (prettyText)
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax
|
||||||
|
import Swarm.Language.Syntax.Direction
|
||||||
|
|
||||||
-- | A /value/ is a term that cannot (or does not) take any more
|
-- | A /value/ is a term that cannot (or does not) take any more
|
||||||
-- evaluation steps on its own.
|
-- evaluation steps on its own.
|
||||||
|
@ -48,7 +48,7 @@ import Data.Text qualified as T
|
|||||||
import Data.Yaml
|
import Data.Yaml
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import Graphics.Text.Width
|
import Graphics.Text.Width
|
||||||
import Swarm.Language.Syntax (AbsoluteDir (..), Direction (..))
|
import Swarm.Language.Syntax.Direction (AbsoluteDir (..), Direction (..))
|
||||||
import Swarm.Util (maxOn, quote)
|
import Swarm.Util (maxOn, quote)
|
||||||
import Swarm.Util.Lens (makeLensesNoSigs)
|
import Swarm.Util.Lens (makeLensesNoSigs)
|
||||||
import Swarm.Util.Yaml (FromJSONE (..), With (runE), getE, liftE, withObjectE)
|
import Swarm.Util.Yaml (FromJSONE (..), With (runE), getE, liftE, withObjectE)
|
||||||
|
@ -102,6 +102,7 @@ import Swarm.Game.Scenario.Topography.Structure.Assembly qualified as Assembly
|
|||||||
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Symmetry
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Symmetry
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type (SymmetryAnnotatedGrid (..))
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type (SymmetryAnnotatedGrid (..))
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type qualified as Structure
|
||||||
import Swarm.Game.Scenario.Topography.WorldDescription
|
import Swarm.Game.Scenario.Topography.WorldDescription
|
||||||
import Swarm.Game.Terrain
|
import Swarm.Game.Terrain
|
||||||
import Swarm.Game.Universe
|
import Swarm.Game.Universe
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
-- SPDX-License-Identifier: BSD-3-Clause
|
-- SPDX-License-Identifier: BSD-3-Clause
|
||||||
@ -11,45 +12,22 @@ module Swarm.Game.Scenario.Topography.Structure where
|
|||||||
import Data.Aeson.Key qualified as Key
|
import Data.Aeson.Key qualified as Key
|
||||||
import Data.Aeson.KeyMap qualified as KeyMap
|
import Data.Aeson.KeyMap qualified as KeyMap
|
||||||
import Data.Maybe (catMaybes)
|
import Data.Maybe (catMaybes)
|
||||||
import Data.Set (Set)
|
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.Yaml as Y
|
import Data.Yaml as Y
|
||||||
import Swarm.Game.Land
|
import Swarm.Game.Land
|
||||||
import Swarm.Game.Location
|
import Swarm.Game.Location
|
||||||
import Swarm.Game.Scenario.RobotLookup
|
import Swarm.Game.Scenario.RobotLookup (RobotMap)
|
||||||
import Swarm.Game.Scenario.Topography.Area
|
import Swarm.Game.Scenario.Topography.Area
|
||||||
import Swarm.Game.Scenario.Topography.Cell
|
import Swarm.Game.Scenario.Topography.Cell
|
||||||
import Swarm.Game.Scenario.Topography.Navigation.Waypoint
|
import Swarm.Game.Scenario.Topography.Navigation.Waypoint
|
||||||
import Swarm.Game.Scenario.Topography.Placement
|
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type
|
||||||
import Swarm.Game.Scenario.Topography.WorldPalette
|
import Swarm.Game.Scenario.Topography.WorldPalette
|
||||||
import Swarm.Language.Syntax.Direction (AbsoluteDir)
|
|
||||||
import Swarm.Util (failT, showT)
|
import Swarm.Util (failT, showT)
|
||||||
import Swarm.Util.Yaml
|
import Swarm.Util.Yaml
|
||||||
import Witch (into)
|
import Witch (into)
|
||||||
|
|
||||||
data NamedArea a = NamedArea
|
|
||||||
{ name :: StructureName
|
|
||||||
, recognize :: Set AbsoluteDir
|
|
||||||
-- ^ whether this structure should be registered for automatic recognition
|
|
||||||
-- and which orientations shall be recognized.
|
|
||||||
-- The supplied direction indicates which cardinal direction the
|
|
||||||
-- original map's "North" has been re-oriented to.
|
|
||||||
-- E.g., 'DWest' represents a rotation of 90 degrees counter-clockwise.
|
|
||||||
, description :: Maybe Text
|
|
||||||
-- ^ will be UI-facing only if this is a recognizable structure
|
|
||||||
, structure :: a
|
|
||||||
}
|
|
||||||
deriving (Eq, Show, Functor)
|
|
||||||
|
|
||||||
isRecognizable :: NamedArea a -> Bool
|
|
||||||
isRecognizable = not . null . recognize
|
|
||||||
|
|
||||||
type NamedGrid c = NamedArea (Grid c)
|
|
||||||
|
|
||||||
type NamedStructure c = NamedArea (PStructure c)
|
|
||||||
|
|
||||||
type InheritedStructureDefs = [NamedStructure (Maybe Cell)]
|
type InheritedStructureDefs = [NamedStructure (Maybe Cell)]
|
||||||
|
|
||||||
instance FromJSONE (TerrainEntityMaps, RobotMap) (NamedArea (PStructure (Maybe Cell))) where
|
instance FromJSONE (TerrainEntityMaps, RobotMap) (NamedArea (PStructure (Maybe Cell))) where
|
||||||
@ -61,33 +39,6 @@ instance FromJSONE (TerrainEntityMaps, RobotMap) (NamedArea (PStructure (Maybe C
|
|||||||
<*> v
|
<*> v
|
||||||
..: "structure"
|
..: "structure"
|
||||||
|
|
||||||
data PStructure c = Structure
|
|
||||||
{ area :: PositionedGrid c
|
|
||||||
, structures :: [NamedStructure c]
|
|
||||||
-- ^ structure definitions from parents shall be accessible by children
|
|
||||||
, placements :: [Placement]
|
|
||||||
-- ^ earlier placements will be overlaid on top of later placements in the YAML file
|
|
||||||
, waypoints :: [Waypoint]
|
|
||||||
}
|
|
||||||
deriving (Eq, Show)
|
|
||||||
|
|
||||||
data Placed c = Placed Placement (NamedStructure c)
|
|
||||||
deriving (Show)
|
|
||||||
|
|
||||||
-- | For use in registering recognizable pre-placed structures
|
|
||||||
data LocatedStructure = LocatedStructure
|
|
||||||
{ placedName :: StructureName
|
|
||||||
, upDirection :: AbsoluteDir
|
|
||||||
, cornerLoc :: Location
|
|
||||||
}
|
|
||||||
deriving (Show)
|
|
||||||
|
|
||||||
instance HasLocation LocatedStructure where
|
|
||||||
modifyLoc f (LocatedStructure x y originalLoc) =
|
|
||||||
LocatedStructure x y $ f originalLoc
|
|
||||||
|
|
||||||
data MergedStructure c = MergedStructure (PositionedGrid c) [LocatedStructure] [Originated Waypoint]
|
|
||||||
|
|
||||||
instance FromJSONE (TerrainEntityMaps, RobotMap) (PStructure (Maybe Cell)) where
|
instance FromJSONE (TerrainEntityMaps, RobotMap) (PStructure (Maybe Cell)) where
|
||||||
parseJSONE = withObjectE "structure definition" $ \v -> do
|
parseJSONE = withObjectE "structure definition" $ \v -> do
|
||||||
pal <- v ..:? "palette" ..!= WorldPalette mempty
|
pal <- v ..:? "palette" ..!= WorldPalette mempty
|
||||||
|
@ -43,6 +43,7 @@ module Swarm.Game.Scenario.Topography.Structure.Recognition.Precompute (
|
|||||||
|
|
||||||
import Control.Arrow ((&&&))
|
import Control.Arrow ((&&&))
|
||||||
import Control.Lens (view)
|
import Control.Lens (view)
|
||||||
|
import Data.Hashable (Hashable)
|
||||||
import Data.Int (Int32)
|
import Data.Int (Int32)
|
||||||
import Data.List.NonEmpty qualified as NE
|
import Data.List.NonEmpty qualified as NE
|
||||||
import Data.Map qualified as M
|
import Data.Map qualified as M
|
||||||
@ -51,28 +52,28 @@ import Data.Semigroup (sconcat)
|
|||||||
import Data.Set qualified as S
|
import Data.Set qualified as S
|
||||||
import Data.Set qualified as Set
|
import Data.Set qualified as Set
|
||||||
import Data.Tuple (swap)
|
import Data.Tuple (swap)
|
||||||
import Swarm.Game.Entity (Entity, entityName)
|
import Swarm.Game.Entity (Entity, EntityName, entityName)
|
||||||
import Swarm.Game.Scenario (StaticStructureInfo (..))
|
import Swarm.Game.Scenario (StaticStructureInfo (..))
|
||||||
import Swarm.Game.Scenario.Topography.Area (Grid (Grid))
|
import Swarm.Game.Scenario.Topography.Area (Grid (Grid))
|
||||||
import Swarm.Game.Scenario.Topography.Cell
|
import Swarm.Game.Scenario.Topography.Cell (PCell, cellEntity)
|
||||||
import Swarm.Game.Scenario.Topography.Placement (Orientation (..), applyOrientationTransform)
|
import Swarm.Game.Scenario.Topography.Placement (Orientation (..), applyOrientationTransform)
|
||||||
import Swarm.Game.Scenario.Topography.Structure
|
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type
|
||||||
import Swarm.Game.Universe (Cosmic (..))
|
import Swarm.Game.Universe (Cosmic (..))
|
||||||
import Swarm.Language.Syntax.Direction (AbsoluteDir)
|
import Swarm.Language.Syntax.Direction (AbsoluteDir)
|
||||||
import Swarm.Util (binTuples, histogram)
|
import Swarm.Util (binTuples, histogram)
|
||||||
import Swarm.Util.Erasable (erasableToMaybe)
|
import Swarm.Util.Erasable (erasableToMaybe)
|
||||||
import Text.AhoCorasick
|
import Text.AhoCorasick
|
||||||
|
|
||||||
getEntityGrid :: Grid (Maybe Cell) -> [SymbolSequence]
|
getEntityGrid :: Grid (Maybe (PCell Entity)) -> [SymbolSequence Entity]
|
||||||
getEntityGrid (Grid cells) = map (map ((erasableToMaybe . cellEntity) =<<)) cells
|
getEntityGrid (Grid cells) = map (map ((erasableToMaybe . cellEntity) =<<)) cells
|
||||||
|
|
||||||
allStructureRows :: [StructureWithGrid] -> [StructureRow]
|
allStructureRows :: [StructureWithGrid b a] -> [StructureRow b a]
|
||||||
allStructureRows =
|
allStructureRows =
|
||||||
concatMap getRows
|
concatMap getRows
|
||||||
where
|
where
|
||||||
getRows :: StructureWithGrid -> [StructureRow]
|
getRows :: StructureWithGrid b a -> [StructureRow b a]
|
||||||
getRows g = zipWith (StructureRow g) [0 ..] $ entityGrid g
|
getRows g = zipWith (StructureRow g) [0 ..] $ entityGrid g
|
||||||
|
|
||||||
mkOffsets :: Foldable f => Int32 -> f a -> InspectionOffsets
|
mkOffsets :: Foldable f => Int32 -> f a -> InspectionOffsets
|
||||||
@ -85,9 +86,11 @@ mkOffsets pos xs =
|
|||||||
-- yield a searcher that can determine whether adjacent
|
-- yield a searcher that can determine whether adjacent
|
||||||
-- rows constitute a complete structure.
|
-- rows constitute a complete structure.
|
||||||
mkRowLookup ::
|
mkRowLookup ::
|
||||||
NE.NonEmpty StructureRow ->
|
(Hashable a, Ord en) =>
|
||||||
AutomatonInfo SymbolSequence StructureWithGrid
|
(a -> en) ->
|
||||||
mkRowLookup neList =
|
NE.NonEmpty (StructureRow b a) ->
|
||||||
|
AutomatonInfo en (SymbolSequence a) (StructureWithGrid b a)
|
||||||
|
mkRowLookup nameFunc neList =
|
||||||
AutomatonInfo participatingEnts bounds sm
|
AutomatonInfo participatingEnts bounds sm
|
||||||
where
|
where
|
||||||
mkSmTuple = entityGrid &&& id
|
mkSmTuple = entityGrid &&& id
|
||||||
@ -96,10 +99,10 @@ mkRowLookup neList =
|
|||||||
-- All of the unique entities across all of the full candidate structures
|
-- All of the unique entities across all of the full candidate structures
|
||||||
participatingEnts =
|
participatingEnts =
|
||||||
S.fromList $
|
S.fromList $
|
||||||
map (view entityName) $
|
map nameFunc $
|
||||||
concatMap (concatMap catMaybes . fst) tuples
|
concatMap (concatMap catMaybes . fst) tuples
|
||||||
|
|
||||||
deriveRowOffsets :: StructureRow -> InspectionOffsets
|
deriveRowOffsets :: StructureRow b a -> InspectionOffsets
|
||||||
deriveRowOffsets (StructureRow (StructureWithGrid _ _ g) rwIdx _) =
|
deriveRowOffsets (StructureRow (StructureWithGrid _ _ g) rwIdx _) =
|
||||||
mkOffsets rwIdx g
|
mkOffsets rwIdx g
|
||||||
|
|
||||||
@ -113,27 +116,27 @@ mkRowLookup neList =
|
|||||||
-- underlying world row against all rows within all structures
|
-- underlying world row against all rows within all structures
|
||||||
-- (so long as they contain the keyed entity).
|
-- (so long as they contain the keyed entity).
|
||||||
mkEntityLookup ::
|
mkEntityLookup ::
|
||||||
[StructureWithGrid] ->
|
(Hashable a, Ord a, Ord en) =>
|
||||||
M.Map Entity (AutomatonInfo AtomicKeySymbol StructureSearcher)
|
(a -> en) ->
|
||||||
mkEntityLookup grids =
|
[StructureWithGrid b a] ->
|
||||||
|
M.Map a (AutomatonInfo en (AtomicKeySymbol a) (StructureSearcher b en a))
|
||||||
|
mkEntityLookup nameFunc grids =
|
||||||
M.map mkValues rowsByEntityParticipation
|
M.map mkValues rowsByEntityParticipation
|
||||||
where
|
where
|
||||||
rowsAcrossAllStructures = allStructureRows grids
|
rowsAcrossAllStructures = allStructureRows grids
|
||||||
|
|
||||||
-- The input here are all rows across all structures
|
-- The input here are all rows across all structures
|
||||||
-- that share the same entity sequence.
|
-- that share the same entity sequence.
|
||||||
mkSmValue :: SymbolSequence -> NE.NonEmpty SingleRowEntityOccurrences -> StructureSearcher
|
|
||||||
mkSmValue ksms singleRows =
|
mkSmValue ksms singleRows =
|
||||||
StructureSearcher sm2D ksms singleRows
|
StructureSearcher sm2D ksms singleRows
|
||||||
where
|
where
|
||||||
structureRowsNE = NE.map myRow singleRows
|
structureRowsNE = NE.map myRow singleRows
|
||||||
sm2D = mkRowLookup structureRowsNE
|
sm2D = mkRowLookup nameFunc structureRowsNE
|
||||||
|
|
||||||
mkValues :: NE.NonEmpty SingleRowEntityOccurrences -> AutomatonInfo AtomicKeySymbol StructureSearcher
|
|
||||||
mkValues neList = AutomatonInfo participatingEnts bounds sm
|
mkValues neList = AutomatonInfo participatingEnts bounds sm
|
||||||
where
|
where
|
||||||
participatingEnts =
|
participatingEnts =
|
||||||
(S.fromList . map (view entityName))
|
(S.fromList . map nameFunc)
|
||||||
(concatMap (catMaybes . fst) tuples)
|
(concatMap (catMaybes . fst) tuples)
|
||||||
|
|
||||||
tuples = M.toList $ M.mapWithKey mkSmValue groupedByUniqueRow
|
tuples = M.toList $ M.mapWithKey mkSmValue groupedByUniqueRow
|
||||||
@ -144,19 +147,18 @@ mkEntityLookup grids =
|
|||||||
|
|
||||||
-- The values of this map are guaranteed to contain only one
|
-- The values of this map are guaranteed to contain only one
|
||||||
-- entry per row of a given structure.
|
-- entry per row of a given structure.
|
||||||
rowsByEntityParticipation :: M.Map Entity (NE.NonEmpty SingleRowEntityOccurrences)
|
|
||||||
rowsByEntityParticipation =
|
rowsByEntityParticipation =
|
||||||
binTuples $
|
binTuples $
|
||||||
map (myEntity &&& id) $
|
map (myEntity &&& id) $
|
||||||
concatMap explodeRowEntities rowsAcrossAllStructures
|
concatMap explodeRowEntities rowsAcrossAllStructures
|
||||||
|
|
||||||
deriveEntityOffsets :: PositionWithinRow -> InspectionOffsets
|
deriveEntityOffsets :: PositionWithinRow b a -> InspectionOffsets
|
||||||
deriveEntityOffsets (PositionWithinRow pos r) =
|
deriveEntityOffsets (PositionWithinRow pos r) =
|
||||||
mkOffsets pos $ rowContent r
|
mkOffsets pos $ rowContent r
|
||||||
|
|
||||||
-- The members of "rowMembers" are of 'Maybe' type; the 'Nothing's
|
-- The members of "rowMembers" are of 'Maybe' type; the 'Nothing's
|
||||||
-- are dropped but accounted for when indexing the columns.
|
-- are dropped but accounted for when indexing the columns.
|
||||||
explodeRowEntities :: StructureRow -> [SingleRowEntityOccurrences]
|
explodeRowEntities :: Ord a => StructureRow b a -> [SingleRowEntityOccurrences b a]
|
||||||
explodeRowEntities r@(StructureRow _ _ rowMembers) =
|
explodeRowEntities r@(StructureRow _ _ rowMembers) =
|
||||||
map f $ M.toList $ binTuples unconsolidated
|
map f $ M.toList $ binTuples unconsolidated
|
||||||
where
|
where
|
||||||
@ -171,18 +173,23 @@ mkEntityLookup grids =
|
|||||||
|
|
||||||
-- | Create Aho-Corasick matchers that will recognize all of the
|
-- | Create Aho-Corasick matchers that will recognize all of the
|
||||||
-- provided structure definitions
|
-- provided structure definitions
|
||||||
mkAutomatons :: [SymmetryAnnotatedGrid (Maybe Cell)] -> RecognizerAutomatons
|
mkAutomatons ::
|
||||||
|
[SymmetryAnnotatedGrid (Maybe (PCell Entity))] ->
|
||||||
|
RecognizerAutomatons (PCell Entity) EntityName Entity
|
||||||
mkAutomatons xs =
|
mkAutomatons xs =
|
||||||
RecognizerAutomatons
|
RecognizerAutomatons
|
||||||
infos
|
infos
|
||||||
(mkEntityLookup rotatedGrids)
|
(mkEntityLookup (view entityName) rotatedGrids)
|
||||||
where
|
where
|
||||||
rotatedGrids = concatMap (extractGrids . namedGrid) xs
|
rotatedGrids = concatMap (extractGrids . namedGrid) xs
|
||||||
|
|
||||||
process g = StructureInfo g (getEntityGrid $ structure $ namedGrid g) . histogram . concatMap catMaybes . getEntityGrid . structure $ namedGrid g
|
process g = StructureInfo g (getEntityGrid $ structure $ namedGrid g) . histogram . concatMap catMaybes . getEntityGrid . structure $ namedGrid g
|
||||||
infos = M.fromList $ map (name . namedGrid &&& process) xs
|
infos = M.fromList $ map (name . namedGrid &&& process) xs
|
||||||
|
|
||||||
extractOrientedGrid :: NamedGrid (Maybe Cell) -> AbsoluteDir -> StructureWithGrid
|
extractOrientedGrid ::
|
||||||
|
NamedGrid (Maybe (PCell Entity)) ->
|
||||||
|
AbsoluteDir ->
|
||||||
|
StructureWithGrid (PCell Entity) Entity
|
||||||
extractOrientedGrid x d = StructureWithGrid x d $ getEntityGrid g'
|
extractOrientedGrid x d = StructureWithGrid x d $ getEntityGrid g'
|
||||||
where
|
where
|
||||||
Grid rows = structure x
|
Grid rows = structure x
|
||||||
@ -191,13 +198,13 @@ extractOrientedGrid x d = StructureWithGrid x d $ getEntityGrid g'
|
|||||||
-- | At this point, we have already ensured that orientations
|
-- | At this point, we have already ensured that orientations
|
||||||
-- redundant by rotational symmetry have been excluded
|
-- redundant by rotational symmetry have been excluded
|
||||||
-- (i.e. at Scenario validation time).
|
-- (i.e. at Scenario validation time).
|
||||||
extractGrids :: NamedGrid (Maybe Cell) -> [StructureWithGrid]
|
extractGrids :: NamedGrid (Maybe (PCell Entity)) -> [StructureWithGrid (PCell Entity) Entity]
|
||||||
extractGrids x = map (extractOrientedGrid x) $ Set.toList $ recognize x
|
extractGrids x = map (extractOrientedGrid x) $ Set.toList $ recognize x
|
||||||
|
|
||||||
-- | The output list of 'FoundStructure' records is not yet
|
-- | The output list of 'FoundStructure' records is not yet
|
||||||
-- vetted; the 'ensureStructureIntact' function will subsequently
|
-- vetted; the 'ensureStructureIntact' function will subsequently
|
||||||
-- filter this list.
|
-- filter this list.
|
||||||
lookupStaticPlacements :: StaticStructureInfo -> [FoundStructure]
|
lookupStaticPlacements :: StaticStructureInfo -> [FoundStructure (PCell Entity) Entity]
|
||||||
lookupStaticPlacements (StaticStructureInfo structDefs thePlacements) =
|
lookupStaticPlacements (StaticStructureInfo structDefs thePlacements) =
|
||||||
concatMap f $ M.toList thePlacements
|
concatMap f $ M.toList thePlacements
|
||||||
where
|
where
|
||||||
|
@ -27,13 +27,15 @@ import Swarm.Game.Scenario.Topography.Navigation.Waypoint (
|
|||||||
)
|
)
|
||||||
import Swarm.Game.Scenario.Topography.Structure (
|
import Swarm.Game.Scenario.Topography.Structure (
|
||||||
InheritedStructureDefs,
|
InheritedStructureDefs,
|
||||||
LocatedStructure,
|
|
||||||
MergedStructure (MergedStructure),
|
|
||||||
PStructure (Structure),
|
|
||||||
)
|
)
|
||||||
import Swarm.Game.Scenario.Topography.Structure qualified as Structure
|
import Swarm.Game.Scenario.Topography.Structure qualified as Structure
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Assembly qualified as Assembly
|
import Swarm.Game.Scenario.Topography.Structure.Assembly qualified as Assembly
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type (
|
||||||
|
LocatedStructure,
|
||||||
|
MergedStructure (MergedStructure),
|
||||||
|
PStructure (Structure),
|
||||||
|
)
|
||||||
import Swarm.Game.Scenario.Topography.WorldPalette
|
import Swarm.Game.Scenario.Topography.WorldPalette
|
||||||
import Swarm.Game.Universe
|
import Swarm.Game.Universe
|
||||||
import Swarm.Game.World.Parse ()
|
import Swarm.Game.World.Parse ()
|
||||||
|
@ -50,7 +50,7 @@ import Data.Map qualified as M
|
|||||||
import Data.Yaml (FromJSON (parseJSON), ToJSON (toJSON))
|
import Data.Yaml (FromJSON (parseJSON), ToJSON (toJSON))
|
||||||
import Linear (Additive (..), V2 (..), negated, norm, perp, unangle)
|
import Linear (Additive (..), V2 (..), negated, norm, perp, unangle)
|
||||||
import Linear.Affine (Affine (..), Point (..), origin)
|
import Linear.Affine (Affine (..), Point (..), origin)
|
||||||
import Swarm.Language.Syntax (AbsoluteDir (..), Direction (..), PlanarRelativeDir (..), RelativeDir (..), isCardinal)
|
import Swarm.Language.Syntax.Direction (AbsoluteDir (..), Direction (..), PlanarRelativeDir (..), RelativeDir (..), isCardinal)
|
||||||
import Swarm.Util qualified as Util
|
import Swarm.Util qualified as Util
|
||||||
|
|
||||||
-- $setup
|
-- $setup
|
@ -25,8 +25,8 @@ import Swarm.Game.Location
|
|||||||
import Swarm.Game.Scenario.Topography.Area
|
import Swarm.Game.Scenario.Topography.Area
|
||||||
import Swarm.Game.Scenario.Topography.Navigation.Waypoint
|
import Swarm.Game.Scenario.Topography.Navigation.Waypoint
|
||||||
import Swarm.Game.Scenario.Topography.Placement
|
import Swarm.Game.Scenario.Topography.Placement
|
||||||
import Swarm.Game.Scenario.Topography.Structure
|
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type
|
||||||
import Swarm.Language.Syntax.Direction (directionJsonModifier)
|
import Swarm.Language.Syntax.Direction (directionJsonModifier)
|
||||||
import Swarm.Util (commaList, quote, showT)
|
import Swarm.Util (commaList, quote, showT)
|
||||||
|
|
@ -12,11 +12,14 @@ import Swarm.Game.Scenario.Topography.Structure.Recognition.Log
|
|||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
|
|
||||||
data StructureRecognizer = StructureRecognizer
|
-- |
|
||||||
{ _automatons :: RecognizerAutomatons
|
-- The three type parameters, `b`, `en`, and `a`, correspond
|
||||||
, _foundStructures :: FoundRegistry
|
-- to 'Cell', 'EntityName', and 'Entity', respectively.
|
||||||
|
data StructureRecognizer b en a = StructureRecognizer
|
||||||
|
{ _automatons :: RecognizerAutomatons b en a
|
||||||
|
, _foundStructures :: FoundRegistry b a
|
||||||
-- ^ Records the top-left corner of the found structure
|
-- ^ Records the top-left corner of the found structure
|
||||||
, _recognitionLog :: [SearchLog]
|
, _recognitionLog :: [SearchLog en]
|
||||||
}
|
}
|
||||||
deriving (Generic)
|
deriving (Generic)
|
||||||
|
|
@ -9,14 +9,13 @@ import Data.Int (Int32)
|
|||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import Servant.Docs (ToSample)
|
import Servant.Docs (ToSample)
|
||||||
import Servant.Docs qualified as SD
|
import Servant.Docs qualified as SD
|
||||||
import Swarm.Game.Entity (EntityName)
|
|
||||||
import Swarm.Game.Location (Location)
|
import Swarm.Game.Location (Location)
|
||||||
import Swarm.Game.Scenario.Topography.Placement (StructureName)
|
import Swarm.Game.Scenario.Topography.Placement (StructureName)
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
import Swarm.Game.Universe (Cosmic)
|
import Swarm.Game.Universe (Cosmic)
|
||||||
|
|
||||||
type StructureRowContent = [Maybe EntityName]
|
type StructureRowContent en = [Maybe en]
|
||||||
type WorldRowContent = [Maybe EntityName]
|
type WorldRowContent en = [Maybe en]
|
||||||
|
|
||||||
data MatchingRowFrom = MatchingRowFrom
|
data MatchingRowFrom = MatchingRowFrom
|
||||||
{ rowIdx :: Int32
|
{ rowIdx :: Int32
|
||||||
@ -27,21 +26,21 @@ data MatchingRowFrom = MatchingRowFrom
|
|||||||
newtype HaystackPosition = HaystackPosition Int
|
newtype HaystackPosition = HaystackPosition Int
|
||||||
deriving (Generic, ToJSON)
|
deriving (Generic, ToJSON)
|
||||||
|
|
||||||
data HaystackContext = HaystackContext
|
data HaystackContext en = HaystackContext
|
||||||
{ worldRow :: WorldRowContent
|
{ worldRow :: WorldRowContent en
|
||||||
, haystackPosition :: HaystackPosition
|
, haystackPosition :: HaystackPosition
|
||||||
}
|
}
|
||||||
deriving (Generic, ToJSON)
|
deriving (Generic, ToJSON)
|
||||||
|
|
||||||
data FoundRowCandidate = FoundRowCandidate
|
data FoundRowCandidate en = FoundRowCandidate
|
||||||
{ haystackContext :: HaystackContext
|
{ haystackContext :: HaystackContext en
|
||||||
, structureContent :: StructureRowContent
|
, structureContent :: StructureRowContent en
|
||||||
, rowCandidates :: [MatchingRowFrom]
|
, rowCandidates :: [MatchingRowFrom]
|
||||||
}
|
}
|
||||||
deriving (Generic, ToJSON)
|
deriving (Generic, ToJSON)
|
||||||
|
|
||||||
data ParticipatingEntity = ParticipatingEntity
|
data ParticipatingEntity en = ParticipatingEntity
|
||||||
{ entity :: EntityName
|
{ entity :: en
|
||||||
, searchOffsets :: InspectionOffsets
|
, searchOffsets :: InspectionOffsets
|
||||||
}
|
}
|
||||||
deriving (Generic, ToJSON)
|
deriving (Generic, ToJSON)
|
||||||
@ -53,15 +52,15 @@ data IntactPlacementLog = IntactPlacementLog
|
|||||||
}
|
}
|
||||||
deriving (Generic, ToJSON)
|
deriving (Generic, ToJSON)
|
||||||
|
|
||||||
data SearchLog
|
data SearchLog en
|
||||||
= FoundParticipatingEntity ParticipatingEntity
|
= FoundParticipatingEntity (ParticipatingEntity en)
|
||||||
| StructureRemoved StructureName
|
| StructureRemoved StructureName
|
||||||
| FoundRowCandidates [FoundRowCandidate]
|
| FoundRowCandidates [FoundRowCandidate en]
|
||||||
| FoundCompleteStructureCandidates [StructureName]
|
| FoundCompleteStructureCandidates [StructureName]
|
||||||
| IntactStaticPlacement [IntactPlacementLog]
|
| IntactStaticPlacement [IntactPlacementLog]
|
||||||
deriving (Generic)
|
deriving (Generic)
|
||||||
|
|
||||||
instance ToJSON SearchLog where
|
instance (ToJSON en) => ToJSON (SearchLog en) where
|
||||||
toJSON = genericToJSON searchLogOptions
|
toJSON = genericToJSON searchLogOptions
|
||||||
|
|
||||||
searchLogOptions :: Options
|
searchLogOptions :: Options
|
||||||
@ -70,7 +69,7 @@ searchLogOptions =
|
|||||||
{ sumEncoding = ObjectWithSingleField
|
{ sumEncoding = ObjectWithSingleField
|
||||||
}
|
}
|
||||||
|
|
||||||
instance ToSample SearchLog where
|
instance ToSample (SearchLog en) where
|
||||||
toSamples _ = SD.noSamples
|
toSamples _ = SD.noSamples
|
||||||
|
|
||||||
data StructureLocation = StructureLocation StructureName (Cosmic Location)
|
data StructureLocation = StructureLocation StructureName (Cosmic Location)
|
@ -29,24 +29,27 @@ import Data.Map.NonEmpty (NEMap)
|
|||||||
import Data.Map.NonEmpty qualified as NEM
|
import Data.Map.NonEmpty qualified as NEM
|
||||||
import Swarm.Game.Location (Location)
|
import Swarm.Game.Location (Location)
|
||||||
import Swarm.Game.Scenario.Topography.Placement (StructureName)
|
import Swarm.Game.Scenario.Topography.Placement (StructureName)
|
||||||
import Swarm.Game.Scenario.Topography.Structure qualified as Structure
|
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type qualified as Structure
|
||||||
import Swarm.Game.Universe (Cosmic)
|
import Swarm.Game.Universe (Cosmic)
|
||||||
import Swarm.Util (binTuples, deleteKeys)
|
import Swarm.Util (binTuples, deleteKeys)
|
||||||
|
|
||||||
-- | The authoritative source of which built structures currently exist.
|
-- | The authoritative source of which built structures currently exist.
|
||||||
data FoundRegistry = FoundRegistry
|
--
|
||||||
{ _foundByName :: Map StructureName (NEMap (Cosmic Location) StructureWithGrid)
|
-- The two type parameters, `b` and `a`, correspond
|
||||||
, _foundByLocation :: Map (Cosmic Location) FoundStructure
|
-- to 'Cell' and 'Entity', respectively.
|
||||||
|
data FoundRegistry b a = FoundRegistry
|
||||||
|
{ _foundByName :: Map StructureName (NEMap (Cosmic Location) (StructureWithGrid b a))
|
||||||
|
, _foundByLocation :: Map (Cosmic Location) (FoundStructure b a)
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyFoundStructures :: FoundRegistry
|
emptyFoundStructures :: FoundRegistry b a
|
||||||
emptyFoundStructures = FoundRegistry mempty mempty
|
emptyFoundStructures = FoundRegistry mempty mempty
|
||||||
|
|
||||||
-- | We use a 'NEMap' here so that we can use the
|
-- | We use a 'NEMap' here so that we can use the
|
||||||
-- safe-indexing function 'indexWrapNonEmpty' in the implementation
|
-- safe-indexing function 'indexWrapNonEmpty' in the implementation
|
||||||
-- of the @structure@ command.
|
-- of the @structure@ command.
|
||||||
foundByName :: FoundRegistry -> Map StructureName (NEMap (Cosmic Location) StructureWithGrid)
|
foundByName :: FoundRegistry b a -> Map StructureName (NEMap (Cosmic Location) (StructureWithGrid b a))
|
||||||
foundByName = _foundByName
|
foundByName = _foundByName
|
||||||
|
|
||||||
-- | This is a worldwide "mask" that prevents members of placed
|
-- | This is a worldwide "mask" that prevents members of placed
|
||||||
@ -54,10 +57,10 @@ foundByName = _foundByName
|
|||||||
-- deletion of structures when their elements are removed from the world.
|
-- deletion of structures when their elements are removed from the world.
|
||||||
--
|
--
|
||||||
-- Each recognized structure instance will have @MxN@ entries in this map.
|
-- Each recognized structure instance will have @MxN@ entries in this map.
|
||||||
foundByLocation :: FoundRegistry -> Map (Cosmic Location) FoundStructure
|
foundByLocation :: FoundRegistry b a -> Map (Cosmic Location) (FoundStructure b a)
|
||||||
foundByLocation = _foundByLocation
|
foundByLocation = _foundByLocation
|
||||||
|
|
||||||
removeStructure :: FoundStructure -> FoundRegistry -> FoundRegistry
|
removeStructure :: FoundStructure b a -> FoundRegistry b a -> FoundRegistry b a
|
||||||
removeStructure fs (FoundRegistry byName byLoc) =
|
removeStructure fs (FoundRegistry byName byLoc) =
|
||||||
FoundRegistry
|
FoundRegistry
|
||||||
(M.update tidyDelete structureName byName)
|
(M.update tidyDelete structureName byName)
|
||||||
@ -71,7 +74,7 @@ removeStructure fs (FoundRegistry byName byLoc) =
|
|||||||
-- Swarm.Game.State.removeRobotFromLocationMap
|
-- Swarm.Game.State.removeRobotFromLocationMap
|
||||||
tidyDelete = NEM.nonEmptyMap . NEM.delete upperLeft
|
tidyDelete = NEM.nonEmptyMap . NEM.delete upperLeft
|
||||||
|
|
||||||
addFound :: FoundStructure -> FoundRegistry -> FoundRegistry
|
addFound :: FoundStructure b a -> FoundRegistry b a -> FoundRegistry b a
|
||||||
addFound fs@(FoundStructure swg loc) (FoundRegistry byName byLoc) =
|
addFound fs@(FoundStructure swg loc) (FoundRegistry byName byLoc) =
|
||||||
FoundRegistry
|
FoundRegistry
|
||||||
(M.insertWith (<>) k (NEM.singleton loc swg) byName)
|
(M.insertWith (<>) k (NEM.singleton loc swg) byName)
|
||||||
@ -84,7 +87,7 @@ addFound fs@(FoundStructure swg loc) (FoundRegistry byName byLoc) =
|
|||||||
--
|
--
|
||||||
-- Each of these shall have been re-checked in case
|
-- Each of these shall have been re-checked in case
|
||||||
-- a subsequent placement occludes them.
|
-- a subsequent placement occludes them.
|
||||||
populateStaticFoundStructures :: [FoundStructure] -> FoundRegistry
|
populateStaticFoundStructures :: [FoundStructure b a] -> FoundRegistry b a
|
||||||
populateStaticFoundStructures allFound =
|
populateStaticFoundStructures allFound =
|
||||||
FoundRegistry byName byLocation
|
FoundRegistry byName byLocation
|
||||||
where
|
where
|
@ -12,8 +12,8 @@ import Data.Set qualified as Set
|
|||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Swarm.Game.Scenario.Topography.Area (Grid (Grid))
|
import Swarm.Game.Scenario.Topography.Area (Grid (Grid))
|
||||||
import Swarm.Game.Scenario.Topography.Placement (Orientation (..), applyOrientationTransform)
|
import Swarm.Game.Scenario.Topography.Placement (Orientation (..), applyOrientationTransform)
|
||||||
import Swarm.Game.Scenario.Topography.Structure qualified as Structure
|
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type (RotationalSymmetry (..), SymmetryAnnotatedGrid (..))
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type (RotationalSymmetry (..), SymmetryAnnotatedGrid (..))
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type qualified as Structure
|
||||||
import Swarm.Language.Syntax.Direction (AbsoluteDir (DSouth, DWest), getCoordinateOrientation)
|
import Swarm.Language.Syntax.Direction (AbsoluteDir (DSouth, DWest), getCoordinateOrientation)
|
||||||
import Swarm.Util (commaList, failT, histogram, showT)
|
import Swarm.Util (commaList, failT, histogram, showT)
|
||||||
|
|
@ -31,14 +31,12 @@ import Data.Semigroup (Max, Min)
|
|||||||
import Data.Set (Set)
|
import Data.Set (Set)
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import Linear (V2 (..))
|
import Linear (V2 (..))
|
||||||
import Swarm.Game.Entity (Entity, EntityName)
|
|
||||||
import Swarm.Game.Location (Location)
|
import Swarm.Game.Location (Location)
|
||||||
import Swarm.Game.Scenario.Topography.Area
|
import Swarm.Game.Scenario.Topography.Area
|
||||||
import Swarm.Game.Scenario.Topography.Cell
|
|
||||||
import Swarm.Game.Scenario.Topography.Placement (StructureName)
|
import Swarm.Game.Scenario.Topography.Placement (StructureName)
|
||||||
import Swarm.Game.Scenario.Topography.Structure (NamedGrid)
|
import Swarm.Game.Scenario.Topography.Structure.Type (NamedGrid)
|
||||||
import Swarm.Game.Universe (Cosmic, offsetBy)
|
import Swarm.Game.Universe (Cosmic, offsetBy)
|
||||||
import Swarm.Language.Syntax (AbsoluteDir)
|
import Swarm.Language.Syntax.Direction (AbsoluteDir)
|
||||||
import Text.AhoCorasick (StateMachine)
|
import Text.AhoCorasick (StateMachine)
|
||||||
|
|
||||||
-- | A "needle" consisting of a single cell within
|
-- | A "needle" consisting of a single cell within
|
||||||
@ -50,7 +48,7 @@ import Text.AhoCorasick (StateMachine)
|
|||||||
-- @
|
-- @
|
||||||
-- aab
|
-- aab
|
||||||
-- @
|
-- @
|
||||||
type AtomicKeySymbol = Maybe Entity
|
type AtomicKeySymbol a = Maybe a
|
||||||
|
|
||||||
-- | A "needle" consisting row of cells within the haystack
|
-- | A "needle" consisting row of cells within the haystack
|
||||||
-- (a sequence of rows) to be searched.
|
-- (a sequence of rows) to be searched.
|
||||||
@ -61,15 +59,15 @@ type AtomicKeySymbol = Maybe Entity
|
|||||||
-- @
|
-- @
|
||||||
-- aab
|
-- aab
|
||||||
-- @
|
-- @
|
||||||
type SymbolSequence = [AtomicKeySymbol]
|
type SymbolSequence a = [AtomicKeySymbol a]
|
||||||
|
|
||||||
-- | This is returned as a value of the 1-D searcher.
|
-- | This is returned as a value of the 1-D searcher.
|
||||||
-- It contains search automatons customized to the 2-D structures
|
-- It contains search automatons customized to the 2-D structures
|
||||||
-- that may possibly contain the row found by the 1-D searcher.
|
-- that may possibly contain the row found by the 1-D searcher.
|
||||||
data StructureSearcher = StructureSearcher
|
data StructureSearcher b en a = StructureSearcher
|
||||||
{ automaton2D :: AutomatonInfo SymbolSequence StructureWithGrid
|
{ automaton2D :: AutomatonInfo en (SymbolSequence a) (StructureWithGrid b a)
|
||||||
, needleContent :: SymbolSequence
|
, needleContent :: SymbolSequence a
|
||||||
, singleRowItems :: NE.NonEmpty SingleRowEntityOccurrences
|
, singleRowItems :: NE.NonEmpty (SingleRowEntityOccurrences b a)
|
||||||
}
|
}
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
@ -83,10 +81,10 @@ data StructureSearcher = StructureSearcher
|
|||||||
-- @
|
-- @
|
||||||
--
|
--
|
||||||
-- Its '_position' is @2@.
|
-- Its '_position' is @2@.
|
||||||
data PositionWithinRow = PositionWithinRow
|
data PositionWithinRow b a = PositionWithinRow
|
||||||
{ _position :: Int32
|
{ _position :: Int32
|
||||||
-- ^ horizontal index of the entity within the row
|
-- ^ horizontal index of the entity within the row
|
||||||
, structureRow :: StructureRow
|
, structureRow :: StructureRow b a
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Represents all of the locations that particular entity
|
-- Represents all of the locations that particular entity
|
||||||
@ -100,10 +98,10 @@ data PositionWithinRow = PositionWithinRow
|
|||||||
-- @
|
-- @
|
||||||
--
|
--
|
||||||
-- this record will contain two entries in its 'entityOccurrences' field.
|
-- this record will contain two entries in its 'entityOccurrences' field.
|
||||||
data SingleRowEntityOccurrences = SingleRowEntityOccurrences
|
data SingleRowEntityOccurrences b a = SingleRowEntityOccurrences
|
||||||
{ myRow :: StructureRow
|
{ myRow :: StructureRow b a
|
||||||
, myEntity :: Entity
|
, myEntity :: a
|
||||||
, entityOccurrences :: NE.NonEmpty PositionWithinRow
|
, entityOccurrences :: NE.NonEmpty (PositionWithinRow b a)
|
||||||
, expandedOffsets :: InspectionOffsets
|
, expandedOffsets :: InspectionOffsets
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,19 +117,25 @@ data SingleRowEntityOccurrences = SingleRowEntityOccurrences
|
|||||||
-- @
|
-- @
|
||||||
--
|
--
|
||||||
-- it's 'rowIndex' is @2@.
|
-- it's 'rowIndex' is @2@.
|
||||||
data StructureRow = StructureRow
|
--
|
||||||
{ wholeStructure :: StructureWithGrid
|
-- The two type parameters, `b` and `a`, correspond
|
||||||
|
-- to 'Cell' and 'Entity', respectively.
|
||||||
|
data StructureRow b a = StructureRow
|
||||||
|
{ wholeStructure :: StructureWithGrid b a
|
||||||
, rowIndex :: Int32
|
, rowIndex :: Int32
|
||||||
-- ^ vertical index of the row within the structure
|
-- ^ vertical index of the row within the structure
|
||||||
, rowContent :: SymbolSequence
|
, rowContent :: SymbolSequence a
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | The original definition of a structure, bundled
|
-- | The original definition of a structure, bundled
|
||||||
-- with its grid of cells having been extracted for convenience.
|
-- with its grid of cells having been extracted for convenience.
|
||||||
data StructureWithGrid = StructureWithGrid
|
--
|
||||||
{ originalDefinition :: NamedGrid (Maybe Cell)
|
-- The two type parameters, `b` and `a`, correspond
|
||||||
|
-- to 'Cell' and 'Entity', respectively.
|
||||||
|
data StructureWithGrid b a = StructureWithGrid
|
||||||
|
{ originalDefinition :: NamedGrid (Maybe b)
|
||||||
, rotatedTo :: AbsoluteDir
|
, rotatedTo :: AbsoluteDir
|
||||||
, entityGrid :: [SymbolSequence]
|
, entityGrid :: [SymbolSequence a]
|
||||||
}
|
}
|
||||||
deriving (Eq)
|
deriving (Eq)
|
||||||
|
|
||||||
@ -151,10 +155,10 @@ data SymmetryAnnotatedGrid a = SymmetryAnnotatedGrid
|
|||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
-- | Structure definitions with precomputed metadata for consumption by the UI
|
-- | Structure definitions with precomputed metadata for consumption by the UI
|
||||||
data StructureInfo = StructureInfo
|
data StructureInfo b a = StructureInfo
|
||||||
{ annotatedGrid :: SymmetryAnnotatedGrid (Maybe Cell)
|
{ annotatedGrid :: SymmetryAnnotatedGrid (Maybe b)
|
||||||
, entityProcessedGrid :: [SymbolSequence]
|
, entityProcessedGrid :: [SymbolSequence a]
|
||||||
, entityCounts :: Map Entity Int
|
, entityCounts :: Map a Int
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | For all of the rows that contain a given entity
|
-- | For all of the rows that contain a given entity
|
||||||
@ -187,8 +191,8 @@ instance Semigroup InspectionOffsets where
|
|||||||
-- | Each automaton shall be initialized to recognize
|
-- | Each automaton shall be initialized to recognize
|
||||||
-- a certain subset of structure rows, that may either
|
-- a certain subset of structure rows, that may either
|
||||||
-- all be within one structure, or span multiple structures.
|
-- all be within one structure, or span multiple structures.
|
||||||
data AutomatonInfo k v = AutomatonInfo
|
data AutomatonInfo en k v = AutomatonInfo
|
||||||
{ _participatingEntities :: Set EntityName
|
{ _participatingEntities :: Set en
|
||||||
, _inspectionOffsets :: InspectionOffsets
|
, _inspectionOffsets :: InspectionOffsets
|
||||||
, _automaton :: StateMachine k v
|
, _automaton :: StateMachine k v
|
||||||
}
|
}
|
||||||
@ -198,11 +202,11 @@ makeLenses ''AutomatonInfo
|
|||||||
|
|
||||||
-- | The complete set of data needed to identify applicable
|
-- | The complete set of data needed to identify applicable
|
||||||
-- structures, based on a just-placed entity.
|
-- structures, based on a just-placed entity.
|
||||||
data RecognizerAutomatons = RecognizerAutomatons
|
data RecognizerAutomatons b en a = RecognizerAutomatons
|
||||||
{ _originalStructureDefinitions :: Map StructureName StructureInfo
|
{ _originalStructureDefinitions :: Map StructureName (StructureInfo b a)
|
||||||
-- ^ all of the structures that shall participate in automatic recognition.
|
-- ^ all of the structures that shall participate in automatic recognition.
|
||||||
-- This list is used only by the UI and by the 'Floorplan' command.
|
-- This list is used only by the UI and by the 'Floorplan' command.
|
||||||
, _automatonsByEntity :: Map Entity (AutomatonInfo AtomicKeySymbol StructureSearcher)
|
, _automatonsByEntity :: Map a (AutomatonInfo en (AtomicKeySymbol a) (StructureSearcher b en a))
|
||||||
}
|
}
|
||||||
deriving (Generic)
|
deriving (Generic)
|
||||||
|
|
||||||
@ -210,8 +214,11 @@ makeLenses ''RecognizerAutomatons
|
|||||||
|
|
||||||
-- | Final output of the search process.
|
-- | Final output of the search process.
|
||||||
-- These are the elements that are stored in the 'FoundRegistry'.
|
-- These are the elements that are stored in the 'FoundRegistry'.
|
||||||
data FoundStructure = FoundStructure
|
--
|
||||||
{ structureWithGrid :: StructureWithGrid
|
-- The two type parameters, `b` and `a`, correspond
|
||||||
|
-- to 'Cell' and 'Entity', respectively.
|
||||||
|
data FoundStructure b a = FoundStructure
|
||||||
|
{ structureWithGrid :: StructureWithGrid b a
|
||||||
, upperLeftCorner :: Cosmic Location
|
, upperLeftCorner :: Cosmic Location
|
||||||
}
|
}
|
||||||
deriving (Eq)
|
deriving (Eq)
|
||||||
@ -226,7 +233,7 @@ data FoundStructure = FoundStructure
|
|||||||
-- Since the natural order of coordinates increases as described,
|
-- Since the natural order of coordinates increases as described,
|
||||||
-- we need to invert it with 'Down' so that this ordering is by
|
-- we need to invert it with 'Down' so that this ordering is by
|
||||||
-- increasing preference.
|
-- increasing preference.
|
||||||
instance Ord FoundStructure where
|
instance (Eq b, Eq a) => Ord (FoundStructure b a) where
|
||||||
compare = compare `on` (f1 &&& f2)
|
compare = compare `on` (f1 &&& f2)
|
||||||
where
|
where
|
||||||
f1 = computeArea . getAreaDimensions . entityGrid . structureWithGrid
|
f1 = computeArea . getAreaDimensions . entityGrid . structureWithGrid
|
||||||
@ -235,7 +242,7 @@ instance Ord FoundStructure where
|
|||||||
-- | Yields coordinates that are occupied by an entity of a placed structure.
|
-- | Yields coordinates that are occupied by an entity of a placed structure.
|
||||||
-- Cells within the rectangular bounds of the structure that are unoccupied
|
-- Cells within the rectangular bounds of the structure that are unoccupied
|
||||||
-- are not included.
|
-- are not included.
|
||||||
genOccupiedCoords :: FoundStructure -> [Cosmic Location]
|
genOccupiedCoords :: FoundStructure b a -> [Cosmic Location]
|
||||||
genOccupiedCoords (FoundStructure swg loc) =
|
genOccupiedCoords (FoundStructure swg loc) =
|
||||||
concatMap catMaybes . zipWith mkRow [0 ..] $ entityGrid swg
|
concatMap catMaybes . zipWith mkRow [0 ..] $ entityGrid swg
|
||||||
where
|
where
|
@ -0,0 +1,63 @@
|
|||||||
|
-- |
|
||||||
|
-- SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
--
|
||||||
|
-- Definitions of "structures" for use within a map
|
||||||
|
-- as well as logic for combining them.
|
||||||
|
module Swarm.Game.Scenario.Topography.Structure.Type where
|
||||||
|
|
||||||
|
import Data.Set (Set)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Swarm.Game.Location
|
||||||
|
import Swarm.Game.Scenario.Topography.Area
|
||||||
|
import Swarm.Game.Scenario.Topography.Navigation.Waypoint
|
||||||
|
import Swarm.Game.Scenario.Topography.Placement
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Overlay
|
||||||
|
import Swarm.Language.Syntax.Direction (AbsoluteDir)
|
||||||
|
|
||||||
|
data NamedArea a = NamedArea
|
||||||
|
{ name :: StructureName
|
||||||
|
, recognize :: Set AbsoluteDir
|
||||||
|
-- ^ whether this structure should be registered for automatic recognition
|
||||||
|
-- and which orientations shall be recognized.
|
||||||
|
-- The supplied direction indicates which cardinal direction the
|
||||||
|
-- original map's "North" has been re-oriented to.
|
||||||
|
-- E.g., 'DWest' represents a rotation of 90 degrees counter-clockwise.
|
||||||
|
, description :: Maybe Text
|
||||||
|
-- ^ will be UI-facing only if this is a recognizable structure
|
||||||
|
, structure :: a
|
||||||
|
}
|
||||||
|
deriving (Eq, Show, Functor)
|
||||||
|
|
||||||
|
isRecognizable :: NamedArea a -> Bool
|
||||||
|
isRecognizable = not . null . recognize
|
||||||
|
|
||||||
|
type NamedGrid c = NamedArea (Grid c)
|
||||||
|
|
||||||
|
type NamedStructure c = NamedArea (PStructure c)
|
||||||
|
|
||||||
|
data PStructure c = Structure
|
||||||
|
{ area :: PositionedGrid c
|
||||||
|
, structures :: [NamedStructure c]
|
||||||
|
-- ^ structure definitions from parents shall be accessible by children
|
||||||
|
, placements :: [Placement]
|
||||||
|
-- ^ earlier placements will be overlaid on top of later placements in the YAML file
|
||||||
|
, waypoints :: [Waypoint]
|
||||||
|
}
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
data Placed c = Placed Placement (NamedStructure c)
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
|
-- | For use in registering recognizable pre-placed structures
|
||||||
|
data LocatedStructure = LocatedStructure
|
||||||
|
{ placedName :: StructureName
|
||||||
|
, upDirection :: AbsoluteDir
|
||||||
|
, cornerLoc :: Location
|
||||||
|
}
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
|
instance HasLocation LocatedStructure where
|
||||||
|
modifyLoc f (LocatedStructure x y originalLoc) =
|
||||||
|
LocatedStructure x y $ f originalLoc
|
||||||
|
|
||||||
|
data MergedStructure c = MergedStructure (PositionedGrid c) [LocatedStructure] [Originated Waypoint]
|
@ -10,12 +10,14 @@ module Swarm.TUI.Model.Structure where
|
|||||||
import Brick.Focus
|
import Brick.Focus
|
||||||
import Brick.Widgets.List qualified as BL
|
import Brick.Widgets.List qualified as BL
|
||||||
import Control.Lens (makeLenses)
|
import Control.Lens (makeLenses)
|
||||||
|
import Swarm.Game.Entity (Entity)
|
||||||
|
import Swarm.Game.Scenario (Cell)
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
import Swarm.TUI.Model.Name
|
import Swarm.TUI.Model.Name
|
||||||
import Swarm.Util (listEnums)
|
import Swarm.Util (listEnums)
|
||||||
|
|
||||||
data StructureDisplay = StructureDisplay
|
data StructureDisplay = StructureDisplay
|
||||||
{ _structurePanelListWidget :: BL.List Name StructureInfo
|
{ _structurePanelListWidget :: BL.List Name (StructureInfo Cell Entity)
|
||||||
-- ^ required for maintaining the selection/navigation
|
-- ^ required for maintaining the selection/navigation
|
||||||
-- state among list items
|
-- state among list items
|
||||||
, _structurePanelFocus :: FocusRing Name
|
, _structurePanelFocus :: FocusRing Name
|
||||||
|
@ -19,14 +19,15 @@ import Data.Map.Strict qualified as M
|
|||||||
import Data.Set qualified as Set
|
import Data.Set qualified as Set
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.Vector qualified as V
|
import Data.Vector qualified as V
|
||||||
import Swarm.Game.Entity (entityDisplay)
|
import Swarm.Game.Entity (Entity, entityDisplay)
|
||||||
|
import Swarm.Game.Scenario (Cell)
|
||||||
import Swarm.Game.Scenario.Topography.Area
|
import Swarm.Game.Scenario.Topography.Area
|
||||||
import Swarm.Game.Scenario.Topography.Placement
|
import Swarm.Game.Scenario.Topography.Placement
|
||||||
import Swarm.Game.Scenario.Topography.Structure qualified as Structure
|
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition (foundStructures)
|
import Swarm.Game.Scenario.Topography.Structure.Recognition (foundStructures)
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Precompute (getEntityGrid)
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Precompute (getEntityGrid)
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry (foundByName)
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Registry (foundByName)
|
||||||
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
|
import Swarm.Game.Scenario.Topography.Structure.Type qualified as Structure
|
||||||
import Swarm.Game.State
|
import Swarm.Game.State
|
||||||
import Swarm.Game.State.Substate
|
import Swarm.Game.State.Substate
|
||||||
import Swarm.Language.Syntax.Direction (directionJsonModifier)
|
import Swarm.Language.Syntax.Direction (directionJsonModifier)
|
||||||
@ -39,7 +40,7 @@ import Swarm.Util (commaList)
|
|||||||
|
|
||||||
-- | Render a two-pane widget with structure selection on the left
|
-- | Render a two-pane widget with structure selection on the left
|
||||||
-- and single-structure details on the right.
|
-- and single-structure details on the right.
|
||||||
structureWidget :: GameState -> StructureInfo -> Widget n
|
structureWidget :: GameState -> StructureInfo Cell Entity -> Widget n
|
||||||
structureWidget gs s =
|
structureWidget gs s =
|
||||||
vBox
|
vBox
|
||||||
[ hBox
|
[ hBox
|
||||||
@ -121,7 +122,7 @@ structureWidget gs s =
|
|||||||
cells = getEntityGrid $ Structure.structure d
|
cells = getEntityGrid $ Structure.structure d
|
||||||
renderOneCell = maybe (txt " ") (renderDisplay . view entityDisplay)
|
renderOneCell = maybe (txt " ") (renderDisplay . view entityDisplay)
|
||||||
|
|
||||||
makeListWidget :: [StructureInfo] -> BL.List Name StructureInfo
|
makeListWidget :: [StructureInfo Cell Entity] -> BL.List Name (StructureInfo Cell Entity)
|
||||||
makeListWidget structureDefinitions =
|
makeListWidget structureDefinitions =
|
||||||
BL.listMoveTo 0 $ BL.list (StructureWidgets StructuresList) (V.fromList structureDefinitions) 1
|
BL.listMoveTo 0 $ BL.list (StructureWidgets StructuresList) (V.fromList structureDefinitions) 1
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ renderStructuresDisplay gs structureDisplay =
|
|||||||
|
|
||||||
drawSidebarListItem ::
|
drawSidebarListItem ::
|
||||||
Bool ->
|
Bool ->
|
||||||
StructureInfo ->
|
StructureInfo Cell Entity ->
|
||||||
Widget Name
|
Widget Name
|
||||||
drawSidebarListItem _isSelected (StructureInfo annotated _ _) =
|
drawSidebarListItem _isSelected (StructureInfo annotated _ _) =
|
||||||
txt . getStructureName . Structure.name $ namedGrid annotated
|
txt . getStructureName . Structure.name $ namedGrid annotated
|
||||||
|
@ -64,6 +64,7 @@ import Servant.Docs (ToCapture)
|
|||||||
import Servant.Docs qualified as SD
|
import Servant.Docs qualified as SD
|
||||||
import Servant.Docs.Internal qualified as SD (renderCurlBasePath)
|
import Servant.Docs.Internal qualified as SD (renderCurlBasePath)
|
||||||
import Swarm.Doc.Command
|
import Swarm.Doc.Command
|
||||||
|
import Swarm.Game.Entity (EntityName)
|
||||||
import Swarm.Game.Robot
|
import Swarm.Game.Robot
|
||||||
import Swarm.Game.Scenario.Objective
|
import Swarm.Game.Scenario.Objective
|
||||||
import Swarm.Game.Scenario.Objective.Graph
|
import Swarm.Game.Scenario.Objective.Graph
|
||||||
@ -104,7 +105,7 @@ type SwarmAPI =
|
|||||||
:<|> "goals" :> "graph" :> Get '[JSON] (Maybe GraphInfo)
|
:<|> "goals" :> "graph" :> Get '[JSON] (Maybe GraphInfo)
|
||||||
:<|> "goals" :> "uigoal" :> Get '[JSON] GoalTracking
|
:<|> "goals" :> "uigoal" :> Get '[JSON] GoalTracking
|
||||||
:<|> "goals" :> Get '[JSON] WinCondition
|
:<|> "goals" :> Get '[JSON] WinCondition
|
||||||
:<|> "recognize" :> "log" :> Get '[JSON] [SearchLog]
|
:<|> "recognize" :> "log" :> Get '[JSON] [SearchLog EntityName]
|
||||||
:<|> "recognize" :> "found" :> Get '[JSON] [StructureLocation]
|
:<|> "recognize" :> "found" :> Get '[JSON] [StructureLocation]
|
||||||
:<|> "code" :> "render" :> ReqBody '[PlainText] T.Text :> Post '[PlainText] T.Text
|
:<|> "code" :> "render" :> ReqBody '[PlainText] T.Text :> Post '[PlainText] T.Text
|
||||||
:<|> "code" :> "run" :> ReqBody '[PlainText] T.Text :> Post '[PlainText] T.Text
|
:<|> "code" :> "run" :> ReqBody '[PlainText] T.Text :> Post '[PlainText] T.Text
|
||||||
@ -210,7 +211,7 @@ goalsHandler appStateRef = do
|
|||||||
appState <- liftIO (readIORef appStateRef)
|
appState <- liftIO (readIORef appStateRef)
|
||||||
return $ appState ^. gameState . winCondition
|
return $ appState ^. gameState . winCondition
|
||||||
|
|
||||||
recogLogHandler :: ReadableIORef AppState -> Handler [SearchLog]
|
recogLogHandler :: ReadableIORef AppState -> Handler [SearchLog EntityName]
|
||||||
recogLogHandler appStateRef = do
|
recogLogHandler appStateRef = do
|
||||||
appState <- liftIO (readIORef appStateRef)
|
appState <- liftIO (readIORef appStateRef)
|
||||||
return $ appState ^. gameState . discovery . structureRecognition . recognitionLog
|
return $ appState ^. gameState . discovery . structureRecognition . recognitionLog
|
||||||
|
75
swarm.cabal
75
swarm.cabal
@ -152,7 +152,6 @@ library swarm-lang
|
|||||||
Swarm.Language.Syntax.CommandMetadata
|
Swarm.Language.Syntax.CommandMetadata
|
||||||
Swarm.Language.Syntax.Comments
|
Swarm.Language.Syntax.Comments
|
||||||
Swarm.Language.Syntax.Constants
|
Swarm.Language.Syntax.Constants
|
||||||
Swarm.Language.Syntax.Direction
|
|
||||||
Swarm.Language.Syntax.Loc
|
Swarm.Language.Syntax.Loc
|
||||||
Swarm.Language.Syntax.Pattern
|
Swarm.Language.Syntax.Pattern
|
||||||
Swarm.Language.Syntax.Util
|
Swarm.Language.Syntax.Util
|
||||||
@ -201,6 +200,50 @@ library swarm-lang
|
|||||||
-- See discussion in #415
|
-- See discussion in #415
|
||||||
StrictData
|
StrictData
|
||||||
|
|
||||||
|
library swarm-topography
|
||||||
|
import: stan-config, common, ghc2021-extensions
|
||||||
|
visibility: public
|
||||||
|
-- cabal-gild: discover src/swarm-topography
|
||||||
|
exposed-modules:
|
||||||
|
Swarm.Game.Location
|
||||||
|
Swarm.Game.Scenario.Topography.Area
|
||||||
|
Swarm.Game.Scenario.Topography.Navigation.Waypoint
|
||||||
|
Swarm.Game.Scenario.Topography.Placement
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Assembly
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Overlay
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Recognition
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Recognition.Log
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Recognition.Symmetry
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
||||||
|
Swarm.Game.Scenario.Topography.Structure.Type
|
||||||
|
Swarm.Game.Universe
|
||||||
|
|
||||||
|
other-modules: Paths_swarm
|
||||||
|
autogen-modules: Paths_swarm
|
||||||
|
build-depends:
|
||||||
|
AhoCorasick >=0.0.4 && <0.0.5,
|
||||||
|
aeson >=2.2 && <2.3,
|
||||||
|
base >=4.14 && <4.20,
|
||||||
|
containers >=0.6.2 && <0.8,
|
||||||
|
extra >=1.7 && <1.8,
|
||||||
|
lens,
|
||||||
|
linear >=1.21.6 && <1.24,
|
||||||
|
nonempty-containers >=0.3.4 && <0.3.5,
|
||||||
|
servant-docs >=0.12 && <0.14,
|
||||||
|
text >=1.2.4 && <2.2,
|
||||||
|
yaml >=0.11 && <0.11.12.0,
|
||||||
|
|
||||||
|
build-depends:
|
||||||
|
swarm:swarm-util
|
||||||
|
|
||||||
|
hs-source-dirs: src/swarm-topography
|
||||||
|
default-language: Haskell2010
|
||||||
|
default-extensions:
|
||||||
|
-- Avoid unexpected unevaluated thunk buildup
|
||||||
|
-- See discussion in #415
|
||||||
|
StrictData
|
||||||
|
|
||||||
library swarm-scenario
|
library swarm-scenario
|
||||||
import: stan-config, common, ghc2021-extensions
|
import: stan-config, common, ghc2021-extensions
|
||||||
visibility: public
|
visibility: public
|
||||||
@ -216,7 +259,6 @@ library swarm-scenario
|
|||||||
Swarm.Game.Failure
|
Swarm.Game.Failure
|
||||||
Swarm.Game.Ingredients
|
Swarm.Game.Ingredients
|
||||||
Swarm.Game.Land
|
Swarm.Game.Land
|
||||||
Swarm.Game.Location
|
|
||||||
Swarm.Game.Recipe
|
Swarm.Game.Recipe
|
||||||
Swarm.Game.ResourceLoading
|
Swarm.Game.ResourceLoading
|
||||||
Swarm.Game.Robot
|
Swarm.Game.Robot
|
||||||
@ -228,28 +270,17 @@ library swarm-scenario
|
|||||||
Swarm.Game.Scenario.Objective.Validation
|
Swarm.Game.Scenario.Objective.Validation
|
||||||
Swarm.Game.Scenario.RobotLookup
|
Swarm.Game.Scenario.RobotLookup
|
||||||
Swarm.Game.Scenario.Style
|
Swarm.Game.Scenario.Style
|
||||||
Swarm.Game.Scenario.Topography.Area
|
|
||||||
Swarm.Game.Scenario.Topography.Cell
|
Swarm.Game.Scenario.Topography.Cell
|
||||||
Swarm.Game.Scenario.Topography.Center
|
Swarm.Game.Scenario.Topography.Center
|
||||||
Swarm.Game.Scenario.Topography.EntityFacade
|
Swarm.Game.Scenario.Topography.EntityFacade
|
||||||
Swarm.Game.Scenario.Topography.Navigation.Portal
|
Swarm.Game.Scenario.Topography.Navigation.Portal
|
||||||
Swarm.Game.Scenario.Topography.Navigation.Waypoint
|
|
||||||
Swarm.Game.Scenario.Topography.Placement
|
|
||||||
Swarm.Game.Scenario.Topography.Structure
|
Swarm.Game.Scenario.Topography.Structure
|
||||||
Swarm.Game.Scenario.Topography.Structure.Assembly
|
|
||||||
Swarm.Game.Scenario.Topography.Structure.Overlay
|
|
||||||
Swarm.Game.Scenario.Topography.Structure.Recognition
|
|
||||||
Swarm.Game.Scenario.Topography.Structure.Recognition.Log
|
|
||||||
Swarm.Game.Scenario.Topography.Structure.Recognition.Precompute
|
Swarm.Game.Scenario.Topography.Structure.Recognition.Precompute
|
||||||
Swarm.Game.Scenario.Topography.Structure.Recognition.Registry
|
|
||||||
Swarm.Game.Scenario.Topography.Structure.Recognition.Symmetry
|
|
||||||
Swarm.Game.Scenario.Topography.Structure.Recognition.Type
|
|
||||||
Swarm.Game.Scenario.Topography.WorldDescription
|
Swarm.Game.Scenario.Topography.WorldDescription
|
||||||
Swarm.Game.Scenario.Topography.WorldPalette
|
Swarm.Game.Scenario.Topography.WorldPalette
|
||||||
Swarm.Game.State.Config
|
Swarm.Game.State.Config
|
||||||
Swarm.Game.State.Landscape
|
Swarm.Game.State.Landscape
|
||||||
Swarm.Game.Terrain
|
Swarm.Game.Terrain
|
||||||
Swarm.Game.Universe
|
|
||||||
Swarm.Game.World
|
Swarm.Game.World
|
||||||
Swarm.Game.World.Abstract
|
Swarm.Game.World.Abstract
|
||||||
Swarm.Game.World.Compile
|
Swarm.Game.World.Compile
|
||||||
@ -289,7 +320,6 @@ library swarm-scenario
|
|||||||
linear >=1.21.6 && <1.24,
|
linear >=1.21.6 && <1.24,
|
||||||
megaparsec >=9.6.1 && <9.7,
|
megaparsec >=9.6.1 && <9.7,
|
||||||
murmur3 >=1.0.4 && <1.1,
|
murmur3 >=1.0.4 && <1.1,
|
||||||
nonempty-containers >=0.3.4 && <0.3.5,
|
|
||||||
palette >=0.3 && <0.4,
|
palette >=0.3 && <0.4,
|
||||||
parser-combinators >=1.2 && <1.4,
|
parser-combinators >=1.2 && <1.4,
|
||||||
prettyprinter >=1.7.0 && <1.8,
|
prettyprinter >=1.7.0 && <1.8,
|
||||||
@ -305,6 +335,7 @@ library swarm-scenario
|
|||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
swarm:swarm-lang,
|
swarm:swarm-lang,
|
||||||
|
swarm:swarm-topography,
|
||||||
swarm:swarm-util,
|
swarm:swarm-util,
|
||||||
|
|
||||||
hs-source-dirs: src/swarm-scenario
|
hs-source-dirs: src/swarm-scenario
|
||||||
@ -405,6 +436,7 @@ library swarm-engine
|
|||||||
build-depends:
|
build-depends:
|
||||||
swarm:swarm-lang,
|
swarm:swarm-lang,
|
||||||
swarm:swarm-scenario,
|
swarm:swarm-scenario,
|
||||||
|
swarm:swarm-topography,
|
||||||
swarm:swarm-util,
|
swarm:swarm-util,
|
||||||
|
|
||||||
hs-source-dirs: src/swarm-engine
|
hs-source-dirs: src/swarm-engine
|
||||||
@ -449,6 +481,7 @@ library swarm-web
|
|||||||
swarm:swarm-engine,
|
swarm:swarm-engine,
|
||||||
swarm:swarm-lang,
|
swarm:swarm-lang,
|
||||||
swarm:swarm-scenario,
|
swarm:swarm-scenario,
|
||||||
|
swarm:swarm-topography,
|
||||||
swarm:swarm-tui,
|
swarm:swarm-tui,
|
||||||
swarm:swarm-util,
|
swarm:swarm-util,
|
||||||
|
|
||||||
@ -520,6 +553,7 @@ library swarm-util
|
|||||||
exposed-modules:
|
exposed-modules:
|
||||||
Control.Carrier.Accum.FixedStrict
|
Control.Carrier.Accum.FixedStrict
|
||||||
Data.BoolExpr.Simplify
|
Data.BoolExpr.Simplify
|
||||||
|
Swarm.Language.Syntax.Direction
|
||||||
Swarm.Util
|
Swarm.Util
|
||||||
Swarm.Util.Effect
|
Swarm.Util.Effect
|
||||||
Swarm.Util.Erasable
|
Swarm.Util.Erasable
|
||||||
@ -545,6 +579,7 @@ library swarm-util
|
|||||||
extra >=1.7 && <1.8,
|
extra >=1.7 && <1.8,
|
||||||
filepath >=1.4 && <1.5,
|
filepath >=1.4 && <1.5,
|
||||||
fused-effects >=1.1.1.1 && <1.2,
|
fused-effects >=1.1.1.1 && <1.2,
|
||||||
|
hashable >=1.3.4 && <1.5,
|
||||||
lens >=4.19 && <5.4,
|
lens >=4.19 && <5.4,
|
||||||
minimorph >=0.3 && <0.4,
|
minimorph >=0.3 && <0.4,
|
||||||
mtl >=2.2.2 && <2.4,
|
mtl >=2.2.2 && <2.4,
|
||||||
@ -699,6 +734,7 @@ library swarm-tui
|
|||||||
swarm:swarm-engine,
|
swarm:swarm-engine,
|
||||||
swarm:swarm-lang,
|
swarm:swarm-lang,
|
||||||
swarm:swarm-scenario,
|
swarm:swarm-scenario,
|
||||||
|
swarm:swarm-topography,
|
||||||
swarm:swarm-util,
|
swarm:swarm-util,
|
||||||
|
|
||||||
hs-source-dirs: src/swarm-tui
|
hs-source-dirs: src/swarm-tui
|
||||||
@ -745,7 +781,10 @@ executable swarm-scene
|
|||||||
build-depends:
|
build-depends:
|
||||||
base,
|
base,
|
||||||
optparse-applicative >=0.16 && <0.19,
|
optparse-applicative >=0.16 && <0.19,
|
||||||
|
|
||||||
|
build-depends:
|
||||||
swarm:swarm-scenario,
|
swarm:swarm-scenario,
|
||||||
|
swarm:swarm-topography,
|
||||||
|
|
||||||
hs-source-dirs: app/scene
|
hs-source-dirs: app/scene
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
@ -836,6 +875,7 @@ test-suite swarm-unit
|
|||||||
swarm:swarm-engine,
|
swarm:swarm-engine,
|
||||||
swarm:swarm-lang,
|
swarm:swarm-lang,
|
||||||
swarm:swarm-scenario,
|
swarm:swarm-scenario,
|
||||||
|
swarm:swarm-topography,
|
||||||
swarm:swarm-tui,
|
swarm:swarm-tui,
|
||||||
swarm:swarm-util,
|
swarm:swarm-util,
|
||||||
|
|
||||||
@ -907,12 +947,15 @@ benchmark benchmark
|
|||||||
extra,
|
extra,
|
||||||
lens,
|
lens,
|
||||||
mtl,
|
mtl,
|
||||||
|
tasty-bench >=0.3.1 && <0.4,
|
||||||
|
text,
|
||||||
|
|
||||||
|
build-depends:
|
||||||
swarm:swarm-engine,
|
swarm:swarm-engine,
|
||||||
swarm:swarm-lang,
|
swarm:swarm-lang,
|
||||||
swarm:swarm-scenario,
|
swarm:swarm-scenario,
|
||||||
|
swarm:swarm-topography,
|
||||||
swarm:swarm-util,
|
swarm:swarm-util,
|
||||||
tasty-bench >=0.3.1 && <0.4,
|
|
||||||
text,
|
|
||||||
|
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
ghc-options:
|
ghc-options:
|
||||||
|
@ -12,7 +12,7 @@ import Data.Text (Text)
|
|||||||
import Graphics.Vty.Input.Events qualified as V
|
import Graphics.Vty.Input.Events qualified as V
|
||||||
import Swarm.Game.Location
|
import Swarm.Game.Location
|
||||||
import Swarm.Language.Key
|
import Swarm.Language.Key
|
||||||
import Swarm.Language.Syntax
|
import Swarm.Language.Syntax.Direction
|
||||||
import Test.QuickCheck qualified as QC
|
import Test.QuickCheck qualified as QC
|
||||||
import Test.Tasty
|
import Test.Tasty
|
||||||
import Test.Tasty.HUnit
|
import Test.Tasty.HUnit
|
||||||
|
Loading…
Reference in New Issue
Block a user