Skip to content

Commit

Permalink
add tests for placement offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed Sep 23, 2024
1 parent 99ab1ce commit edc8671
Show file tree
Hide file tree
Showing 10 changed files with 433 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
nonoverlapping-structure-merge.yaml
root-map-expansion.yaml
structure-composition.yaml
sequential-placement.yaml
sequential-placement.yaml
coordinate-offset-propagation.yaml
simultaneous-north-and-west-offset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
version: 1
name: Structure coordinate offset propagation
author: Karl Ostmo
description: |
If a structure incorporates subplacements
entailing negative offsets, its coordinate origin must be shifted.
The updated coordinate origin should be propagated to parent structures
and utilized to offset placement.
robots:
- name: base
dir: north
objectives:
- goal:
- Enjoy the view.
condition: |
return true
solution: |
noop
known: [boulder, log, pixel (R), pixel (G), pixel (B), gold]
world:
structures:
- name: micro
structure:
mask: '.'
palette:
'x': [stone, gold]
map: |
xx
- name: block
structure:
mask: '.'
palette:
'x': [stone, pixel (R)]
map: |
xx
xx
- name: master
structure:
mask: '.'
palette:
'x': [stone, pixel (B)]
placements:
- src: block
offset: [0, 1]
- src: micro
offset: [-2, 0]
map: |
..x
..x
..x
- name: final
structure:
mask: '.'
palette:
'x': [stone, pixel (G)]
placements:
- src: master
map: |
x
x
x
x
dsl: |
overlay
[ {grass}
, mask (y > -4 && y < 4 || x > -4 && x < 4) {stone}
, mask (y > -2 && y < 2 || x > -2 && x < 2) {ice}
, mask (y > -1 && y < 1 || x > -1 && x < 1) {dirt}
]
palette:
'Ω': [grass, erase, base]
mask: '.'
placements:
- src: final
offset: [0, 0]
upperleft: [0, 0]
map: |
Ω
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
version: 1
name: Northwest sibling structure coordinate offsets
author: Karl Ostmo
description: |
Make sure that the second sibling is displayed correctly when there
is a simultaneous negative-x and positive-y offset on the first sibling.
robots:
- name: base
dir: north
loc: [0, 2]
objectives:
- goal:
- Enjoy the view.
condition: |
return true
solution: |
noop
known: [pixel (R), gold]
world:
structures:
- name: micro
structure:
mask: '.'
palette:
'x': [stone, gold]
map: |
x
- name: block
structure:
mask: '.'
palette:
'x': [stone, pixel (R)]
map: |
xx
xx
- name: master
structure:
mask: '.'
placements:
- src: micro
offset: [-1, 1]
- src: block
map: ""
dsl: |
overlay
[ {grass}
, mask (y > -4 && y < 4 || x > -4 && x < 4) {stone}
, mask (y > -2 && y < 2 || x > -2 && x < 2) {ice}
, mask (y > -1 && y < 1 || x > -1 && x < 1) {dirt}
]
mask: '.'
placements:
- src: master
offset: [0, 0]
upperleft: [0, 0]
map: ""
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@ instance FromJSONE WorldParseDependencies WorldDescription where
let placedStructures =
map (offsetLoc $ coerce ul) staticStructurePlacements

-- Override upper-left corner with explicit location
let area = mergedGrid {gridPosition = ul}

let area = modifyLoc ((ul .+^) . asVector) mergedGrid
return $ WorldDescription {..}

------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/swarm-topography/Swarm/Game/Location.hs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ euclidean p1 p2 = norm (fromIntegral <$> (p2 .-. p1))

-- | Converts a 'Point' to a vector offset from the 'origin'.
asVector :: Location -> V2 Int32
asVector loc = loc .-. origin
asVector (P vec) = vec

-- | Get all the locations that are within a certain manhattan
-- distance from a given location.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ data AreaDimensions = AreaDimensions
{ rectWidth :: Int32
, rectHeight :: Int32
}
deriving (Show, Eq)

