Skip to content

Commit

Permalink
Implement non-truncating structure overlays
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed May 12, 2024
1 parent bc0c404 commit 4632462
Show file tree
Hide file tree
Showing 22 changed files with 590 additions and 75 deletions.
3 changes: 2 additions & 1 deletion data/scenarios/Testing/00-ORDER.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ Achievements
1747-volume-command.yaml
1777-capability-cost.yaml
1775-custom-terrain.yaml
1642-biomes.yaml
1642-biomes.yaml
1780-structure-merge-expansion
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nonoverlapping-structure-merge.yaml
root-map-expansion.yaml
structure-composition.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
version: 1
name: Expansion of a substructure to fit its placements
description: |
Define two structures and place them on the map.
robots:
- name: base
loc: [4, -4]
dir: east
known: [water, sand, tree]
world:
palette:
'.': [grass]
upperleft: [-1, 1]
structures:
- name: vertical rectangle
structure:
palette:
'x': [blank, tree]
map: |
xx
xx
xx
xx
- name: horizontal rectangle
structure:
palette:
'x': [blank, sand]
map: |
xxxx
xxxx
- name: disjoint rectangles
structure:
palette:
'x': [blank, water]
map: |
xx
xx
placements:
- src: vertical rectangle
truncate: false
offset: [-7, 7]
- src: horizontal rectangle
truncate: false
offset: [7, -7]
placements:
- src: disjoint rectangles
offset: [2, -2]
map: |
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: 1
name: Non-overlapping merging with expansion
description: |
Define two structures and place them on the map.
Demonstrates automatic expansion of the root map grid.
robots:
- name: base
loc: [8, 0]
dir: east
known: [tree, sand, water]
world:
palette:
'.': [grass]
'i': [ice]
'j': [dirt]
'k': [stone]
'l': [stone, sand]
'm': [stone, water]
upperleft: [3, 3]
structures:
- name: single tree
structure:
palette:
'x': [blank, tree]
map: |
x
placements:
- src: single tree
truncate: false
offset: [-2, -4]
map: |
i.
.j
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
version: 1
name: Various structure merging arrangements
description: |
Define two structures and place them on the map.
robots:
- name: base
loc: [11, 0]
dir: east
known: [water, sand]
world:
palette:
'.': [grass]
upperleft: [-1, 1]
structures:
- name: vertical rectangle
structure:
palette:
'x': [blank, water]
map: |
xx
xx
xx
xx
- name: horizontal rectangle
structure:
palette:
'x': [blank, sand]
map: |
xxxx
xxxx
- name: combined rectangles blank base
structure:
palette:
'x': [blank]
map: |
xxxx
xxxx
xxxx
xxxx
placements:
- src: vertical rectangle
- src: horizontal rectangle
- name: combined rectangles empty base
structure:
palette:
'x': [blank]
map: ""
placements:
- src: vertical rectangle
truncate: false
- src: horizontal rectangle
truncate: false
- name: combined rectangles single cell base
structure:
palette:
'x': [blank]
map: |
x
placements:
- src: vertical rectangle
truncate: false
- src: horizontal rectangle
truncate: false
- name: multi overlap
structure:
palette:
'x': [blank]
map: |
xxxx
placements:
- src: vertical rectangle
offset: [1, 0]
truncate: false
- src: horizontal rectangle
truncate: false
offset: [0, -2]
- src: vertical rectangle
offset: [3, -2]
truncate: false
- src: horizontal rectangle
truncate: false
offset: [3, -4]
- src: vertical rectangle
offset: [5, -4]
truncate: false
placements:
- src: vertical rectangle
offset: [1, -1]
- src: horizontal rectangle
offset: [1, -1]
- src: multi overlap
offset: [1, -6]
truncate: false
- src: combined rectangles blank base
offset: [6, -1]
- src: combined rectangles empty base
offset: [11, -1]
- src: combined rectangles single cell base
offset: [11, -6]
map: |
................
................
................
................
................
................
................
................
................
................
................
5 changes: 2 additions & 3 deletions scripts/test/run-tests.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/bin/bash -ex

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR/..
cd $(git rev-parse --show-toplevel)

# See https://github.com/swarm-game/swarm/issues/936
STACK_WORK=.stack-work-test stack test --fast "$@"
cabal test -O0 -j "$@"
3 changes: 2 additions & 1 deletion src/swarm-scenario/Swarm/Game/Scenario.hs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import Swarm.Game.Scenario.Topography.Navigation.Portal
import Swarm.Game.Scenario.Topography.Navigation.Waypoint (Parentage (..))
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.Overlay
import Swarm.Game.Scenario.Topography.Structure.Recognition.Symmetry
import Swarm.Game.Scenario.Topography.Structure.Recognition.Type (SymmetryAnnotatedGrid (..))
import Swarm.Game.Scenario.Topography.WorldDescription
Expand Down Expand Up @@ -336,7 +337,7 @@ instance FromJSONE ScenarioInputs Scenario where
(sequenceA . (id &&& (Assembly.mergeStructures mempty Root . Structure.structure)))
rootLevelSharedStructures

