1/* Sunken Treasure -- a sample adventure game, by Deepti Panuganti.
    2   Consult this file and issue the command:   start.  */
    3
    4:- dynamic at/2, i_am_at/1, alive/1, wearing/1,dead/1,count/1.  /* Needed by SWI-Prolog. */
    5:- retractall(at(_, _)), retractall(i_am_at(_)), retractall(alive(_)).    6
    7
    8count(0).
    9
   10
   11/* This defines my current location. */
   12
   13i_am_at(sea).
   14
   15
   16/* These facts describe how the rooms are connected. */
   17
   18path(sea, s, trench).
   19path(trench, n, sea).
   20path(sea, e, palace_entrance).
   21path(palace_entrance, w, sea).
   22path(palace_entrance, s, palace_door).
   23path(palace_door, n, palace_entrance).
   24path(locked_door, u, shelf).
   25path(shelf, d, locked_door).
   26path(sunken_ship, s, sea) :-
   27	wearing(invisibility_cloak),!,nl.
   28path(sunken_ship, s, sea) :-
   29	write('The merman can see you! Put your invisibility_cloak back on.'),nl,fail.
   30path(through_trench, s, shell).
   31path(shell, n, through_trench).
   32
   33path(sea, n, sunken_ship) :- 
   34    alive(invisibility_cloak),
   35    wearing(invisibility_cloak),!,nl.
   36path(sea, n, sunken_ship) :- 
   37    at(invisibility_cloak,in_hand),
   38    dead(invisibility_cloak),
   39    write('The spell on the invisibility_cloak is wearing off! You need to recast the spell.'),
   40    nl,!,fail.
   41path(sea, n, sunken_ship) :-
   42	alive(invisibility_cloak),
   43	at(invisibility_cloak,in_hand),
   44	write('The merman can still see you! Wear your invisibility_cloak.'),nl,!, fail.
   45
   46path(sea, n, sunken_ship) :- 
   47    write('There is a vicious looking merman with '), nl,
   48    write('a spear guarding the ship!'), nl,
   49    write('If he sees you who knows what he''ll do.'), nl,
   50    write('You better not go there.'), 
   51    nl,!,fail.
   52
   53path(sea, w, indefinitesea) :- 
   54    write('Don''t give up already!'),nl,
   55    write('You can find the treasure.'),
   56    nl,!,fail.
   57
   58  path(indefinitesea, e, sea).
   59
   60 path(squid, w, palace_entrance). 
   61
   62
   63path(palace_entrance, e, squid).
   64path(squid, e, guarded_door).
   65path(guarded_door, w, palace_entrance).
   66
   67path(king, s, palace_entrance).
   68path(palace_entrance, n, king) :-
   69    wearing(invisibility_cloak),
   70    at(chest,in_hand),
   71    write('The king can''t see you!'),nl,
   72    write('Remove the invisibility_cloak first.'),
   73    nl,!,fail.
   74
   75path(palace_entrance, n, king) :-
   76    at(chest,in_hand),!.
   77
   78path(palace_entrance, n, king) :-
   79    wearing(invisibility_cloak), 
   80    alive(invisibility_cloak),!,nl.
   81
   82path(palace_entrance, n, king) :-
   83    at(invisibility_cloak,in_hand),
   84    alive(invisibility_cloak),
   85    write('Don''t just hold the invisibility_cloak. Wear it!'),!,fail,nl.
   86
   87path(palace_entrance, n, king) :-
   88	at(invisibility_cloak, in_hand),
   89	write('The spell on the invisibility_cloak doesn''t seem to be working properly.'), nl, !, fail.
   90
   91path(palace_entrance, n, king) :- 
   92    write('You don''t want the king to '),nl,
   93    write('see you lurking around.'),
   94    nl,fail.
   95
   96path(trench, u, above_trench).
   97path(above_trench, d, trench).
   98path(through_trench, n, trench).
   99path(trench, s, through_trench).
  100
  101path(sunken_ship, e, corridor) :-
  102	wearing(invisibility_cloak),
  103	write('There is huge shark in front of you. Lucky you have the invisibility_cloak.'),nl,!.
  104
  105path(sunken_ship, e, corridor):- 
  106    write('Uh-oh! There is a huge shark right '),nl,
  107    write('in front of you!'),nl, 
  108    write('Get out of there ASAP.'),
  109    nl.
  110
  111 path(corridor, w, sunken_ship) :- 
  112 	wearing(invisibility_cloak),nl,!.
  113
  114path(corridor, w, sunken_ship) :-
  115 	write('What did you do with your invisibility_cloak?!'),nl,
  116 	write('The shark can see you. Put it back on!'),nl,!,fail.
  117 
  118
  119path(locked_door, e, sunken_ship).
  120path(sunken_ship, w, locked_door) :- 
  121    at(key, in_hand).
  122path(sunken_ship, w, locked_door) :- 
  123    write('The door is locked.'),
  124    nl,fail.
  125
  126path(locked_door, u, chest).
  127path(chest, d, locked_door).
  128
  129/* These facts tell where the various objects in the game are located. */
  130
  131at(key, corridor). 
  132at(trident, palace_door).
  133at(invisibility_cloak, guarded_door).
  134at(chest, shelf).
  135
  136
  137/* This fact specifies that the squid is alive. */
  138
  139alive(squid).
  140alive(shell).
  141alive(shark).
  142dead(invisibility_cloak).
  143
  144
  145/* These rules describe how to pick up an object. */
  146
  147take(invisibility_cloak) :-
  148		count(N),
  149        N<2,
  150        retract(count(N)),
  151        Y is N+1, 
  152        assert(count(Y)),
  153		i_am_at(Place),
  154        at(X, Place),
  155        retract(at(X, Place)),
  156        assert(at(X, in_hand)),
  157        write('OK. But the invisibility_cloak doesn''t seem to be working very well'), nl,
  158        write('Maybe the spell is wearing off. You better find a way to recast it.'),
  159        nl, !.
  160
  161take(invisibility_cloak) :-
  162        i_am_at(Place),
  163        at(_, Place),
  164        write('You can only hold 2 objects at a time. You have to drop something.'),
  165        nl, !,fail.
  166
  167take(invisibility_cloak) :-
  168        write('It isn''t here.'),
  169        nl, !,fail.
  170
  171
  172take(X) :-
  173        at(X, in_hand),
  174        write('You''re already holding it!'),
  175        nl, !.
  176
  177take(X) :-
  178        count(N),
  179        N<2,
  180        retract(count(N)),
  181        Y is N+1, 
  182        assert(count(Y)),
  183        i_am_at(Place),
  184        at(X, Place),
  185        retract(at(X, Place)),
  186        assert(at(X, in_hand)),
  187        
  188        write('OK.'),
  189        nl, !.  
  190
  191take(_) :-
  192        i_am_at(Place),
  193        at(_, Place),
  194        write('You can only hold 2 objects at a time. You have to drop something.'),
  195        nl, !,fail.  
  196
  197take(_) :-
  198		
  199        write('It isn''t here'),
  200        nl,!,fail.
  201
  202
  203 wear(invisibility_cloak) :-
  204        dead(invisibility_cloak),
  205        write('It''s not working! What''s the point of wearing it?'),nl,fail,!.
  206
  207 wear(X):-
  208        assert(wearing(X)). 
  209
  210remove(X) :-
  211        retract(wearing(X)).  
  212
  213i :-
  214        at(X,in_hand),
  215        write(X),nl,fail.       
  216
  217
  218/* These rules describe how to put down an object. */
  219
  220drop(invisibility_cloak) :-
  221        at(X, in_hand),
  222        i_am_at(Place),
  223        retract(at(X, in_hand)),
  224        assert(at(X, Place)),
  225        retract(wearing(invisibility_cloak)),
  226        count(N),
  227        retract(count(N)),
  228        Y is N-1, 
  229        assert(count(Y)),
  230        write('OK.'),
  231        nl, !.
  232
  233drop(X) :-
  234        at(X, in_hand),
  235        i_am_at(Place),
  236        retract(at(X, in_hand)),
  237        assert(at(X, Place)),
  238        count(N),
  239        retract(count(N)),
  240        Y is N-1, 
  241        assert(count(Y)),
  242        write('OK.'),
  243        nl, !.
  244
  245drop(_) :-
  246        write('You aren''t holding it!'),
  247        nl.
  248
  249
  250/* These rules define the six direction letters as calls to go/1. */
  251
  252n :- go(n).
  253
  254s :- go(s).
  255
  256e :- go(e).
  257
  258w :- go(w).
  259
  260u :- go(u).
  261
  262d :- go(d).
  263
  264
  265/* This rule tells how to move in a given direction. */
  266
  267go(Direction) :-
  268        i_am_at(Here),
  269        path(Here, Direction, There),
  270        retract(i_am_at(Here)),
  271        assert(i_am_at(There)),
  272        look, !.
  273
  274go(_) :-
  275        write('You can''t go that way.'),fail.
  276
  277
  278/* This rule tells how to look about you. */
  279
  280look :-
  281        i_am_at(Place),
  282        describe(Place),
  283        nl,
  284        notice_objects_at(Place),
  285        nl.
  286
  287
  288/* These rules set up a loop to mention all the objects
  289   in your vicinity. */
  290
  291notice_objects_at(Place) :-
  292        at(X, Place),
  293        write('There is a '), write(X), write(' here.'), nl,
  294        fail.
  295
  296notice_objects_at(_).
  297
  298
  299/* These rules tell how to handle the shark and squid */
  300
  301attack :-
  302        i_am_at(corridor),
  303        write('Did you really think you could kill a shark?'),nl,
  304        write('It ate you for supper.'), nl,!, die.
  305
  306attack :-
  307        i_am_at(sea),
  308        write('You try to fight but '),
  309        write('the merman is too tough for you.'),nl,
  310        write('You should escape while you still can.'), nl.
  311
  312attack :-
  313        i_am_at(squid),
  314        at(trident, in_hand),
  315        retract(alive(squid)),
  316        write('You attack the squid with your trident,'), nl,
  317        write('piercing it until it falls to the sand below.'), nl,
  318        write('That seems to have done the trick.'), nl,
  319        write('There is a door to the east.'),
  320        nl, !.
  321
  322attack :-
  323        i_am_at(above_trench),
  324        write('You are no match for the jellyfish.'), nl,
  325        write('As you get stung over and over you start to lose conciousness '), nl,write('and die.'),nl,!,die.
  326
  327attack :-
  328        write('There is nothing to attack here.'),nl,write('Boy, you''re violent!'), nl,fail.
  329
  330break :-
  331        i_am_at(shell),
  332        alive(shell),
  333        at(trident,in_hand),
  334        retract(alive(shell)),
  335        assert(dead(shell)),
  336        assert(at(spellbook, shell)),
  337        write('The shell broke open!'), nl,
  338        write('You find a spellbook inside.'),nl,
  339        write('You should take it and search for the spell'),
  340        nl,!.
  341
  342break :-
  343        i_am_at(shell),
  344        alive(shell),
  345        write('Wow that is one strong shell!'),nl,
  346        write('You are not able to break it with your bare hands.'),nl,
  347        write('You may need something else.'),
  348        nl,!,fail.
  349
  350break :-
  351        i_am_at(shell),
  352        write('It''s already open!').
  353
  354search :-
  355 		at(spellbook,in_hand),
  356 		retract(dead(invisibility_cloak)),
  357 		assert(alive(invisibility_cloak)),
  358 		write('You look through the book carefully and after a lot of squinting you find the right spell!'),nl,
  359 		write('You say the incantation aloud and the spell is cast.'),nl,
  360 		write('Your invisibility_cloak is now working!'),nl,!.
  361
  362 search :-
  363 		i_am_at(through_trench),
  364 		write('You should get closer to see what it is.'),nl.
  365 	
  366 search :-
  367        write('You don''t notice anything special'),nl.
  368
  369
  370
  371
  372
  373/* This rule tells how to die. */
  374
  375die :-
  376        !, finish.
  377
  378
  379/* Under UNIX, the   halt.  command quits Prolog but does not
  380   remove the output window. On a PC, however, the window
  381   disappears before the final output can be seen. Hence this
  382   routine requests the user to perform the final  halt.  */
  383
  384finish :-
  385        nl,
  386        write('Game Over!'),nl,write('Please enter the   halt.   command.'),
  387        nl, !.
  388
  389
  390/* This rule just writes out game instructions. */
  391
  392help :-
  393        nl,
  394        write('Enter commands using standard Prolog syntax.'), nl,
  395        write('Available commands are:'), nl,
  396        write('start.                   -- to start the game.'), nl,
  397        write('n.  s.  e.  w.  u.  d.   -- to go in that direction.'), nl,
  398        write('take(Object).            -- to pick up an object.'), nl,
  399        write('drop(Object).            -- to put down an object.'), nl,
  400        write('wear(Object).		    -- to wear something.'),nl,
  401	    write('attack.                  -- to attack an enemy.'), nl,
  402	    write('break.                   -- to break an object'),nl,
  403        write('look.                    -- to look around you again.'), nl,
  404        write('search                   -- to search an object more closely.'),nl,
  405        write('i.                       -- to see what you are currently holding.'),nl,
  406        write('help.                    -- to see this message again.'), nl,
  407        write('halt.                    -- to end the game and quit.'), nl,
  408        nl.
  409
  410
  411/* This rule prints out instructions and tells where you are. */
  412
  413start :-
  414        help,
  415        write('You are underwater in the lost city of Atlantica.'),nl,
  416        write('You have been banished for badmouthing your king.'),nl,
  417        write('to get back in his good books find the lost treasure and present it to him.'),nl,
  418        write('To the north there is a huge shipwreck covered in seaweed.'),nl,
  419        write('To the south there is a formidable looking trench.'),nl,
  420        write('To the east there is the King''s palace and '),nl,
  421        write('to the west is an unending blue expanse of sea.'),nl,
  422        write('Good luck!'),
  423        nl.
  424
  425
  426/* These rules describe the various rooms.  Depending on circumstances, a room may have more than one description. */
  427
  428describe(sea) :-
  429		write('You are back in the middle of the city.'), nl,
  430		write('To the north there is a huge shipwreck covered in seaweed.'),nl,
  431        write('To the south there is a formidable looking trench.'),nl,
  432        write('To the east there is the King''s palace and '),nl,
  433        write('to the west is an unending blue expanse of sea.'),nl.
  434       
  435
  436describe(palace_entrance) :-
  437        alive(squid),
  438        write('You are in the King''s palace. Don''t be seen.'),nl,
  439        write('To the north is the King''s court.'), nl,
  440        write('To the south is a small door and to the east there '), nl,
  441        write('is a smaller room blocked by a giant squid. The exit is to the west.'), nl.
  442
  443describe(palace_entrance) :-
  444        write('You are in the King''s palace. Don''t be seen.'),nl,
  445        write('To the north is the King''s court.'), nl,
  446        write('To the south is a small door and to the east there '), nl,
  447        write('is a smaller room. The exit is to the west.'), nl.
  448
  449describe(trench) :-
  450        write('You are staring at a huge trench. You can '), nl,
  451        write('either go above it or continue south through it.'), nl, write('Go back north to get out.'),nl.
  452
  453describe(sunken_ship) :-
  454        write('You are inside the ship! There is a long dark corridor '), nl,
  455        write('to the east and a fancy looking door to the west.'), nl,
  456        write('The exit is to the south.'),
  457        nl.
  458
  459describe(above_trench) :-
  460        write('There is a swarm of jellyfish here! Get out!'), nl.
  461
  462describe(through_trench) :-
  463        write('You are in the trench. Yikes! Looks creepy.'),nl, 
  464        write('You see something shining in the distance to the south.'), nl,
  465        write('The exit is to the north.'), nl.
  466
  467describe(squid) :-
  468        alive(squid),
  469        at(trident, in_hand),
  470        write('The squid looks like it is going to attack! Watch out!'), nl.
  471
  472describe(squid) :-
  473        alive(squid),
  474        write('The squid wraps it''s tentacles around your neck '),
  475        write('and strangles you. You die.'), nl, die.
  476
  477describe(squid):-
  478	write('The door is open.'),nl.
  479
  480
  481describe(guarded_door):-
  482	write('You are inside a tiny passageway that is '),nl,
  483    write('lit by candles. Yes, they can glow underwater.'),nl,
  484    write('The exit is to the west').
  485
  486describe(palace_door) :-
  487        write('It is a small room that looks like '),nl,
  488        write('nobody has used it in a long time.'),nl,
  489        write('The exit is to the north.'),nl.
  490
  491describe(king) :-
  492	at(chest,in_hand), 
  493    write('The king is very pleased with you!'),nl,
  494    write('So pleased that he decided to forgive you!'),nl,
  495    write('You can now go back home. Congratulations!'),nl,finish.
  496
  497describe(king) :-
  498	wearing(invisibility_cloak), 
  499    write('Just a bunch of boring ministers discussing politics.'),nl.
  500
  501describe(locked_door) :-
  502        at(chest,in_hand),
  503        write('You are in a room full of shelves and cabinets.'), nl,
  504        write('The exit is to the east.'),nl,!.
  505
  506describe(locked_door) :-
  507        write('You are in a room full of shelves and cabinets.'), nl,
  508        write('Then you see it. A treasure chest! It is in a shelf above you.'), nl,
  509        write('The exit is to the east.'),nl.
  510
  511
  512describe(shelf) :-
  513	write('Almost there!'),nl.
  514
  515describe(shell) :-
  516    alive(shell),
  517    write('You are in front of a beautiful Oyster shell. It is closed.'),nl,write('You might need to break it to get it open.'),nl.
  518
  519describe(shell) :-
  520    write('You are in front of a beautiful Oyster shell. The exit is to the north.'),nl.
  521
  522describe(corridor) :-
  523    write('At the end of the corridor is a staircase.'),nl,
  524    write('As you reach the foot of the stairs you see something glimmer.'),nl