-- | This module defines some example worlds and programs for testing -- your Karel interpreter. module KarelExamples where import Prelude hiding (Either(..)) import KarelSyntax import KarelState -- -- * Trivial worlds -- -- | A world that is all walls. wallWorld :: World wallWorld = const Nothing -- | A world that is completely empty of walls and beepers. emptyWorld :: World emptyWorld = const (Just 0) -- | A robot that starts at the origin, facing north, with the -- given number of beepers. originBot :: Int -> Robot originBot b = ((0,0),North,b) -- -- * Demo world -- -- | A 10x5 room with some beepers in a line, illustrated below. -- -- XXXXXXXXXXXX -- X X -- X X -- X X -- X @ 2 3 4 X -- X X -- XXXXXXXXXXXX -- -- The @ symbol is coordinate (1,1). -- Clear spaces are from (0,0) to (9,4). -- There are beepers at the following locations: -- * 2 beepers at (4,1) -- * 3 beepers at (6,1) -- * 4 beepers at (8,1) -- demoWorld :: World demoWorld (4,1) = Just 2 demoWorld (6,1) = Just 3 demoWorld (8,1) = Just 4 demoWorld (x,y) | x >= 0 && x < 10 && y >= 0 && y < 5 = Just 0 | otherwise = Nothing -- | An initial robot state for the demo world. The robot starts at -- (1,1), facing East, with 1 beeper in its bag. demoBot :: Robot demoBot = ((1,1),East,1) -- -- * Program generators -- -- | Generate a program that does the following n times: -- 1. moves in a straight line until it finds a beeper -- 2. picks it up -- 3. returns to its original position and facing. fetcher :: Int -> Prog fetcher n = ([("fetch",fetch)], main) where fetch = Block [ While (Not Beeper) -- do until we find a beeper: (If (Clear Front) -- can we move forward? Move -- if yes, then do it Shutdown) -- if not, shut down , PickBeeper ] main = Block [ Iterate n $ Block -- repeat n times: [ PutBeeper -- put a beeper down to mark our place , Move -- move forward one space , Call "fetch" -- go get a new beeper , Turn Back -- turn around , Move -- move forward one space , Call "fetch" -- go back to where we started , Turn Back ] -- turn back to our initial facing , Shutdown ] -- | Generates a statement that moves the robot in a rectangle of -- the given dimensions. rectangle :: Int -> Int -> Stmt rectangle w h = Block [ While (Not (Facing North)) (Turn Right) , Iterate h Move , Turn Right , Iterate w Move , Turn Right , Iterate h Move , Turn Right , Iterate w Move , Turn Right ]