-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKarelExamples.hs
103 lines (89 loc) · 2.72 KB
/
KarelExamples.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
-- | 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 ]