Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restyle structure grid expansion #1842

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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