haskell-karel/Internal/Karel.hs

75 lines
1.7 KiB
Haskell
Raw Normal View History

{-# LANGUAGE LambdaCase #-}
module Internal.Karel where
import Internal.Types
import Internal.World
data Karel = Karel
{ karelPosition :: Vector,
karelDirection :: Direction,
karelBeepers :: Int,
karelWorld :: World
}
deriving (Show, Eq)
stepVector :: Direction -> Vector
stepVector = \case
North -> (0, 1)
East -> (1, 0)
South -> (0, -1)
West -> (-1, 0)
leftTurn :: Direction -> Direction
leftTurn = \case
North -> West
West -> South
South -> East
East -> North
changeBeepers :: Int -> Karel -> Karel
changeBeepers db robot
| checkedCount <= 0 = error ("There are no beepers to " ++ msg)
| otherwise =
robot
{ karelBeepers = inBag + db,
karelWorld = setBeepersAt position (atPosition - db) world
}
where
(position, world) = (karelPosition robot, karelWorld robot)
inBag = karelBeepers robot
atPosition = getBeepersAt position world
(checkedCount, msg) =
if db == 1 then (atPosition, "pick up") else (inBag, "put down")
defaultKarel :: World -> Karel
defaultKarel world =
Karel
{ karelPosition = (1, 1),
karelDirection = East,
karelBeepers = 0,
karelWorld = world
}
initialPosition :: Vector -> Karel -> Karel
initialPosition pos robot
| not $ positionWithinWorld (karelWorld robot) pos = error "Invalid position"
| otherwise =
robot
{ karelPosition = pos
}
initialDirection :: Direction -> Karel -> Karel
initialDirection dir robot =
robot
{ karelDirection = dir
}
initialBeepersInBag :: Int -> Karel -> Karel
initialBeepersInBag beepers robot
| beepers < 0 = error "Invalid count of beepers"
| otherwise =
robot
{ karelBeepers = beepers
}