- Use internal modules for helper functions - Clean up API - Add `facing` to Karel and `notFacing` to SuperKarel - Rename functions for creating world and Karel Signed-off-by: Matej Focko <me@mfocko.xyz>
73 lines
1.6 KiB
Haskell
73 lines
1.6 KiB
Haskell
module Karel
|
|
( -- data types
|
|
Vector,
|
|
Direction (..),
|
|
Karel,
|
|
-- public interface
|
|
step,
|
|
turnLeft,
|
|
pickBeeper,
|
|
putBeeper,
|
|
frontIsClear,
|
|
beepersPresent,
|
|
facing,
|
|
facingNorth,
|
|
beepersInBag,
|
|
-- for creating world
|
|
worldWithDimensions,
|
|
setBeepersAt,
|
|
addWallAt,
|
|
removeWallAt,
|
|
-- for creating Karel
|
|
defaultKarel,
|
|
initialPosition,
|
|
initialDirection,
|
|
initialBeepersInBag,
|
|
)
|
|
where
|
|
|
|
import Internal.Karel
|
|
import Internal.Types
|
|
import Internal.World
|
|
|
|
step :: Karel -> Karel
|
|
step robot
|
|
| hasWallAt position' direction' (karelWorld robot) = error "Cannot pass through the wall"
|
|
| otherwise =
|
|
robot
|
|
{ karelPosition = (x + dx, y + dy)
|
|
}
|
|
where
|
|
position' = karelPosition robot
|
|
direction' = karelDirection robot
|
|
(x, y) = position'
|
|
(dx, dy) = stepVector direction'
|
|
|
|
turnLeft :: Karel -> Karel
|
|
turnLeft robot =
|
|
robot
|
|
{ karelDirection = leftTurn $ karelDirection robot
|
|
}
|
|
|
|
pickBeeper :: Karel -> Karel
|
|
pickBeeper = changeBeepers 1
|
|
|
|
putBeeper :: Karel -> Karel
|
|
putBeeper = changeBeepers (-1)
|
|
|
|
frontIsClear :: Karel -> Bool
|
|
frontIsClear robot = not $ hasWallAt pos dir wrld
|
|
where
|
|
(pos, dir, wrld) = (karelPosition robot, karelDirection robot, karelWorld robot)
|
|
|
|
beepersPresent :: Karel -> Bool
|
|
beepersPresent robot = (> 0) $ getBeepersAt (karelPosition robot) (karelWorld robot)
|
|
|
|
facing :: Direction -> Karel -> Bool
|
|
facing dir = (== dir) . karelDirection
|
|
|
|
facingNorth :: Karel -> Bool
|
|
facingNorth = facing North
|
|
|
|
beepersInBag :: Karel -> Bool
|
|
beepersInBag = (> 0) . karelBeepers
|