getGridDimensions :: Grid a -> AreaDimensions
getGridDimensions g = getAreaDimensions $ getRows g
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
-- as well as logic for combining them.
module Swarm.Game.Scenario.Topography.Structure.Assembly (
mergeStructures,

-- * Exposed for unit tests:
foldLayer,
)
where

Expand Down Expand Up @@ -63,30 +66,15 @@ mergeStructures ::
Parentage Placement ->
PStructure (Maybe a) ->
Either Text (MergedStructure (Maybe a))
mergeStructures inheritedStrucDefs parentPlacement (Structure origArea subStructures subPlacements subWaypoints) = do
mergeStructures inheritedStrucDefs parentPlacement baseStructure = do
overlays <-
left (elaboratePlacement parentPlacement <>) $
mapM (validatePlacement structureMap) subPlacements

let wrapPlacement (Placed z ns) =
LocatedStructure
(name ns)
(up $ orient structPose)
(offset structPose)
where
structPose = structurePose z

wrappedOverlays =
map wrapPlacement $
filter (\(Placed _ ns) -> isRecognizable ns) overlays

-- NOTE: Each successive overlay may alter the coordinate origin.
-- We make sure this new origin is propagated to subsequent sibling placements.
foldlM
(flip $ overlaySingleStructure structureMap)
(MergedStructure origArea wrappedOverlays originatedWaypoints)
overlays
foldLayer structureMap origArea overlays originatedWaypoints
where
Structure origArea subStructures subPlacements subWaypoints = baseStructure

originatedWaypoints = map (Originated parentPlacement) subWaypoints

-- deeper definitions override the outer (toplevel) ones
Expand All @@ -95,6 +83,32 @@ mergeStructures inheritedStrucDefs parentPlacement (Structure origArea subStruct
(M.fromList $ map (name &&& id) subStructures)
inheritedStrucDefs

-- | NOTE: Each successive overlay may alter the coordinate origin.
-- We make sure this new origin is propagated to subsequent sibling placements.
foldLayer ::
M.Map StructureName (NamedStructure (Maybe a)) ->
PositionedGrid (Maybe a) ->
[Placed (Maybe a)] ->
[Originated Waypoint] ->
Either Text (MergedStructure (Maybe a))
foldLayer structureMap origArea overlays originatedWaypoints =
foldlM
(flip $ overlaySingleStructure structureMap)
(MergedStructure origArea wrappedOverlays originatedWaypoints)
overlays
where
wrappedOverlays =
map wrapPlacement $
filter (\(Placed _ ns) -> isRecognizable ns) overlays

wrapPlacement (Placed z ns) =
LocatedStructure
(name ns)
(up $ orient structPose)
(offset structPose)
where
structPose = structurePose z

-- * Grid manipulation

overlayGridExpanded ::
Expand All @@ -105,14 +119,13 @@ overlayGridExpanded ::
overlayGridExpanded
baseGrid
(Pose yamlPlacementOffset orientation)
-- NOTE: The '_childAdjustedOrigin' is the sum of origin adjustments
-- to completely assemble some substructure. However, we discard
-- this when we place a substructure into a new base grid.
(PositionedGrid _childAdjustedOrigin overlayArea) =
-- The 'childAdjustedOrigin' is the sum of origin adjustments
-- to completely assemble some substructure.
(PositionedGrid childAdjustedOrigin overlayArea) =
baseGrid <> positionedOverlay
where
reorientedOverlayCells = applyOrientationTransform orientation overlayArea
placementAdjustedByOrigin = gridPosition baseGrid .+^ asVector yamlPlacementOffset
placementAdjustedByOrigin = childAdjustedOrigin .+^ asVector yamlPlacementOffset
positionedOverlay = PositionedGrid placementAdjustedByOrigin reorientedOverlayCells

-- * Validation
Expand Down
Loading

0 comments on commit edc8671

Please sign in to comment.