Refactor handling of walls
Fixes #2 Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
c8e84da990
commit
2a30414ac8
1 changed files with 28 additions and 22 deletions
|
@ -66,33 +66,39 @@ isOnEdge (width, height) (x, y) dir = horizontally || vertically
|
||||||
horizontally = x == width && dir == East
|
horizontally = x == width && dir == East
|
||||||
vertically = y == height && dir == North
|
vertically = y == height && dir == North
|
||||||
|
|
||||||
|
getWalls :: Vector -> M.Map Vector (S.Set Direction) -> S.Set Direction
|
||||||
|
getWalls = M.findWithDefault S.empty
|
||||||
|
|
||||||
|
genericWallAt :: (Vector -> Direction -> World -> a) -> (World -> a) -> a -> Vector -> Direction -> World -> a
|
||||||
|
genericWallAt action edgeValue errorValue pos dir world
|
||||||
|
| not $ positionWithinWorld world pos = errorValue
|
||||||
|
| isOnEdge (worldDimensions world) position direction = edgeValue world
|
||||||
|
| otherwise = action position direction world
|
||||||
|
where (position, direction) = switchDirectionToInternal pos dir
|
||||||
|
|
||||||
addWallAt :: Vector -> Direction -> World -> World
|
addWallAt :: Vector -> Direction -> World -> World
|
||||||
addWallAt pos dir w
|
addWallAt = genericWallAt addWall id (error "Invalid position")
|
||||||
| not $ positionWithinWorld w newPosition = error "Invalid position"
|
|
||||||
| isOnEdge (worldDimensions w) newPosition newDirection = w
|
|
||||||
| otherwise = w {worldWalls = M.insert newPosition newWalls (worldWalls w)}
|
|
||||||
where
|
where
|
||||||
(newPosition, newDirection) = switchDirectionToInternal pos dir
|
addWall position direction world =
|
||||||
oldWalls = M.findWithDefault S.empty newPosition (worldWalls w)
|
world {worldWalls = M.insert position newWalls walls}
|
||||||
newWalls = S.union oldWalls $ S.singleton newDirection
|
where
|
||||||
|
walls = worldWalls world
|
||||||
|
newWalls = S.union (getWalls position walls) $ S.singleton direction
|
||||||
|
|
||||||
removeWallAt :: Vector -> Direction -> World -> World
|
removeWallAt :: Vector -> Direction -> World -> World
|
||||||
removeWallAt pos dir w
|
removeWallAt = genericWallAt removeWall id (error "Invalid position")
|
||||||
| not $ positionWithinWorld w newPosition = error "Invalid position"
|
|
||||||
| isOnEdge (worldDimensions w) newPosition newDirection = w
|
|
||||||
| S.null newWalls = w {worldWalls = M.delete newPosition (worldWalls w)}
|
|
||||||
| otherwise = w {worldWalls = M.insert newPosition newWalls (worldWalls w)}
|
|
||||||
where
|
where
|
||||||
(newPosition, newDirection) = switchDirectionToInternal pos dir
|
removeWall position direction world
|
||||||
oldWalls = M.findWithDefault S.empty newPosition (worldWalls w)
|
| S.null newWalls = world {worldWalls = M.delete position walls}
|
||||||
newWalls = oldWalls S.\\ S.singleton newDirection
|
| otherwise = world {worldWalls = M.insert position newWalls walls}
|
||||||
|
where
|
||||||
|
walls = worldWalls world
|
||||||
|
newWalls = getWalls position walls S.\\ S.singleton direction
|
||||||
|
|
||||||
hasWallAt :: Vector -> Direction -> World -> Bool
|
hasWallAt :: Vector -> Direction -> World -> Bool
|
||||||
hasWallAt pos dir w
|
hasWallAt = genericWallAt hasWall (const True) False
|
||||||
| not $ positionWithinWorld w newPosition = False
|
|
||||||
| isOnEdge (worldDimensions w) newPosition newDirection = True
|
|
||||||
| otherwise = case worldWalls w M.!? newPosition of
|
|
||||||
Just wallsInPlace -> S.member newDirection wallsInPlace
|
|
||||||
Nothing -> False
|
|
||||||
where
|
where
|
||||||
(newPosition, newDirection) = switchDirectionToInternal pos dir
|
hasWall position direction world =
|
||||||
|
case worldWalls world M.!? position of
|
||||||
|
Just wallsInPlace -> S.member direction wallsInPlace
|
||||||
|
Nothing -> False
|
||||||
|
|
Loading…
Reference in a new issue