diff options
author | Griffin Smith <grfn@gws.fyi> | 2021-11-06T17·20-0400 |
---|---|---|
committer | grfn <grfn@gws.fyi> | 2021-11-06T17·34+0000 |
commit | b68414c66b35cc54835db3d344c2eed01fbff7aa (patch) | |
tree | 92a93318e80354574a898235bdedf584e8b74a59 /users/grfn/xanthous/src/Xanthous/Generators/Level | |
parent | eeafd0fa0ed85957f0609863d1d06b570c55341b (diff) |
fix(gs/xanthous): Fix numAliveNeighbors{,M} on the edge r/3012
numAliveNeighbors was doing bounds checks too aggressively, resulting in always returning 8 for points on the edge, meaning walls weren't getting properly created for those points, making edges of the map open to walk through. Change-Id: Iada6be46ce7cc77ce99a320b7310008898b89273 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3805 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
Diffstat (limited to 'users/grfn/xanthous/src/Xanthous/Generators/Level')
-rw-r--r-- | users/grfn/xanthous/src/Xanthous/Generators/Level/Util.hs | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/users/grfn/xanthous/src/Xanthous/Generators/Level/Util.hs b/users/grfn/xanthous/src/Xanthous/Generators/Level/Util.hs index c64377817939..0008eb965c42 100644 --- a/users/grfn/xanthous/src/Xanthous/Generators/Level/Util.hs +++ b/users/grfn/xanthous/src/Xanthous/Generators/Level/Util.hs @@ -52,13 +52,18 @@ initializeEmpty :: RandomGen g => Dimensions -> CellM g s (MCells s) initializeEmpty dims = lift $ newArray (0, V2 (dims ^. width) (dims ^. height)) False +-- | Returns the number of neighbors of the given point in the given array that +-- are True. +-- +-- Behavior if point is out-of-bounds for the array is undefined, but will not +-- error numAliveNeighborsM :: forall a i m . (MArray a Bool m, Ix i, Integral i) => a (V2 i) Bool -> V2 i -> m Word -numAliveNeighborsM cells (V2 x y) = do +numAliveNeighborsM cells pt@(V2 x y) = do cellBounds <- getBounds cells getSum <$> foldlMapM' (fmap (Sum . fromIntegral . fromEnum) . boundedGet cellBounds) @@ -66,24 +71,32 @@ numAliveNeighborsM cells (V2 x y) = do where boundedGet :: (V2 i, V2 i) -> (Int, Int) -> m Bool + boundedGet bnds _ + | not (inRange bnds pt) + = pure True boundedGet (V2 minX minY, V2 maxX maxY) (i, j) - | x <= minX - || y <= minY - || x >= maxX - || y >= maxY + | (x <= minX && i < 0) + || (y <= minY && j < 0) + || (x >= maxX && i > 0) + || (y >= maxY && j > 0) = pure True | otherwise = let nx = fromIntegral $ fromIntegral x + i ny = fromIntegral $ fromIntegral y + j in readArray cells $ V2 nx ny +-- | Returns the number of neighbors of the given point in the given array that +-- are True. +-- +-- Behavior if point is out-of-bounds for the array is undefined, but will not +-- error numAliveNeighbors :: forall a i . (IArray a Bool, Ix i, Integral i) => a (V2 i) Bool -> V2 i -> Word -numAliveNeighbors cells (V2 x y) = +numAliveNeighbors cells pt@(V2 x y) = let cellBounds = bounds cells in getSum $ foldMap (Sum . fromIntegral . fromEnum . boundedGet cellBounds) @@ -91,11 +104,14 @@ numAliveNeighbors cells (V2 x y) = where boundedGet :: (V2 i, V2 i) -> (Int, Int) -> Bool + boundedGet bnds _ + | not (inRange bnds pt) + = True boundedGet (V2 minX minY, V2 maxX maxY) (i, j) - | x <= minX - || y <= minY - || x >= maxX - || y >= maxY + | (x <= minX && i < 0) + || (y <= minY && j < 0) + || (x >= maxX && i > 0) + || (y >= maxY && j > 0) = True | otherwise = let nx = fromIntegral $ fromIntegral x + i |