Skip to content

Commit

Permalink
Allow for empty cells in structure modification hook mask
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed Nov 13, 2023
1 parent ceb8fa2 commit e493875
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
1575-remove-structure.yaml
1575-swap-structure.yaml
1575-placement-occlusion.yaml
1575-interior-entity-placement.yaml
1575-floorplan-command.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
version: 1
name: Structure recognition - interior space
description: |
Entities can be added and removed
on empty cells within the rectangular
boundary of an already-placed structure without
affecting its recognition status.
Additionally, recognition of statically-placed
structures at scenario initialization is also
unaffected by interior entities.
However, any such "contaminating" entities
will prevent the recognition of a structure
when constructed by a robot.
creative: false
objectives:
- teaser: Replace rock
prerequisite: grab_rock
goal:
- |
Place the `rock`{=entity} entity back inside the `pigpen`{=structure}.
condition: |
foundBox <- structure "pigpen" 0;
case foundBox (\_. return false) (\struc.
let structPos = snd struc in
j <- robotnamed "judge";
as j {
structBounds <- floorplan "pigpen";
// Move to bottom-left corner
teleport self structPos;
rockCount <- resonate "rock" ((0, 0), structBounds);
return $ rockCount > 0;
}
);
- teaser: Grab rock
id: grab_rock
prerequisite: prerecognized
goal:
- |
Grab an entity from inside a `pigpen`{=structure} structure.
condition: |
as base {
has "rock";
}
- teaser: Prerecognize
id: prerecognized
goal:
- |
`pigpen`{=structure} structure should be recognized upon initialization,
even with an extraneous entity within its bounds.
condition: |
def isRight = \x. case x (\_. false) (\_. true); end;
foundBox <- structure "pigpen" 0;
return $ isRight foundBox;
robots:
- name: base
dir: [1, 0]
devices:
- ADT calculator
- blueprint
- grabber
- logger
- treads
- name: judge
dir: [1, 0]
system: true
display:
invisible: true
solution: |
move; move;
x <- grab;
move;
place x;
structures:
- name: pigpen
recognize: true
structure:
palette:
'b': [stone, board]
mask: '.'
map: |
bbbb
b..b
b..b
bbbb
known: [board, rock]
world:
dsl: |
{blank}
placements:
- src: pigpen
offset: [1, 0]
- src: pigpen
offset: [3, -6]
palette:
'.': [grass, erase]
'B': [grass, erase, base]
'r': [grass, rock]
'j': [grass, erase, judge]
upperleft: [-7, 3]
map: |
j.....
......
B.r...
......
......
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Data.Function (on)
import Data.Int (Int32)
import Data.List.NonEmpty qualified as NE
import Data.Map (Map)
import Data.Maybe (catMaybes)
import Data.Ord (Down (Down))
import Data.Semigroup (Max, Min)
import GHC.Generics (Generic)
Expand Down Expand Up @@ -211,8 +212,12 @@ instance Ord FoundStructure where
f1 = computeArea . getAreaDimensions . entityGrid . structureWithGrid
f2 = Down . upperLeftCorner

-- | Yields coordinates that are occupied by an entity of a placed structure.
-- Cells within the rectangular bounds of the structure that are unoccupied
-- are not included.
genOccupiedCoords :: FoundStructure -> [Cosmic Location]
genOccupiedCoords (FoundStructure swg loc) =
[loc `offsetBy` V2 x (negate y) | x <- [0 .. w - 1], y <- [0 .. h - 1]]
catMaybes . concat . zipWith mkRow [0 ..] $ entityGrid swg
where
AreaDimensions w h = getAreaDimensions $ entityGrid swg
mkCol y x ent = loc `offsetBy` V2 x (negate y) <$ ent
mkRow rowIdx = zipWith (mkCol rowIdx) [0 ..]
10 changes: 6 additions & 4 deletions src/Swarm/Game/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1321,10 +1321,12 @@ ensureStructureIntact (FoundStructure (StructureWithGrid _ grid) upperLeft) =
allM outer $ zip [0 ..] grid
where
outer (y, row) = allM (inner y) $ zip [0 ..] row
inner y (x, cell) =
fmap (== cell) $
entityAt $
upperLeft `offsetBy` V2 x (negate y)
inner y (x, maybeTemplateEntity) = case maybeTemplateEntity of
Nothing -> return True
Just _ ->
fmap (== maybeTemplateEntity) $
entityAt $
upperLeft `offsetBy` V2 x (negate y)

mkRecognizer ::
(Has (State GameState) sig m) =>
Expand Down
1 change: 1 addition & 0 deletions test/integration/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ testScenarioSolutions rs ui =
, testSolution Default "Testing/1575-structure-recognizer/1575-remove-structure"
, testSolution Default "Testing/1575-structure-recognizer/1575-swap-structure"
, testSolution Default "Testing/1575-structure-recognizer/1575-placement-occlusion"
, testSolution Default "Testing/1575-structure-recognizer/1575-interior-entity-placement"
, testSolution Default "Testing/1575-structure-recognizer/1575-floorplan-command"
]
]
Expand Down

0 comments on commit e493875

Please sign in to comment.