-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBrisbinStreet.hs
1384 lines (1327 loc) · 63.2 KB
/
BrisbinStreet.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
module BrisbinStreet (buildWorld) where
import Defs
import Things
import Categories
import Score
import Actions
import Verbs
import GameMap
import Control.Monad
import Data.Maybe
buildWorld :: Game ()
buildWorld = do
brisbin <- newRoom "Brisbin Street" $
"You are in the middle of Brisbin Street. The street continues to the " ++
"west and east. To the north is Granny\'s House, and to the south is " ++
"Nick\'s house."
mapRoom brisbin 1 (4,3)
setArticle brisbin ""
player <- newPlayer "yourself" $
"You are an eight year old boy with blond hair, " ++
"wearing jeans, a t-shirt, and tennis shoes with tube socks."
move player brisbin
addAliases player ["you", "self", "me", "myself", "i"]
setArticle player ""
backpack <- newObject player "backpack" "A blue canvas backpack."
makeContainer backpack
mathBook <- newObject backpack "math book" $
"A second grade math textbook."
setDescription2 mathBook "You might learn something if you read it."
setVerb1 "read" mathBook $ do
msg $ "You read some second grade math and feel smarter about carrying " ++
"and borrowing."
addPoints 5 "learning something"
setDescription2 mathBook ""
setVerb1 "read" mathBook $ stop "You\'ve already read that."
frontYard <- newRoom "Granny\'s front yard" $
"The grass has many holes in it where squirrels have been " ++
"digging. There is a concrete path connecting the street to the south " ++
"and the driveway to the northwest. Granny\'s house is north and the " ++
"side yard is northeast. There are a pine tree and two white oak trees " ++
"in the yard. A squirrel watches you nervously from one of the oak trees."
mapRoom frontYard 1 (4,5)
setArticle frontYard ""
newExit "north" brisbin frontYard
newExit "south" frontYard brisbin
acorns <- newObject frontYard "acorns" $
"Ordinary white oak acorns. Could you throw them at a squirrel?"
addAliases acorns ["acorn", "acorns", "an acorn"]
setVerb1 "eat" acorns $
msg $ "You try one, but they taste terribly bitter. Maybe a squirrel " ++
"would like them if you threw them at it?"
setVerb1 "use" acorns $ msg "Do you want to throw the acorns?"
squirrel <- newObject frontYard "squirrel" $
"A common grey squirrel. She is high up in one of the oak trees in " ++
"the yard. She looks at you as if she is expecting something."
makeCreature squirrel
let highInTree = msg "The squirrel is high up in a tree."
setVerb1 "get" squirrel highInTree
setVerb1 "pet" squirrel highInTree
let throwAcorns finalAction = \target -> do
room <- getRoom
unless (room == frontYard) $ stop "You don\'t see any squirrels here."
targetName <- qualifiedName target
unless (target == squirrel) $ stop $
"There is no point in throwing an acorn at " ++ targetName ++ "."
finalAction
firstThrow = do
msg $ "You throw an acorn at the squirrel. She catches the acorn, " ++
"runs up the tree, and eats the acorn hungrily."
addPoints 10 "improving your aim"
setVerb2 "throw" acorns "at" $ throwAcorns subsequentThrow
subsequentThrow = msg "The squirrel catches the acorn and eats it."
setVerb2 "throw" acorns "at" $ throwAcorns firstThrow
living <- newRoom "living room" $
"This is clearly the living room of Granny\'s House. The floor has " ++
"plain brown carpet. There are a tan sofa and two rust colored " ++
"armchairs, and a spindly palm tree sits in the corner next to a " ++
"display case. To the south is Granny\'s front door, which goes back " ++
"to the front yard."
mapRoom living 2 (5,1)
enterHouse <- newExit "north" frontYard living
exitHouse <- newExit "south" living frontYard
frontDoorKey <- newObject living "front door key"
"This looks like the key to Granny\'s front door."
makeLocked enterHouse frontDoorKey
beforeGo exitHouse $ do
isLocked <- getIsLocked enterHouse
when isLocked $ do
msg "You unlock the front door before exiting."
setIsLocked enterHouse False
setDescription2 living "It\'s hot and muggy in here."
airConditioner <- newObject living "air conditioner" $
"You see a beefy, 240 volt window unit air conditioner. It has plastic " ++
"paneling that is made to look like wood."
makeImmobile airConditioner
addAliases airConditioner ["air", "conditioner", "ac"]
setDescription2 airConditioner
"It sure would be nice if you could turn it on."
let acFails = msg $ "You press the on button, but nothing happens. " ++
"The power must be off at the breaker."
let acWorks = do
msg $ "You turn on the air conditioner, and it starts up with a " ++
"noisy hum. Cold air blows into the room, and it feels much " ++
"better in here."
addPoints 5 "becoming an HVAC specialist"
let acAlreadyOn = stop "The air conditioner is already running."
setVerb1 "use" airConditioner acAlreadyOn
setVerb1 "turn on" airConditioner acAlreadyOn
setVerb1 "turn off" airConditioner $ stop $
"You don\'t want to turn it off. It would get hot and muggy again."
setDescription2 living "It feels cool and pleasant in here."
let acDesc2On = "The unit hums noisily as it runs."
acCyclesOn = do
room <- getRoom
when (room == living) $ msg $ "The air conditioner cycles on. " ++
acDesc2On
setDescription2 airConditioner acDesc2On
queueAction 4 acCyclesOff
acCyclesOff = do
room <- getRoom
when (room == living) $ msg $ "The air conditioner cycles " ++
"off. It is suddenly quiet."
setDescription2 airConditioner ""
queueAction 4 acCyclesOn
setDescription2 airConditioner acDesc2On
queueAction 5 acCyclesOff
setVerb1 "use" airConditioner acFails
setVerb1 "turn on" airConditioner acFails
setVerb1 "turn off" airConditioner $
stop "The air conditioner isn\'t running."
dinette <- newRoom "dinette" $
"This is a tiny dining room, most of which is taken up by a normal " ++
"sized table. It has a plastic veneer which imitates a light brown " ++
"wood pattern. Four chairs with dark brown plastic seats and backs " ++
"surround the table, and the floor is a brown tile with a swirly " ++
"pattern."
mapRoom dinette 2 (3,1)
newExit "west" living dinette
newExit "east" dinette living
newspaper <- newObject dinette "newspaper" $
"This is today\'s issue of the Minneapolis Star and Tribune."
setVerb1 "read" newspaper $ msg $
"You read the sports section. It\'s all about " ++
"how the Minnesota Twins won the 1987 World Series."
candle <- newObject dinette "candle" "A plain red candle."
setDescription2 candle "It is not lit."
kitchen <- newRoom "kitchen" $
"This is a small but functional kitchen. There is a fridge in the " ++
"corner with an ancient AM/FM radio on top of it. Dark brown cupboards " ++
"go along the west and south walls. There is a gas stove with an oven " ++
"and broiler, a double sink, and a dishwasher. Next to the sink is a " ++
"ceramic fish for holding Brillo pads, and on the cupboard is a fruit " ++
"bowl. To the west is Granny\'s side door, which goes to the driveway."
mapRoom kitchen 2 (1,1)
newExit "west" dinette kitchen
newExit "east" kitchen dinette
stove <- newObject kitchen "stove" $
"A vintage gas stove with one non-functional burner. Even the oven " ++
"is gas."
makeImmobile stove
let useStove = msg $ "You turn on a burner, and it lights from the pilot " ++
"light. You let it burn for a little bit, then, having nothing to " ++
"cook, turn it off."
setVerb1 "use" stove useStove
setVerb1 "light" stove useStove
setVerb1 "turn on" stove useStove
setVerb1 "turn off" stove $ stop "The stove is already off."
setVerb2 "light" stove "with" $ \_ -> stop "The stove has a pilot light."
matches <- newObject kitchen "matches" "A simple book of paper matches."
addAlias matches "match"
setVerb1 "use" matches $
msg $ "Instead of using the matches, please use the thing you\'re " ++
"trying to light."
setVerb1 "light" matches $
msg $ "You light a match and watch as it burns down towards your " ++
"fingers. You blow out the match and throw it away."
apple <- newObject kitchen "apple" "A red delicious apple."
setVerb1 "eat" apple $ do
msg "The apple tastes sweet and slightly astringent."
moveNowhere apple
addPoints 5 "tasting an apple"
banana <- newObject kitchen "banana" "The bottom half of a banana."
setVerb1 "eat" banana $ do
msg "The half banana tastes great and is surprisingly filling."
moveNowhere banana
addPoints 5 "finishing a banana"
orange <- newObject kitchen "orange" "A large seedless navel orange."
setVerb1 "eat" orange $ msg "Oranges don\'t agree with you."
let useCandleAction = do
maybeCandleLoc <- getLocation candle
room <- getRoom
unless (maybeCandleLoc == Just room) $ stop
"You should drop the candle before lighting it."
maybeMatchesLoc <- getLocation matches
unless (maybeMatchesLoc == Just player) $ stop
"You\'re not carrying anything to light the candle with."
msg "You light the candle and it burns brightly."
addPoints 10 "leveling up your pyromaniac skills"
let alreadyLit = stop "The candle is already lit."
setVerb1 "use" candle alreadyLit
setVerb1 "light" candle alreadyLit
setVerb2 "light" candle "with" $ \_ -> alreadyLit
setDescription2 candle "It is burning brightly."
setVerb2 "put" candle "in" $ \container -> do
containerName <- qualifiedName container
stop $ "It wouldn\'t be safe to put a lit candle in "
++ containerName ++ "."
setVerb1 "use" candle useCandleAction
setVerb1 "light" candle useCandleAction
setVerb2 "light" candle "with" $ \lighter -> do
unless (lighter == matches) $ do
lighterName <- qualifiedName lighter
stop $ "You can\'t light the candle with " ++ lighterName ++ "."
matchesLoc <- getLocation matches
unless (matchesLoc == Just player) $ stop
"You need to be holding the matches."
useCandleAction
hallway <- newRoom "hallway" $
"This simple east-west hallway has a tiny five watt light fixture on " ++
"the ceiling. There is a wicker hamper which, on inspection, appears " ++
"to contain a stack of clean placemats."
mapRoom hallway 2 (5,3)
newExit "south" hallway living
newExit "north" living hallway
masterBedroom <- newRoom "master bedroom" $
"Someone has clearly spend some money filling this bedroom with nice " ++
"furniture. There are a desk, a highboy dresser, another long dresser, " ++
"and a queen size bed with a flower-print bedspread. A touch tone " ++
"phone sits on the bedside stand."
mapRoom masterBedroom 2 (3,3)
newExit "east" masterBedroom hallway
newExit "west" hallway masterBedroom
{-flashlight <- newObject masterBedroom "flashlight" $
"A chrome-plated flashlight with a red switch and a red shade around " ++
"the light."
let --flashlightOnDesc = "The flashlight is on."
flashlightOffDesc = "The flashlight is off."
setDescription2 flashlight flashlightOffDesc-}
basementKey <- newObject masterBedroom "basement key" $
"This is an ordinery-looking key that opens the basement. Type \"unlock " ++
"down with the basement key\" to use it."
childBedroom <- newRoom "child\'s bedroom" $
"This bedroom clearly belongs to a young boy. There " ++
"are toys strewn about the floor, and a half-empty toybox is against " ++
"the west wall. There are three moderately-sized dressers, and a " ++
"large bookcase sits atop the biggest one. A twin bed is in the corner."
mapRoom childBedroom 2 (7,3)
newExit "west" childBedroom hallway
newExit "east" hallway childBedroom
dollhouse <- newObject childBedroom "Gabby\'s dollhouse" $
"This dollhouse is pink and blue, and looks like a giant cat. There " ++
"are three floors connected by an elevator, with one room on each side " ++
"of the elevator on each floor. Everything inside the dollhouse looks " ++
"like a cartoon. Try \"use the dollhouse\" to enter or exit the dollhouse."
makeContainer dollhouse
setArticle dollhouse ""
addAliases dollhouse ["dollhouse", "the dollhouse"]
gabby <- newObject childBedroom "Gabby" $
"This is a Gabby doll. It looks like she wants to be in her dollhouse."
setArticle gabby ""
addAliases gabby ["doll", "the doll"]
makeCreature gabby
setGuard1 "use" dollhouse $ do
let verb = "use"
stopIfPlayer verb dollhouse
stopIfExit verb dollhouse
stopIfInOpenContainer verb dollhouse
setVerb1 "use" dollhouse $ do
playerLoc <- getRoom
maybeDollhouseLoc <- getLocation dollhouse
let failUseDollhouse = stop $ "Something has gone wrong. You can\'t " ++
"use the dollhouse now."
when (maybeDollhouseLoc == Nothing) failUseDollhouse
let dollhouseLoc = fromJust maybeDollhouseLoc
when (dollhouseLoc == player) $ stop "Please drop the dollhouse first."
if playerLoc == dollhouse then do
msg "You exit the dollhouse. Everything looks normal again."
move player dollhouseLoc
doVerb $ Verb0 "look"
else if playerLoc == dollhouseLoc then do
msg $ "You enter the dollhouse. Everything looks like a cartoon " ++
"in here."
move player dollhouse
doVerb $ Verb0 "look"
else failUseDollhouse
let goInDollhouse = do
msg $ "Gabby turns into her cartoon self and looks very happy to be " ++
"in her dollhouse!"
addPoints 10 "returning Gabby to her home"
clearVerb1 "drop" gabby
clearVerb2 "put" gabby "in"
setDescription gabby
"This is cartoon Gabby. She likes being in her dollhouse."
defaultDropGabby <- getVerb1 "drop" gabby
setVerb1 "drop" gabby $ do
defaultDropGabby
maybeGabbyLoc <- getLocation gabby
when (maybeGabbyLoc == Just dollhouse) goInDollhouse
defaultPutGabbyIn <- getVerb2 "put" gabby "in"
setVerb2 "put" gabby "in" $ (\container -> do
defaultPutGabbyIn container
when (container == dollhouse) goInDollhouse)
bathroom <- newRoom "bathroom" $
"This is a small but servicable bathroom. The counter is a pale " ++
"yellow, with a plain white sink inset into it. There are built in " ++
"cupboards " ++
"below the counter, and a cupboard door stands wide open to allow heat " ++
"into the bathroom from a vent enclosed by the cabinetry."
mapRoom bathroom 2 (5,5)
newExit "north" hallway bathroom
newExit "south" bathroom hallway
perfume <- newObject bathroom "perfume" $
"A collection of tiny vials of perfume, probably collected from store " ++
"samples."
setVerb1 "use" perfume $ do
msg "You wipe perfume on your neck. You smell like perfume now..."
bathtub <- newObject bathroom "bathtub" $
"This is a plain white bathtub with a shower attachment and glass " ++
"doors."
addAlias bathtub "tub"
setDescription2 bathtub "Type \"fill the bathtub\" to fill it with water."
makeImmobile bathtub
makeContainer bathtub
basementLanding <- newRoom "basement landing" $
"The stairway, and the floor of this entire level, is a thin green " ++
"carpet. There are several rooms connected to the landing: a dining " ++
"room to the west, an unfinished laundry room to the south, a bathroom " ++
"to the north, and a bedroom to the east."
mapRoom basementLanding 3 (2,2)
basementEntrance <- newExit "down" kitchen basementLanding
addAliases basementEntrance ["door", "the door"]
makeLocked basementEntrance basementKey
newExit "up" basementLanding kitchen
basementShortcut <- newExit "shortcut to Granny\'s basement" brisbin
basementLanding
addAlias basementShortcut "b"
laundryRoom <- newRoom "laundry room" $
"This room used to double as a kitchen. There are a gas stove and a " ++
"refrigerator along the west wall, and cupboards and a kitchen sink " ++
"against the east wall. The floor and exterior walls are exposed " ++
"concrete, and the interior walls are covered in thin cheap paneling. " ++
"There is a tremendous amount of clutter in the middle of the room, " ++
"with a narrow path going back to the washer and dryer."
mapRoom laundryRoom 3 (2,0)
setDescription2 laundryRoom "You might find something if you search."
newExit "south" basementLanding laundryRoom
newExit "north" laundryRoom basementLanding
laundryDesk <- newObject laundryRoom "old desk" $
"This is a disused desk with drawers on the right hand side."
addAlias laundryDesk "desk"
makeImmobile laundryDesk
makeContainer laundryDesk
upstairsKey <- newObject laundryDesk "upstairs key" $
"This is an ordinary looking key to the upstairs level of Granny\'s House."
moveNowhere upstairsKey
setVerb1 "search" laundryRoom $ msg $
"You look everywhere in the laundry room, but don\'t find anything. " ++
"Maybe there is something in the old desk?"
setVerb1 "search" laundryDesk $ do
msg "You find something in the desk."
move upstairsKey laundryDesk
setDescription2 laundryRoom ""
clearVerb1 "search" laundryRoom
clearVerb1 "search" laundryDesk
diningRoom <- newRoom "dining room" $
"This small room is nearly filled with a huge round oaken table. " ++
"There are six large padded wooden chairs surrounding it. This must " ++
"be where Granny and her family share meals on special occasions. A " ++
"cabinet holds Granny\'s fine china. There " ++
"is an ironing board and an iron near the entrance, and a circuit " ++
"breaker box in the far corner in a wooden cabinet."
mapRoom diningRoom 3 (0,2)
newExit "west" basementLanding diningRoom
newExit "east" diningRoom basementLanding
circuitBreakerBox <- newObject diningRoom "circuit breaker box" $
"This is an ordinary circuit breaker box with 100 Amp service."
addAliases circuitBreakerBox
["circuit breaker", "circuit breakers", "breaker box", "breaker",
"breakers", "box"]
makeImmobile circuitBreakerBox
setDescription2 circuitBreakerBox $
"One of the breakers is in the off position. It is labeled \"Air " ++
"Conditioner\". Type \"turn on the breaker\" to turn it on."
let resetBreaker = do
msg "You flip the breaker labeled \"Air Conditioner\" to on."
addPoints 5 "being an electrician"
let goodBreakers = "All of the breakers are in the on position."
setDescription2 circuitBreakerBox goodBreakers
setVerb1 "use" circuitBreakerBox $ stop goodBreakers
setVerb1 "turn on" circuitBreakerBox $ stop goodBreakers
setVerb1 "use" airConditioner acWorks
setVerb1 "turn on" airConditioner acWorks
setVerb1 "use" circuitBreakerBox resetBreaker
setVerb1 "turn on" circuitBreakerBox resetBreaker
setVerb1 "turn off" circuitBreakerBox $ stop
"You shouldn\'t pointlessly monkey around with circuit breakers."
basementBedroom <- newRoom "basement bedroom" $
"This bedroom has a huge king-size bed and a very old vacuum tube " ++
"television that sits directly on the floor. Granny\'s nightstand " ++
"sits by the bed. There is a tan recliner facing the TV."
mapRoom basementBedroom 3 (4,2)
newExit "east" basementLanding basementBedroom
newExit "west" basementBedroom basementLanding
nightstand <- newObject basementBedroom "nightstand" $
"This is a fancy-looking nightstand with an old school clock radio, " ++
"some moisturizer, and two large drawers."
addAlias nightstand "stand"
makeImmobile nightstand
makeContainer nightstand
magnifyingGlass <- newObject nightstand "magnifying glass" $
"This is a rectangular magnifying glass with a metal handle, of a type " ++
"that hasn\'t been made in decades. It looks big enough that it would " ++
"concentrate the sun and burn things very well. Type \"use the " ++
"magnifying glass\" to use it."
addAlias magnifyingGlass "glass"
basementBar <- newRoom "bar" $
"This area is half filled with a large wet bar. The bar is quite wide, " ++
"and has a light colored wood pattern on its plastic top; the sides " ++
"are dark wood. There are three tall bar chairs with black padded " ++
"backs and seats, and two armchairs along the opposite wall. The bar " ++
"has a small incandescent light on the far wall."
mapRoom basementBar 3 (4,4)
newExit "north" basementBedroom basementBar
newExit "south" basementBar basementBedroom
spirits <- newObject basementBar "spirits" $
"Behind the bar are numerous bottles of whiskey and other spirits, " ++
"all capped with pour spouts."
addAliases spirits ["alcohol", "whiskey", "booze", "liquor"]
setVerb1 "get" spirits $ msg $ "As you are underage, you don't think " ++
"you should be walking around with opened liquor bottles."
setVerb1 "drink" spirits $ msg $ "An eight year old boy such as yourself " ++
"should not be drinking booze."
barLight <- newObject basementBar "light" $ "This is a small round light " ++
"mounted on the far wall. The word BAR is on its globe in large, ornate " ++
"capital letters."
addAlias barLight "bar light"
makeImmobile barLight
let lightOffDesc = "The light is currently off."
lightOnDesc = "Light shines from the globe, illuminating the area."
let lightOn = do
msg "You turn the bar light on."
setDescription2 barLight lightOnDesc
setVerb1 "use" barLight lightOff
setVerb1 "turn on" barLight lightAlreadyOn
setVerb1 "turn off" barLight lightOff
lightAlreadyOn = stop "The bar light is already on."
lightOff = do
msg "You turn the bar light off."
setDescription2 barLight lightOffDesc
setVerb1 "use" barLight lightOn
setVerb1 "turn on" barLight lightOn
setVerb1 "turn off" barLight lightAlreadyOff
lightAlreadyOff = stop "The bar light is already off."
setDescription2 barLight lightOffDesc
setVerb1 "use" barLight lightOn
setVerb1 "turn on" barLight lightOn
setVerb1 "turn off" barLight lightAlreadyOff
basementBathroom <- newRoom "bathroom" $
"This is a full bathroom, with a large counter and vanity with three " ++
"mirrors and two cabinets, a toilet, and " ++
"a shower stall with small green square tile. There is a little round " ++
"light in the ceiling just outside the shower stall."
mapRoom basementBathroom 3 (2,4)
newExit "north" basementLanding basementBathroom
newExit "south" basementBathroom basementLanding
newExit "east" basementBathroom basementBar
newExit "west" basementBar basementBathroom
note <- newObject basementBathroom "note" $
"This helpful note lists ways to earn points in this game. Reading it " ++
"is cheating a little bit!"
setVerb1 "read" note $ do
msg "Ways to Earn Points:"
msg "1. Learn some math"
msg "2. Pet a bunny"
msg "3. Water the grass"
msg "4. Feed the squirrel"
msg "5. Eat something"
msg "6. Become a pyromaniac"
msg "7. Help a doll"
msg "8. Become an exterminator"
msg "9. Cool the house"
msg "10. Play with a toy"
msg "11. Play a game of hide and seek"
msg $ "Finally, you must solve the mystery of the Haunted House."
upstairs <- newRoom "Upstairs" $
"This finished room spans the whole east-west length of Granny\'s " ++
"house. There are windows at each end, and a door to the south. The " ++
"room is used for storage. There are many large pieces of furniture " ++
"and boxes filling up most of the space, with only narrow paths to " ++
"walk along."
mapRoom upstairs 4 (0,2)
toUpstairs <- newExit "up" living upstairs
newExit "down" upstairs living
addAliases toUpstairs ["door", "the door"]
makeLocked toUpstairs upstairsKey
attic <- newRoom "Attic" $
"This room is unfinished, with studs and insulation visible. There is " ++
"one small light bulb with a chain switch. Several dressers and chests " ++
"of drawers fill the space, and there is a disused Capsella set on one " ++
"of the pieces of furniture."
mapRoom attic 4 (0,0)
newExit "south" upstairs attic
newExit "north" attic upstairs
capsellaSet <- newObject attic "Capsella set" $
"This modular toy consists of a large number of clear plastic spheres " ++
"with connectors. Each sphere has a motor, gears, or a mechanism inside " ++
"it."
setDescription2 capsellaSet $
"You can make a toy out of the capsella set by typing \"use the " ++
"Capsella set\"."
addAlias capsellaSet "set"
setVerb1 "get" capsellaSet $ stop $ "The Capsella set is too big to carry " ++
"around."
capsellaToy <- newObject attic "Capsella toy" $
"This elaborate toy has a battery pack, switch, motor, gears, and " ++
"propeller. There are four big yellow orbs which are intended as " ++
"flotation devices. This would work well in a bathtub full of water. " ++
"Type \"play with the Capsella toy\" to make it go!"
addAlias capsellaToy "toy"
moveNowhere capsellaToy
setVerb1 "use" capsellaSet $ do
msg $ "Following the instruction book, you put together pieces until " ++
"you\'ve made a Capsella toy. Look at the toy for more details."
addPoints 5 "creating something cool"
setVerb1 "use" capsellaSet $ msg $ "There aren\'t enough parts left in " ++
"the Capsella set to make another creation."
move capsellaToy attic
setDescription2 capsellaSet ""
let fillBathtub = do
msg "You fill the bathtub with water."
addPoints 5 "becoming a hydrologist"
setDescription2 bathtub "It is full of warm water."
let alreadyFull = msg "The bathtub is already full of water."
setVerb1 "fill" bathtub alreadyFull
setVerb1 "use" bathtub alreadyFull
setVerb1 "play with" capsellaToy toySwimsFirstTime
setVerb1 "turn on" capsellaToy toySwimsFirstTime
setVerb1 "use" capsellaToy toySwimsFirstTime
noWater = stop "You\'ll have to put the Capsella toy in water first."
toySwims = do
toyLoc <- getLocation capsellaToy
unless (toyLoc == Just bathtub) noWater
msg $ "You turn on the switch on the Capsella toy. Its motor starts " ++
"up, and the propeller turns. The toy zooms through the water " ++
"and gently bonks against the end of the bathtub."
toySwimsFirstTime = do
toySwims
addPoints 10 "being a true eight year-old"
setVerb1 "play with" capsellaToy toySwims
setVerb1 "turn on" capsellaToy toySwims
setVerb1 "use" capsellaToy toySwims
capsellaGuard = stopIfNotObject "play with" capsellaToy
setVerb1 "fill" bathtub fillBathtub
setVerb1 "use" bathtub fillBathtub
setVerb1 "play with" capsellaToy noWater
setVerb1 "turn on" capsellaToy noWater
setVerb1 "use" capsellaToy noWater
setGuard1 "play with" capsellaToy capsellaGuard
setGuard1 "turn on" capsellaToy capsellaGuard
setGuard1 "use" capsellaToy capsellaGuard
atticShortcut <- newExit "shortcut to Granny\'s attic" brisbin attic
addAlias atticShortcut "a"
driveway <- newRoom "driveway" $
"A concrete driveway extends along the west side of Granny\'s House. " ++
"Granny\'s side door is to the east. The front yard is to the " ++
"southeast and the backyard is to the northeast. The garage is north."
mapRoom driveway 1 (2,7)
setDescription2 driveway $
"There are a great many small brown and medium black ants coming " ++
"and going out of anthills along the driveway. You wish you had a " ++
"magnifying glass to use on the ants."
ants <- newObject driveway "ants" $
"You wish you could kill all these ants somehow."
makeCreature ants
makeImmobile ants
newExit "east" driveway kitchen
newExit "west" kitchen driveway
newExit "southeast" driveway frontYard
newExit "northwest" frontYard driveway
let noUseGlass = stop
"There isn\'t anything to burn with the sun around here."
burnAnts = do
msg "You burn ant after ant with the sun, killing many of them."
addPoints 10 "being an exterminator"
setVerb1 "use" magnifyingGlass noUseGlass
setVerb2 "burn" ants "with" $ \tool -> do
checkTool tool
stop "The ants are already mostly dead."
setVerb2 "use" magnifyingGlass "on" $ \victim -> do
checkVictim victim
stop "The ants are already mostly dead."
setDescription2 driveway $
"There are a great many dead and burned ants littering the " ++
"concrete driveway. You smile at your deed."
setDescription ants $
"The ants are mostly dead, especially the medium black ones. " ++
"There are still some small brown ones running around."
checkTool tool = do
unless (tool == magnifyingGlass) $ do
toolName <- qualifiedName tool
stop $ "You can\'t burn the ants with " ++ toolName ++ "."
checkVictim victim = do
unless (victim == ants) $ do
victimName <- qualifiedName victim
stop $ "You can\'t (or shouldn\'t) burn " ++ victimName ++
"with the magnifying glass."
setVerb1 "use" magnifyingGlass $ do
room <- getRoom
unless (room == driveway) noUseGlass
burnAnts
setVerb2 "burn" ants "with" $ \tool -> do
checkTool tool
burnAnts
setVerb2 "use" magnifyingGlass "on" $ \victim -> do
checkVictim victim
burnAnts
garage <- newRoom "garage" $
"Two cars are squeezed into this garage: a 1970s era yellow " ++
"Oldsmobile, and a very old green car with patched rust spots all over " ++
"its body. There is a side door going to the back yard to the east."
mapRoom garage 1 (2,9)
newExit "north" driveway garage
newExit "south" garage driveway
sprinkler <- newObject garage "sprinkler" $
"This sprinkler spins around fast when used."
bigWheel <- newObject garage "big wheel" $
"This is a classic Big Wheel trike from the 1970s. It\'s made from " ++
"blue and black plastic adorned with Batman logos, with a 16 inch " ++
"front wheel and a hand brake, presumably to facilitate intentional " ++
"spin outs."
setVerb1 "get" bigWheel $ msg "The big wheel is too big to carry around."
backyard <- newRoom "backyard" $
"This is the largest part of Granny\'s yard. There are numerous shrubs " ++
"along the property line to the east, an empty sandbox near the house " ++
"to the south, a small garden with moss roses in the middle of the " ++
"yard, and lilacs are planted next to the garage. Behind the garage " ++
"are some disused laundry poles with old clotheslines strung between " ++
"them. The driveway is southwest, and the side yard is southeast. A " ++
"side door goes to the garage to the west."
mapRoom backyard 1 (4,9)
newExit "southwest" backyard driveway
newExit "northeast" driveway backyard
newExit "west" backyard garage
newExit "east" garage backyard
sideYard <- newRoom "side yard" $
"This narrow bit of property runs along the east side of Granny\'s " ++
"house. There is a window unit air conditioner sticking out of the " ++
"house, and a lightning rod and a TV antenna have been installed with " ++
"corresponding wires running up to the roof. The front yard is " ++
"southwest and the backyard is northwest."
mapRoom sideYard 1 (6,7)
setDescription2 sideYard $
"The grass here looks dry and parched. A hose beckons you to water the " ++
"yard."
newExit "northwest" sideYard backyard
newExit "southeast" backyard sideYard
newExit "southwest" sideYard frontYard
newExit "northeast" frontYard sideYard
nickYard <- newRoom "Nick\'s yard" $
"This house is in a very poor state of disrepair. It is green, like " ++
"Granny\'s house, but could use a coat of paint, to say the least. " ++
"The lawn is in serious need of weeding. There is a paper wasp nest " ++
"out of reach, on the outside of the second floor."
mapRoom nickYard 1 (4,1)
setArticle nickYard ""
newExit "north" nickYard brisbin
newExit "south" brisbin nickYard
eastBrisbin <- newRoom "east Brisbin Street" $
"This is the east end of the block. Mike\'s house is north, and " ++
"Justin\'s house is south."
mapRoom eastBrisbin 1 (8,3)
setArticle eastBrisbin ""
newExit "east" brisbin eastBrisbin
newExit "west" eastBrisbin brisbin
mikeYard <- newRoom "Mike\'s yard" $
"Mike\'s house is large and L-shaped. The driveway goes around the " ++
"house to the adjacent avenue. There is a planter in the shape of " ++
"an old-fashioned well with petunias growing out of it, and you also " ++
"see a flower bed next to the house. A garage stands at the back of " ++
"the lot. A pet bunny named Misty is here."
mapRoom mikeYard 1 (8,5)
setArticle mikeYard ""
newExit "north" eastBrisbin mikeYard
newExit "south" mikeYard eastBrisbin
misty <- newObject mikeYard "Misty" $
"Misty is a small bunny with a grey coat, a white underbelly, a cute " ++
"nose, long ears, imploring eyes, a tiny little tail, and a pink " ++
"collar. She would like it if you pet her."
setArticle misty ""
addAliases misty ["bunny", "rabbit", "the bunny", "the rabbit"]
makeCreature misty
setVerb1 "get" misty $ do
msg "Misty likes being picked up and snuggles into your arms."
move misty player
setVerb1 "drop" misty $ do
msg "You gently set Misty down."
room <- getRoom
move misty room
putMistyIn <- getVerb2 "put" misty "in"
setVerb2 "put" misty "in" $ \container -> do
putMistyIn container
when (container == backpack) $ msg "Misty loves your backpack!"
let happyMisty = do
msg $ "You gently pet Misty between her eyes and nose. " ++
"She excitedly hops about; she loves being pet there."
queueAction 2 $ do
room <- getRoom
mistyLoc <- getLocation misty
when (Just room == mistyLoc) $ msg $
"Misty hops up to you and wants to be pet again."
setVerb1 "pet" misty $ do
happyMisty
addPoints 10 "being so loving to a deserving animal"
setVerb1 "pet" misty happyMisty
setVerb1 "play with" misty $ msg
"Misty runs in joyous clockwise circles around your feet."
justinYard <- newRoom "Justin\'s yard" $
"You stand in front of Justin\'s house. It is a large home with a " ++
"noticable addition and multiple floors. There is a crabapple tree " ++
"here."
mapRoom justinYard 1 (8,1)
setArticle justinYard ""
let bimboIsHere = "Bimbo the cat is hanging out in the yard."
setDescription2 justinYard bimboIsHere
newExit "south" eastBrisbin justinYard
newExit "north" justinYard eastBrisbin
crabapple <- newObject justinYard "crabapple" $
"This crabapple looks like it might have a worm in it. Yuck!"
setVerb1 "eat" crabapple $ do
msg "You eat the crabapple, worm and all! YUCK!"
moveNowhere crabapple
addPoints (-10) "grossing yourself out"
bimbo <- newObject justinYard "Bimbo" $
"Bimbo, who is oddly a male cat, has grey and white stripes covering " ++
"all of his body."
setArticle bimbo ""
addAliases bimbo ["cat", "the cat"]
makeCreature bimbo
setVerb1 "pet" bimbo $ msg "Bimbo purrs and rubs up against you."
westBrisbin <- newRoom "west Brisbin Street" $
"This is the west end of the block. There is a seedy motel to the " ++
"north, and what looks like a haunted house to the south."
mapRoom westBrisbin 1 (0,3)
setArticle westBrisbin ""
newExit "west" brisbin westBrisbin
newExit "east" westBrisbin brisbin
motel <- newRoom "Oak Grove Motel" $
"You stand in the parking lot of a down-and-out motel. There are two " ++
"yellow cottages, a large white house with an exterior staircase, and " ++
"a row of motel rooms along the back of the property. In the middle of " ++
"the lot is an oval of grass with a picnic table and several oak trees, " ++
"from which the property no doubt got its name."
mapRoom motel 1 (0,5)
newExit "north" westBrisbin motel
newExit "south" motel westBrisbin
leah <- newObject motel "Leah" $
"Leah is a five year old girl with straight blonde hair."
setDescription2 leah $
"She might want to play with you. Please try \"talk to Leah\" or " ++
"\"play with Leah\"."
setArticle leah ""
makeImmobile leah
makeCreature leah
setVerb1 "talk to" leah $ msg $
"Leah says, \"Do you wanna play hide and seek? I want to play " ++
"with you!\" (Type \"play with Leah\" to play hide and seek.)"
let foundLeah = do
msg "Leah says, \"You found me! You\'re good at this game!\""
msg "Leah goes down the stairs."
move leah motel
setVerb1 "talk to" leah $ msg $
"Leah says, \"I'm done playing for now. Thanks!\""
clearVerb1 "find" leah
addPoints 5 "playing with a fun child"
setDescription2 leah "She is done playing games with you."
setVerb1 "play with" leah $ do
msg "Leah says, \"Hooray! Hide and seek! That\'s my favorite!\""
msg "Leah leaves to the south."
move leah upstairs
setDescription2 leah $
"She is playing hide and seek with you. Please type \"find Leah\" " ++
"to let her know you have found her!"
setVerb1 "talk to" leah foundLeah
setVerb1 "find" leah foundLeah
clearVerb1 "play with" leah
hauntedYard <- newRoom "haunted house yard" $
"This is a very large white stucco two story house, with a sizeable " ++
"addition above the garage. There is a lightpost in a tiny clearing in " ++
"the front yard, with white rocks surrounding it. As you approach the " ++
"house, the light on the post turns on. You feel like you are being " ++
"watched."
mapRoom hauntedYard 1 (0,1)
newExit "south" westBrisbin hauntedYard
newExit "north" hauntedYard westBrisbin
hhFoyer <- newRoom "foyer" $
"This is the front room of the haunted house. The whole house appears " ++
"to be done in lavish wood paneling. There is a picture of an elderly " ++
"man on the wall, and his eyes move to follow you. There is a writing " ++
"desk and a basket for umbrellas next to the coat closet."
mapRoom hhFoyer 5 (0,4)
hhEntrance <- newExit "south" hauntedYard hhFoyer
beforeGo hhEntrance $ msg "You hear footsteps as you enter the house."
newExit "north" hhFoyer hauntedYard
writingDesk <- newObject hhFoyer "desk" $
"This is a small writing desk with multiple drawers for storage and an " ++
"upper shelf with paper and fountain pens."
makeImmobile writingDesk
makeContainer writingDesk
addAliases writingDesk ["drawers", "drawer"]
newObject writingDesk "notebook" $
"This is a common spiral bound notebook with a puce cover."
costume <- newObject writingDesk "ghost costume" $
"This is a plain white sheet with two holes for your eyes. The corners " ++
"have been cut off to make it circular. A classic Halloween costume!"
let getCostume = do
move costume player
msg "You put on the ghost costume."
setDescription2 player $ "You are wearing a classic ghost costume " ++
"over your clothes."
putCostume destination = do
move costume destination
msg "You take off the ghost costume."
setDescription2 player ""
setVerb1 "get" costume getCostume
setVerb2 "get" costume "from" $ \_ -> getCostume
setVerb1 "drop" costume $ do
room <- getRoom
putCostume room
setVerb2 "put" costume "in" putCostume
setVerb1 "get" bimbo $ do
costumeLocation <- getLocation costume
unless (costumeLocation == Just player) $ stop $
"Bimbo squirms out of your grasp and jumps to the ground."
msg $ "Bimbo is scared by your ghost costume. " ++
"He squirms out of your grasp and runs into the backyard!"
moveNowhere bimbo
setDescription2 justinYard ""
queueAction 3 $ do
room <- getRoom
when (room == justinYard) $ msg "Bimbo returns to the front yard."
move bimbo justinYard
setDescription2 justinYard bimboIsHere
hhReadingRoom <- newRoom "reading room" $
"There are three high backed reading chairs upholstered in red suede " ++
"in this room. The walls are covered in bookshelves, with gaps for two " ++
"small windows. A colony of orb weaver spiders has made this room their " ++
"home -- you can see their webs covering the upper shelves of the " ++
"bookcases. One red book stands out from the rest, as if it has been " ++
"pulled out several inches."
mapRoom hhReadingRoom 5 (2,4)
newExit "east" hhFoyer hhReadingRoom
newExit "west" hhReadingRoom hhFoyer
book <- newObject hhReadingRoom "book" $
"This red book stands out from the rest. It beckons you to take it."
crookedKey <- newObject hhReadingRoom "crooked key" $
"This is an oddly shaped key. Who knows what it unlocks?"
moveNowhere crookedKey
setDescription2 hhReadingRoom $
"There is a lot of clutter on the floor. Maybe there is something " ++
"important hidden here?"
setVerb1 "search" hhReadingRoom $ do
msg $ "You look everywhere, and find a crooked key under one of the " ++
"armchairs."
move crookedKey hhReadingRoom
addPoints 5 "finding a useful key"
clearVerb1 "search" hhReadingRoom
setDescription2 hhReadingRoom ""
makeLocked writingDesk crookedKey
-- These two lines should come after makeLocked above
setUnlockedDescription2 writingDesk "The drawers are unlocked."
setLockedDescription2 writingDesk "The drawers are locked."
hhBathroom <- newRoom "bathroom" $
"In this otherwise normal-looking bathroom, there is an open coffin. " ++
"It takes up most of the space on the floor. Other than that, you see " ++
"a sink, a toilet, and a shower. There is a medicine cabinet behind the " ++
"bathroom mirror."
mapRoom hhBathroom 5 (2,2)
bathroomEntrance <- newExit "south" hhReadingRoom hhBathroom
newExit "north" hhBathroom hhReadingRoom
medicineCabinet <- newObject hhBathroom "medicine cabinet" $
"This is an ordinary cabinet. It\'s white on the inside and has glass " ++
"shelves."
addAlias medicineCabinet "cabinet"
makeImmobile medicineCabinet
makeContainer medicineCabinet
flask <- newObject medicineCabinet "flask" $
"This is a stoppered flask of clear liquid. It has a label which reads " ++
"\"Holy Water\"."
addAlias flask "holy water"
setVerb1 "drink" flask $ msg $ "You have a feeling the contents of " ++
"this flask are too important to drink."
setVerb1 "read" flask $ doVerb $ Verb1 "look" flask
hhDiningRoom <- newRoom "dining room" $
"This dining room has a huge octagonal hardwood table with eight chairs " ++
"on all sides of it. There is a chandelier with real candles in it, " ++
"which have been recently lit. In the middle of the table is a big " ++
"ceramic jar."
mapRoom hhDiningRoom 5 (0,2)
newExit "south" hhFoyer hhDiningRoom
newExit "north" hhDiningRoom hhFoyer
eyeballs <- newObject hhDiningRoom "jar" $
"The jar is labeled \"Eyeballs\". You try not to think about what might " ++
"be inside."
setVerb1 "get" eyeballs $ msg
"You read the label on the jar and shiver nervously."
ghosts <- newObject hhDiningRoom "three ghosts" $
"Three big ghosts circle the dining room table. It looks like they are " ++
"guarding something."
addAlias ghosts "ghosts"
makeImmobile ghosts
makeCreature ghosts
skullKey <- newObject hhDiningRoom "skull key" $
"This key has a tiny metal skull on its handle. Who knows what it " ++
"unlocks?"
defaultGetSkullKey <- getVerb1 "get" skullKey
setVerb1 "get" skullKey $ do
costumeLocation <- getLocation costume
unless (costumeLocation == Just player) $ stop $
"You approach the table to pick up the key, but the ghosts all turn " ++
"towards you and bare their huge ghostly teeth! You are too scared to " ++
"go on."
msg $ "Wearing your ghost costume, you walk right up to the table and " ++
"take the skull key from the ghosts. They must think you are one of them."
defaultGetSkullKey
addPoints 5 "turning the tables on the three ghosts"
clearVerb1 "get" skullKey
hhKitchen <- newRoom "kitchen" $
"This kitchen is a complete mess. Someone has thrown all of the dishes " ++
"all over the room and broken them. Sharp pieces of ceramic litter the " ++
"floor and countertops. There is no food anywhere to be seen, and the " ++
"fridge is standing open and completely empty. You watch your step " ++
"very carefully as you pass through this room."
kitchenEntrance <- newExit "south" hhDiningRoom hhKitchen
addAliases kitchenEntrance ["door", "the door"]
makeLocked kitchenEntrance skullKey
beforeGo kitchenEntrance $ msg $ "Boards creak under your feet, but the " ++
"ghosts don\'t notice." -- TODO: message shouldn't appear if door is locked
newExit "north" hhKitchen hhDiningRoom
canOpener <- newObject hhKitchen "can opener" $
"This is a metal and plastic can opener of a common style that you " ++
"have seen many times before. The handles are red."
addAlias canOpener "opener"
setVerb1 "use" canOpener $ stop
"Instead of using the can opener, please open something with it."
tuna <- newObject hhKitchen "can of tuna"
"A can of StarKist brand skipjack tuna."
addAliases tuna ["tuna", "can"]
moveNowhere tuna
setVerb1 "eat" tuna $ msg "You haven\'t opened the can of tuna."
setVerb1 "search" hhKitchen $ do
move tuna hhKitchen
msg "You look in the cupboards and find some cans of tuna."
addPoints 5 "finding something delicious"
clearVerb1 "search" hhKitchen
hhStaircase <- newRoom "spiral staircase" $
"This room has a very large and opulent spiral staircase going to the " ++
"upstairs floor. The walnut railing is inlaid with mother of pearl, and " ++
"the steps are covered in yellow carpet."
setDescription2 hhStaircase $ "A very unfriendly black cat is " ++