/* DRAGON -- a sample adventure game, by David Matuszek. Consult this file and issue the command "start." */ /* Quintus Prolog and SWI-Prolog require that any clauses you intend to assert or retract be marked "dynamic." */ :- dynamic i_am_at/1, at/2, holding/1, dragon_is_present/0, locked/1. /* This defines my current location. */ i_am_at(meadow). /* These facts describe how the rooms are connected. */ path(cave, w, cave_entrance). path(cave_entrance, e, cave). path(cave_entrance, s, meadow). path(meadow, n, cave_entrance) :- holding(flashlight). path(meadow, n, cave_entrance) :- write('Go into that dark cave without a light? Are you crazy?'), nl, fail. path(meadow, s, building). path(building, n, meadow). path(closet, w, building). path(building, e, closet) :- locked(closet), write('The door appears to be locked.'), nl, !, fail. path(building, e, closet). /* These facts tell where the various objects in the game are located. */ at(key, cave_entrance). at(flashlight, building). at(sword, closet). /* Here we make the chest too heavy to lift. */ heavy(chest). /* The closet and the chest are both locked. Amazingly, the same key will work on both. */ locked(chest). locked(closet). /* This fact specifies that the dragon is present. */ dragon_is_present. /* These rules describe how to pick up an object. */ take(X) :- holding(X), write('You''re already holding it!'), nl. take(X) :- i_am_at(Place), at(X, Place), heavy(X), write('With a mighty heave, you fail to lift it.'), nl. take(X) :- i_am_at(Place), at(X, Place), retract(at(X, Place)), assert(holding(X)), write('OK.'), nl. take(_) :- write('I don''t see it here.'), nl. /* These rules describe how to put down an object. */ drop(X) :- holding(X), i_am_at(Place), retract(holding(X)), assert(at(X, Place)), write('OK.'), nl. drop(_) :- write('You aren''t holding it!'), nl. /* These rules tell how to "use" various objects. */ use(sword) :- holding(sword), attack. use(key) :- holding(key), i_am_at(building), retract(locked(closet)), write('The closet is no longer locked.'), nl. use(key) :- holding(key), i_am_at(Place), at(chest, Place), retract(locked(chest)), write('Opening the chest reveals a giant ruby!'), nl, assert(at(ruby, Place)). use(flashlight) :- holding(flashlight), write('The flashlight is on.'), nl. use(X) :- holding(X), write('That doesn''t seem to be useful.'), nl. use(_) :- write('You aren''t holding it.'), nl. /* These rules define the direction letters as calls to go/1. */ n :- go(n). s :- go(s). e :- go(e). w :- go(w). /* This rule tells how to move in a given direction. */ go(Direction) :- i_am_at(Here), path(Here, Direction, There), retract(i_am_at(Here)), assert(i_am_at(There)), look. go(_) :- write('You can''t go that way.'). /* This rule tells how to look about you. */ look :- i_am_at(Place), describe(Place), nl, notice_objects_at(Place), nl. /* These rules set up a loop to mention all the objects in your vicinity. */ notice_objects_at(Place) :- at(X, Place), write('There is a '), write(X), write(' here.'), nl, fail. notice_objects_at(_). /* These rules tell how to handle attacking the dragon. */ attack :- i_am_at(cave), dragon_is_present, holding(sword), write('Screaming madly and flailing the sword in the air,'), nl, write('you rush headlong at the dragon.'), nl, write('The dragon, startled out of a sound sleep, flies'), nl, write('out of the cave. He''ll probably be back soon...'), nl, nl, retract(dragon_is_present), assert(at(chest, cave)). attack :- i_am_at(cave), write('Your common sense suddenly gets the better of you.'), nl. attack :- i_am_at(Place), holding(sword), write('Congratulations! You have put several scars in the '), write(Place), ('.'), nl. /* This rule tells how to die. */ die :- finish. /* Under UNIX, the "halt." command quits Prolog but does not remove the output window. On a PC, however, the window disappears before the final output can be seen. Hence this routine requests the user to perform the final "halt." */ finish :- nl, write('The game is over. Please enter the "halt." command.'), nl. /* This rule just writes out game instructions. */ instructions :- nl, write('Enter commands using standard Prolog syntax.'), nl, write('Available commands are:'), nl, write('start. -- to start the game.'), nl, write('n. s. e. w. -- to go in that direction.'), nl, write('take(Object). -- to pick up an object.'), nl, write('drop(Object). -- to put down an object.'), nl, write('use(Object). -- to use an object.'), nl, write('attack. -- to attack an enemy.'), nl, write('look. -- to look around you again.'), nl, write('instructions. -- to see this message again.'), nl, write('halt. -- to end the game and quit.'), nl, nl. /* This rule prints out instructions and tells where you are. */ start :- instructions, look. /* These rules describe the various rooms. Depending on circumstances, a room may have more than one description. */ describe(meadow) :- holding(ruby), write('Congratulations!! You have recovered the ruby'), nl, write('and won the game.'), nl, finish. describe(meadow) :- write('You are in a meadow. To the north is the dark mouth'), nl, write('of a cave; to the south is a small building. Your'), nl, write('assignment, should you decide to accept it, is to'), nl, write('recover the famed Bar-Abzad ruby and return it to'), nl, write('this meadow.'), nl. describe(building) :- write('You are in a small building. The exit is to the north.'), nl, write('The room is devoid of furniture, and the only feature'), nl, write('seems to be a small door to the east.'), nl. describe(closet) :- write('This is nothing but an old storage closet.'), nl. describe(cave_entrance) :- write('You are in the mouth of a dank cave. The exit is to'), nl, write('the south; there is a large, dark, round passage to'), nl, write('the east.'), nl. describe(cave) :- dragon_is_present, write('You''re in the cave, and...Shhh! There''s a dragon here!'), nl, write('It''s curled up around a chest of some sort...I don''t'), nl, write('think it''s noticed you...yet.'), nl. describe(cave) :- write('You are in a big, dark cave. The air is fetid.'), nl.