1/* WIZARD OF OZ - A small game by Shreejit Gangadharan.
    2   Consult this file and issue the command:   start.  */
    3
    4:- dynamic at/2, i_am_at/1, alive/1.   /* Needed by SWI-Prolog. */
    5:- retractall(at(_, _)), retractall(i_am_at(_)), retractall(alive(_)).    6
    7/* This defines my current location. */
    8
    9i_am_at(house_in_kansas).
   10
   11
   12/* These facts describe how the rooms are connected. */
   13
   14path(house_in_kansas, n, kansas_landscape).
   15path(house_in_kansas, d, couch_in_kansas).
   16path(couch_in_kansas, u, field_in_munchkin_county).
   17
   18path(field_in_munchkin_county, n, hardware_store).
   19path(hardware_store, s, field_in_munchkin_county).
   20path(hardware_store, u, hardware_store_attic).
   21path(hardware_store_attic, d, hardware_store).
   22
   23path(field_in_munchkin_county, w, yellow_brick_road_east_1).
   24path(yellow_brick_road_east_1, e, field_in_munchkin_county).
   25
   26path(yellow_brick_road_east_1, w, yellow_brick_road_east_2).
   27path(yellow_brick_road_east_2, e, yellow_brick_road_east_1).
   28
   29path(yellow_brick_road_east_2, w, yellow_brick_road_east_3).
   30path(yellow_brick_road_east_3, e, yellow_brick_road_east_2).
   31
   32path(yellow_brick_road_east_3, w, emerald_city) :- at(scarecrow, party), at(tin_man, party), at(lion, party), at(toto, inventory),
   33        at(silver_shoes, inventory).
   34path(yellow_brick_road_east_3, w, emerald_city) :- 
   35        write('You need the scarecrow, tin man and lion in your party and Toto and silver shoes in your inventory to see the '),
   36        write('Wizard of Oz! Go back and figure how to get them '),
   37        write('to join your party.'), nl, !, fail.
   38
   39path(emerald_city, e, yellow_brick_road_east_3).
   40
   41
   42/* These facts tell where the various objects in the game
   43   are located. */
   44
   45at(toto, couch_in_kansas).
   46at(silver_shoes, field_in_munchkin_county).
   47at(kiss, field_in_munchkin_county).
   48
   49at(oil_can, hardware_store).
   50at(large_knife, hardware_store).
   51
   52/* This fact specifies that the spider is alive. */
   53
   54alive(ww_east).
   55
   56
   57/* These rules describe how to pick up an object. */
   58
   59add :-  nb_getval(i_size, C), 
   60        CNew is C + 1, 
   61        nb_setval(i_size, CNew).
   62
   63sub :-  nb_getval(i_size, C), 
   64        CNew is C - 1, 
   65        nb_setval(i_size, CNew).
   66
   67take(X) :-
   68        at(X, inventory),
   69        write('You''re already holding it!'),
   70        nl, !.
   71
   72take(_) :-
   73        add,
   74        nb_getval(i_size, CounterValue),
   75        nb_getval(i_limit, CounterLimit),
   76        CounterValue > CounterLimit,
   77        sub,
   78        write('You have too many items! Drop some.'),
   79        nl, !.
   80
   81take(X) :-
   82        i_am_at(Place),
   83        at(X, Place),
   84        retract(at(X, Place)),
   85        assert(at(X, inventory)),
   86        write('OK.'),
   87        nl, !.
   88
   89take(_) :-
   90        write('I don''t see it here.'),
   91        nl.
   92
   93/* These rules describe how to put down an object. */
   94
   95drop(X) :-
   96        at(X, inventory),
   97        i_am_at(Place),
   98        retract(at(X, inventory)),
   99        assert(at(X, Place)),
  100        sub,
  101        write('OK.'),
  102        nl, !.
  103
  104drop(_) :-
  105        write('You aren''t holding it!'),
  106        nl.
  107
  108
  109/* These rules define the six direction letters as calls to go/1. */
  110
  111n :- go(n).
  112
  113s :- go(s).
  114
  115e :- go(e).
  116
  117w :- go(w).
  118
  119u :- go(u).
  120
  121d :- go(d).
  122
  123
  124/* This rule tells how to move in a given direction. */
  125
  126go(Direction) :-
  127        i_am_at(Here),
  128        path(Here, Direction, There),
  129        retract(i_am_at(Here)),
  130        assert(i_am_at(There)),
  131        look, !.
  132
  133go(_) :-
  134        write('You can''t go that way.').
  135
  136
  137/* This rule tells how to look about you. */
  138
  139look :-
  140        i_am_at(Place),
  141        describe(Place),
  142        nl,
  143        notice_objects_at(Place),
  144        nl.
  145
  146
  147/* These rules set up a loop to mention all the objects
  148   in your vicinity. */
  149
  150notice_objects_at(Place) :-
  151        at(X, Place),
  152        write('There is a '), write(X), write(' here.'), nl,
  153        fail.
  154
  155notice_objects_at(_).
  156
  157/* These rules show the inventory */
  158
  159i :-
  160        at(X, inventory),
  161        write('You have a '),
  162        write(X),
  163        write(' in your inventory.'),
  164        nl, fail.
  165
  166/* These commands are for listing the party */
  167
  168p :-
  169        at(X, party),
  170        write(X),
  171        write(' is a part of your party.'),
  172        nl, fail.
  173
  174/* These rules tell how to handle interact the lion and the spider. */
  175
  176interact(tin_man) :-
  177        at(oil_can, inventory),
  178        i_am_at(yellow_brick_road_east_2),
  179        write('You apply the oil onto the tin man\'s joints and it\'s able to move again! It tells you that it needs to meet the Wizard'),
  180        write('the Wizard of Oz to get a heart. It decides to accompany you! '),
  181        assert((at(tin_man, party))),
  182        nl, !.
  183interact(tin_man) :-
  184        i_am_at(yellow_brick_road_east_2),
  185        write('The joins are rusted. The tin man could walk if they were lubricated.'), 
  186        nl, !.
  187
  188interact(scarecrow) :-
  189        at(large_knife, inventory), 
  190        i_am_at(yellow_brick_road_east_1),
  191        write('You\'ve freed the scarecrow. It seemed to have tried cutting the branch it was on and got tied up. It tells you it '),
  192        write('needs to meet the Wizard of Oz to get a brain. It decides to accompany you! '),
  193        assert((at(scarecrow, party))),
  194        nl, !.
  195interact(scarecrow) :-
  196        write('You need to free him from the rope. You could cut it in some way.'), 
  197        nl, !.
  198
  199interact(lion) :-
  200        at(toto, inventory), 
  201        i_am_at(yellow_brick_road_east_3),
  202        write('Toto runs after the cat and rescues the lion!. It tells you it '),
  203        write('needs to meet the Wizard of Oz to get courage. It decides to accompany you! '),
  204        assert((at(lion, party))),
  205        nl, !.
  206
  207interact(lion) :-
  208        at(vodka_bottle, inventory), 
  209        i_am_at(yellow_brick_road_east_3),
  210        write('The \'liquid courage\' gives the lion a brief spell of courage to chase away the cat. It tells you it '),
  211        write('needs to meet the Wizard of Oz to get courage. It decides to accompany you! '),
  212        assert((at(lion, party))),
  213        nl, !.
  214
  215interact(lion) :-
  216        write('The lion is too busy running from the cat. I wonder if you could chase the cat away with something?'), 
  217        nl, !.
  218
  219interact(_) :-
  220        write('Nothing happens.'),
  221        nl, !.
  222/* This rule tells how to die. */
  223
  224die :-
  225        !, finish.
  226
  227
  228/* Under UNIX, the   halt.  command quits Prolog but does not
  229   remove the output window. On a PC, however, the window
  230   disappears before the final output can be seen. Hence this
  231   routine requests the user to perform the final  halt.  */
  232
  233finish :-
  234        nl,
  235        write('The game is over. Please enter the   halt.   command.'),
  236        nl, !.
  237
  238
  239/* This rule just writes out game instructions. */
  240
  241instructions :-
  242        nl,
  243        write('Enter commands using standard Prolog syntax.'), nl,
  244        write('Available commands are:'), nl,
  245        write('start.                   -- to start the game.'), nl,
  246        write('n.  s.  e.  w.  u.  d.   -- to go in that direction.'), nl,
  247        write('take(Object).            -- to pick up an object.'), nl,
  248        write('drop(Object).            -- to put down an object.'), nl,
  249        write('interact.                -- interact with an object.'), nl,
  250        write('look.                    -- to look around you again.'), nl,
  251        write('instructions.            -- to see this message again.'), nl,
  252        write('halt.                    -- to end the game and quit.'), nl,
  253        write('i.                       -- to check the inventory.'), nl,
  254        write('p.                       -- to check people in your party.'), nl,
  255        nl.
  256
  257
  258/* This rule prints out instructions and tells where you are. */
  259
  260start :-
  261        nb_setval(i_size, 0),
  262        nb_setval(i_limit, 3),
  263        instructions,
  264        look, !.
  265
  266
  267/* These rules describe the various rooms.  Depending on
  268   circumstances, a room may have more than one description. */
  269
  270describe(kansas_landscape) :-
  271        write('A hurricane hits Kansas! Your house is blown away and you\'re left in the middle of nowhere! You die.'),
  272        finish, !.
  273
  274describe(couch_in_kansas) :-
  275        write('You\'re playing with your dog Toto when your house starts to tremble and the windows start to shake. '),
  276        write('You look outside and it\'s a huge hurricane! You frantically search for something to grab on to. You find '),
  277        write('Toto barking furiously and pick him up. You two brace for impact and expect the worst. '),
  278        assert((at(toto, inventory))),
  279        add,
  280        nl,
  281        write('Press u to follow the hurricane (you can\'t do anything else).'),
  282        nl.
  283        
  284describe(house_in_kansas) :-
  285        write('Hello Dorothy! You\'re being raised by Uncle Henry and Aunt Em in the bleak landscape of a Kansas farm. '),
  286        write('One day when your Uncle and Aunt leave the house, and ask you to come with them to sell the wheat. '),
  287        nl,
  288        write('You can exit the house and join them by going north.'),
  289        nl,
  290        write('or stay in the house and laze around by sitting down.').
  291
  292describe(field_in_munchkin_county) :-
  293        at(silver_shoes, inventory),
  294        write('Now that you\'re wearing the silver shoes, you ask the Good Witch of the North how to get back home. She tells you '),
  295        write('to go to the Emerald City and ask the Wizard of Oz.'),
  296        nl,
  297        write('You can go west to start on the yellow brick road.'),
  298        nl,
  299        write('There\'s also a hardware shop in the north.'),
  300        !.
  301
  302describe(field_in_munchkin_county) :-
  303        write('Now that was no normal hurricane! You\'ve been transported to the Land of Oz! You\'re in a field in Munchkin County, '),
  304        write('and as you step out of the house, you see a lot of munchkins! You look at the bottom of the house and see a pair of feet. '),
  305        write('You\'ve killed the Wicked Witch of the East and have freed the munchkins from her evil grip. The Good Witch of the North '),
  306        write('teleports to you and removes the Silver Shoes from the witch and offers them to you. She also offers a kiss for protection.'),
  307        nl.
  308
  309describe(house_in_kansas) :-
  310        at(silver_shoes, inventory),
  311        write('Well done Dorothy! You just defeated the Wicked Witch of the West and are now back in Kansas!'), nl, finish, !.
  312
  313describe(hardware_store) :-
  314        write('You enter a hardware store with a really grumpy looking man sitting at the desk. You see there are two items for sale.'),
  315        nl,
  316        write('The exit is towards the south. There also seems to be a room upstairs.').
  317
  318describe(hardware_store_attic) :-
  319        at(large_knife, inventory), 
  320        write('It\s dark and dusty. You cut through the spider-webs with your knife. You find a vodka_bottle lying beside a bunch of '),
  321        write('boxes. '),
  322        nl,
  323        assert((at(vodka_bottle, hardware_store_attic))),
  324        write('You think about the passage down to the store.'),
  325        nl.
  326
  327describe(hardware_store_attic) :-
  328        write('It\s dark and dusty. There are way too many spider-webs blocking your way.'),
  329        nl,
  330        write('You need to go back down to the store.'),
  331        nl.
  332
  333describe(yellow_brick_road_east_1) :-
  334        at(scarecrow, party),
  335        write('You see a tree with a piece of rope tied to a branch. You could'),
  336        nl,
  337        write('Proceed west along the yellow brick road or'),
  338        nl,
  339        write('backtrack east'),
  340        nl.
  341
  342describe(yellow_brick_road_east_1) :-
  343        write('You hop along the yellow brick road and you see a \'scarecrow\' tied to a tree branch with a piece of rope. If only you '),
  344        write('could cut him down. You could'),
  345        nl,
  346        write('Proceed west along the yellow brick road or'),
  347        nl,
  348        write('backtrack east'),
  349        nl.
  350
  351describe(yellow_brick_road_east_2) :-
  352        at(tin_man, party),
  353        write('You see a corrugated shed with lots of oil lying around. You could'),
  354        nl,
  355        write('Proceed west along the yellow brick road or'),
  356        nl,
  357        write('backtrack east'),
  358        nl.
  359
  360describe(yellow_brick_road_east_2) :-
  361        write('You hop along the yellow brick road and you see a \'tin_man\' with too much rust to move. There\'s nothing you can do to'),
  362        write('help him now. You could'),
  363        nl,
  364        write('Proceed west along the yellow brick road or'),
  365        nl,
  366        write('backtrack east'),
  367        nl.
  368
  369describe(yellow_brick_road_east_3) :-
  370        at(lion, party),
  371        write('You see an empty field. Do you'),
  372        nl,
  373        write('Proceed west along the yellow brick road or'),
  374        nl,
  375        write('backtrack east'),
  376        nl.
  377
  378describe(yellow_brick_road_east_3) :-
  379        write('You hop along the yellow brick road and you see a dejected \'lion\' in the middle of a field being chased by a small cat. '),
  380        write('The lion is huge and strong, but seems to lack confidence. Is there something you can do to encourage it? '),
  381        nl,
  382        write('Proceed west along the yellow brick road or'),
  383        nl,
  384        write('backtrack east'),
  385        nl.
  386
  387describe(emerald_city) :- 
  388        write('You\'re at the Emerald City! You wait for the Wizard of Oz. More to come in Part 2!'),
  389        nl, finish, !