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