Refactor wall handling in prettyprint

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2020-11-15 13:28:11 +01:00
parent 66c91096ab
commit bd69dacb93
No known key found for this signature in database
GPG key ID: DE0CF444096A468D

View file

@ -15,6 +15,10 @@ data Karel = Karel
} }
deriving (Eq) deriving (Eq)
xor :: Bool -> Bool -> Bool
xor True a = not a
xor False a = a
getHeader :: Karel -> String getHeader :: Karel -> String
getHeader karel = unlines [ getHeader karel = unlines [
printf " %8s %s %s %s" "POSITION" "FACING" "BEEP-BAG" "BEEP-POS", printf " %8s %s %s %s" "POSITION" "FACING" "BEEP-BAG" "BEEP-POS",
@ -50,32 +54,27 @@ mapCell karel x y
| otherwise = " . " | otherwise = " . "
where beepersAt = getBeepersAt (x, y) $ karelWorld karel where beepersAt = getBeepersAt (x, y) $ karelWorld karel
mapWall :: Karel -> Int -> Int -> String mapWall :: Karel -> Int -> Int -> String
mapWall karel x y = leftPart <> rightPart mapWall karel x y = leftPart <> rightPart
where where
world = karelWorld karel world = karelWorld karel
(width, height) = worldDimensions world (northWall:eastWall:westWall:_) = map (\d -> hasWallAt (x, y) d world) [North, East, West]
wallAtNorth = hasWallAt (x, y) North world (northWallOnLeft:northWallOnRight:_) = map (\d -> hasWallAt (x + d, y) North world) [-1, 1]
vWallAbove = hasWallAt (x, y + 1) East world (eastWallAbove:westWallAbove:_) = map (\d -> hasWallAt (x, y + 1) d world) [East, West]
vWallBelow = hasWallAt (x, y - 1) East world verticalWall = eastWall && eastWallAbove
vWallAt = hasWallAt (x, y) East world wallEnds = northWall && not northWallOnRight
verticalWall = vWallAt && vWallAbove wallStarts = northWall && x > 1 && not northWallOnLeft
wallEnds = wallAtNorth && (not $ hasWallAt (x + 1, y) North world)
wallStarts = wallAtNorth && x > 1 && (not $ hasWallAt (x - 1, y) North world)
noVWall = not (hasWallAt (x, y) West world || hasWallAt (x, y + 1) West world)
leftPart leftPart
| wallStarts && noVWall = "+-" | wallStarts && not (westWall || westWallAbove) = "+-"
| wallAtNorth = "--" | northWall = "--"
| otherwise = " " | otherwise = " "
rightPart rightPart
| wallAtNorth && wallEnds && verticalWall = "-|" | northWall && wallEnds && verticalWall = "-|"
| wallEnds = "-+" | wallEnds || (northWall && eastWallAbove) = "-+"
| wallAtNorth && (vWallAbove) = "-+" | northWall = "--"
| wallAtNorth = "--" | (verticalWall && northWallOnRight) || (eastWall `xor` eastWallAbove) = " +"
| verticalWall && hasWallAt (x+1, y) North world = " +"
| verticalWall = " |" | verticalWall = " |"
| not vWallAbove && vWallAt = " +"
| not vWallAt && vWallAbove = " +"
| otherwise = " " | otherwise = " "
getRow :: Karel -> Int -> String getRow :: Karel -> Int -> String
@ -89,7 +88,7 @@ getRow karel row
mapWall karel column row mapWall karel column row
| column <- [1..width] | column <- [1..width]
] ]
line = (printf "%2d |" row) <> foldl1 (<>) [ line = printf "%2d |" row <> foldl1 (<>) [
position <> wall position <> wall
| column <- [1..width], | column <- [1..width],
let wall = if hasWallAt (column, row) East world then "|" else " ", let wall = if hasWallAt (column, row) East world then "|" else " ",