let namedGrids = map (\(ns, Structure.MergedStructure s _ _) -> s <$ ns) mergedStructures
let namedGrids = map (\(ns, Structure.MergedStructure (PositionedGrid _ s) _ _) -> s <$ ns) mergedStructures

allWorlds <- localE (WorldParseDependencies worldMap rootLevelSharedStructures rsMap) $ do
rootWorld <- v ..: "world"
Expand Down
28 changes: 22 additions & 6 deletions src/swarm-scenario/Swarm/Game/Scenario/Topography/Area.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ newtype Grid c = Grid
}
deriving (Show, Eq, Functor, Foldable, Traversable)

-- | Since the derived 'Functor' instance applies to the
-- type parameter that is nested within lists, we define
-- an explicit function for mapping over the enclosing lists.
mapRows :: ([[a]] -> [[b]]) -> Grid a -> Grid b
mapRows f (Grid rows) = Grid $ f rows

instance (ToJSON a) => ToJSON (Grid a) where
toJSON (Grid g) = toJSON g

Expand All @@ -41,21 +47,25 @@ invertY (V2 x y) = V2 x (-y)
-- | Incorporates an offset by @-1@, since the area is
-- "inclusive" of the lower-right coordinate.
-- Inverse of 'cornersToArea'.
upperLeftToBottomRight :: AreaDimensions -> Location -> Location
upperLeftToBottomRight (AreaDimensions w h) upperLeft =
computeBottomRightFromUpperLeft :: AreaDimensions -> Location -> Location
computeBottomRightFromUpperLeft a upperLeft =
upperLeft .+^ displacement
where
displacement = invertY $ subtract 1 <$> V2 w h
displacement = invertY $ computeAbsoluteCornerDisplacement a

computeAbsoluteCornerDisplacement :: AreaDimensions -> V2 Int32
computeAbsoluteCornerDisplacement (AreaDimensions w h) =
subtract 1 <$> V2 w h

-- | Converts the displacement vector between the two
-- diagonal corners of the rectangle into an 'AreaDimensions' record.
-- Adds one to both dimensions since the corner coordinates are "inclusive".
-- Inverse of 'upperLeftToBottomRight'.
-- Inverse of 'computeBottomRightFromUpperLeft'.
cornersToArea :: Location -> Location -> AreaDimensions
cornersToArea upperLeft lowerRight =
cornersToArea upperLeft bottomRight =
AreaDimensions x y
where
V2 x y = (+ 1) <$> invertY (lowerRight .-. upperLeft)
V2 x y = (+ 1) <$> invertY (bottomRight .-. upperLeft)

-- | Has zero width or height.
isEmpty :: AreaDimensions -> Bool
Expand All @@ -71,3 +81,9 @@ getAreaDimensions cellGrid =

computeArea :: AreaDimensions -> Int32
computeArea (AreaDimensions w h) = w * h

fillGrid :: AreaDimensions -> a -> Grid a
fillGrid (AreaDimensions w h) =
Grid
. replicate (fromIntegral h)
. replicate (fromIntegral w)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Swarm.Game.Scenario.Topography.Area
import Swarm.Game.Scenario.Topography.Cell
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.WorldPalette
import Swarm.Language.Direction (AbsoluteDir)
import Swarm.Util (failT, showT)
Expand Down Expand Up @@ -60,7 +61,7 @@ instance FromJSONE (TerrainEntityMaps, RobotMap) (NamedArea (PStructure (Maybe C
..: "structure"

data PStructure c = Structure
{ area :: Grid c
{ area :: PositionedGrid c
, structures :: [NamedStructure c]
-- ^ structure definitions from parents shall be accessible by children
, placements :: [Placement]
Expand All @@ -84,7 +85,7 @@ instance HasLocation LocatedStructure where
modifyLoc f (LocatedStructure x y originalLoc) =
LocatedStructure x y $ f originalLoc

data MergedStructure c = MergedStructure (Grid c) [LocatedStructure] [Originated Waypoint]
data MergedStructure c = MergedStructure (PositionedGrid c) [LocatedStructure] [Originated Waypoint]

instance FromJSONE (TerrainEntityMaps, RobotMap) (PStructure (Maybe Cell)) where
parseJSONE = withObjectE "structure definition" $ \v -> do
Expand All @@ -98,7 +99,7 @@ instance FromJSONE (TerrainEntityMaps, RobotMap) (PStructure (Maybe Cell)) where
(maskedArea, mapWaypoints) <- (v .:? "map" .!= "") >>= paintMap maybeMaskChar pal
return $
Structure
(Grid maskedArea)
(PositionedGrid origin $ Grid maskedArea)
localStructureDefs
placementDefs
(waypointDefs <> mapWaypoints)
Expand Down
Loading

0 comments on commit 4632462

Please sign in to comment.