%Josef Nguyen % %This is a game based on Voltaire's Candide. %The player explores a world based on Candide's %adventures and follows parts of his journey %to complete the game. % %-------------------------------------- %GAME CHARACTERISTICS %-------------------------------------- %places place(constantinople). place(venice). place(marakesh). place(lisbon). place(cadiz). place(paris). place(westphalia). place(portsmith). place('buenos aires'). place(paraguay). place(eldorado). place(surinam). %subplaces place(rubble). place(bazaar). place(mansion). place(monastary). place(arena). place(inn). place(encampment). place(palace). place(prison). %subplace relationship - (subplace, place) subplace(rubble, westphalia). subplace(monastary, paraguay). subplace(mansion, 'buenos aires'). subplace(arena, lisbon). subplace(bazaar, marakesh). subplace(inn, portsmith). subplace(encampment, westphalia). subplace(tent, encampment). subplace(palace, constantinople). subplace(prison, palace). %landpaths - (X -> Y) path(westphalia, paris). path(paris, lisbon). path(paris, cadiz). path(cadiz, lisbon). path(westphalia, venice). path('buenos aires', paraguay). path(paraguay, eldorado). path(eldorado, surinam). waterpath(cadiz, marakesh). waterpath(cadiz, venice). waterpath(venice, constantinople). waterpath(paris, portsmith). waterpath(cadiz, 'buenos aires'). waterpath(surinam, lisbon). %define dual paths pathway(X, Y) :- path(X, Y). pathway(X, Y) :- path(Y, X). subpath(X, Y) :- subplace(X, Y). subpath(X, Y) :- subplace(Y, X). waterpathway(X, Y) :- waterpath(X, Y). waterpathway(X, Y) :- waterpath(Y, X). %items, takeable item(crest). item(sheep). item(sword). item(chest). item(ticket). %location of items - (item, place) location(crest, rubble). location(sheep, eldorado). location(sword, tent). location(chest, cadiz). %key people person(candide). person(sultan). person(cunegonde). person('old lady'). person(paquette). person(governor). person(martin). person(cacambo). %general people person(innkeeper). person(native). person(general). person(monk). person(vendor). %location of people - (person, place) location(candide, prison). location(sultan, palace). location(cunegonde, constantinople). location('old lady', constantinople). location(paquette, venice). location(governor, mansion). location(martin, paris). location(cacambo, cadiz). location(innkeeper, inn). location(native, eldorado). location(general, encampment). location(monk, monastary). location(vendor, arena). %---------------------------------------- %GAME COMMANDS %---------------------------------------- %looking around look :- in(Place), write('You are in '), write(Place), nl, describe(Place), write('You can talk to:'), nl, list_people(Place), write('You can see:'), nl, list_things(Place), write('You can go to:'), nl, list_subplaces(Place), nl, list_paths(Place), write('You can sail to:'), nl, list_waterpaths(Place). %listing things list_things(Place) :- location(X, Place), item(X), tab(5), write(X), nl, fail. list_things(_). list_people(Place) :- location(X, Place), person(X), tab(5), write(X), nl, fail. list_people(_). list_paths(Place) :- pathway(Place, X), tab(5), write(X), nl, fail. list_paths(_). list_waterpaths(Place) :- waterpathway(Place, X), tab(5), write(X), nl, fail. list_waterpaths(_). list_subplaces(Place) :- subplace(X, Place), tab(5), write(X), nl, fail. list_subplaces(_). %moving from one place to another (land, sea) goto(Place) :- can_go(Place), in(X), move(Place), look. goto(Place) :- can_subpath(Place), in(X), move(Place), look. goto(Place) :- place(Place), write('You can\'t go there from here'). goto(Place) :- write('Are you sure that\'s a place you can go to?'). sailto(Place) :- can_sail(Place), in(X), move(Place), look. sailto(Place) :- place(Place), write('You can\'t sail there from here'). sailto(Place) :- write('Are you sure that\'s a place?'). can_go(Place) :- in(X), pathway(X, Place). can_sail(Place) :- in(X), waterpathway(X, Place). can_subpath(Place) :- in(X), subpath(Place, X). move(Place) :- retract(in(X)), asserta(in(Place)). leave :- in(X), can_leave(X, Place), move(Place), look, nl. leave :- write('You can\'t exit to anywhere'), nl. can_leave(X, Place) :- in(X), subplace(X, Place). %taking objects take(X):- can_take(X), take_object(X), describe(X). can_take(Thing) :- in(Place), item(Thing), location(Thing, Place). can_take(Thing) :- item(Thing), have(Thing), write('You already have the '), write(Thing), nl, fail. can_take(Thing) :- not(place(Thing)), not(person(Thing)), not(subplace(Thing)), write('You cannot take something like that.'), nl, fail. can_take(Thing) :- not(have(Thing)), write('There is no '), write(Thing), write(' here'), nl, fail. take_object(X):- retract(location(X,_)), asserta(have(X)), write('You now have the '), write(X), write(' in your posession'), nl. grab(X) :- take(X). %checking inventory list_inventory :- have(X), nl, tab(5), write(X), fail. list_inventory. inventory :- write('You have: '), list_inventory, nl. %examine examine(X) :- in(Place), location(X, Place), describe(X). examine(X) :- have(X), describe(X). examine(X) :- in(X), describe(X). examine(X) :- write('You can\'t examine that'), nl. %///////////////////////////////// %DESCRIBING/EXAMINING THINGS/PLACES/PEOPLE %///////////////////////////////// %setup of quest :- story :- tab(5), write('The time had finally arrived when the gentle Candide would at last'), nl, tab(5), write('be reunited with his beloved, though now aged and ugly, Cunegonde,'), nl, tab(5), write('and in Constantinople of all places. But as it is accustomed in'), nl, tab(5), write('the best of all possible worlds, the Sultan seizes Candide and charges'), nl, tab(5), write('him with all the crimes committed in Constantinople during the last year.'), nl, tab(5), write('It is now up to you prove Candide\'s innocence by retracing his journey and'), nl, tab(5), write('validating his story of how he was to come to Constantinople.'), nl, tab(5), write('Begin by looking around. Then, visit the sultan in his palace'), nl, tab(5), write('to receive the criteria to set Candide free. Talk to Candide to hear his story'), nl, tab(5), write('If you need help, type "help." to receive in game commands. Good luck!!!.'), nl. %end of game end_game :- nl, nl, tab(5), write('CONGRATULATIONS!!!'), nl, tab(5), write('You have freed Candide from captivaty and he is now free to marry his beloved,'), nl, tab(5), write('though quite ugly, Cunegonde. They are forever greatful.'), nl, asserta(end_condition(end)). %desribe things describe(crest) :- tab(5), write('This is a damaged and dirty crest from the Baron Thunder-ten-Tronck.'), nl, tab(5), write('It is a small medal that must have adorned a wall or doorway.'), nl, tab(5), write('It is wellknown and recognized.'), nl. describe(sheep) :- tab(5), write('A real golden sheep is baa-ing lightly. It exists as a marvelous exmaple'), nl, tab(5), write('of the paradise that is El Dorado.'), nl. describe(sword) :- tab(5), write('This Bulgar sword was probably used to slaughter the Baron Thunder-ten-Tronck'), nl, tab(5), write('and his family. The seal of the Bulgar forces is marked on the hilt.'), nl. describe(chest) :- tab(5), write('This is an empty and battered chest left on a Spanish dock in Cadiz.'), nl, tab(5), write('It has Cunegonde\'s name inscribe on the lid.'), nl. describe(ticket) :- tab(5), write('It is an unsold ticket from Candide\'s Auto-de-Fe. It says on the ticket'), nl, tab(5), write('that Candide will be flogged severely for heresy.'), nl. %describe people describe(candide) :- tab(5), write('Candide is a sweetly mannered man whose hardships have worn his enormous heart.'), nl, tab(5), write('He is as kind as he is considerate, innocent as he is loyal.'), nl. describe(cunegonde) :- tab(5), write('Now in old age, Cunegonde only has the trace memories of beauty on her face.'), nl, tab(5), write('Her sufferings have been great in her life as she has been the object of'), nl, tab(5), write('many many many many many many many many many many many many many many rapes.'), nl. describe('old lady') :- tab(5), write('The Old Lady is Cunegonde\'s faithful friend and attendant. Once a beautiful'), nl, tab(5), write('Italian princess, she is now ugly.'), nl. describe(paquette) :- tab(5), write('Paquette was an enthusiastic and friendly chambermaid to the Baron\'s family'), nl, tab(5), write('She now lives in Venice where she works as a prostitute.'), nl. describe(sultan) :- tab(5), write('A large and spoiled man, the Sultan is a person of pleasures and regulations.'), nl. describe(governer) :- tab(5), write('Governor Don Fernando d’Ibaraa y Figueora y Mascarenes y Lampourdos y Souza'), nl, tab(5), write('is a hot-tempered man whose passion mirrors the climate of Buenos Aires'), nl. describe(martin) :- tab(5), write('As a scholar, Martin has preached a philosphy of unrelenting pessimism that'), nl, tab(5), write('contradicts the teachings of Pangloss. He was once Candide\'s travel companion.'), nl. describe(cacambo) :- tab(5), write('A native of the Americas, Cacambo is intelligent and honest. Through certain'), nl, tab(5), write('parts of the year, Cacambo works as a guide through the Americas.'), nl. describe(innkeeper) :- tab(5), write('This old man has been the innkeeper in Portsmith for the last twenty-three years.'), nl. describe(native) :- tab(5), write('Like the others, this native of El Dorado is kind and generous, unthreatened by differnce.'), nl. describe(general) :- tab(5), write('The general of the Bulgar Army is in peak physical condition, but his expression is disconcerning.'), nl. describe(monk) :- tab(5), write('This Jesuit monk is tired from the tropical climate and bored of the chanting.'), nl. describe(vendor) :- tab(5), write('The vendor at the arena is a woman of a certain age, tired and jaded.'), nl. %describe places describe(rubble) :- tab(5), write('The remains of the once proud castle of the Baron.'), nl. describe(bazaar) :- tab(5), write('This outdoor bazaar is bustling with people and camels.'), nl. describe(mansion) :- tab(5), write('The governor\'s mansion is as extravagant as the weather is hot.'), nl. describe(monastary) :- tab(5), write('The Jesuits live a modest and rather dull life in this monastary.'), nl. describe(arena) :- tab(5), write('An entertainment venue to Lisbon, this arena is the site of many Auto-de-Fe\'s.'), nl. describe(inn) :- tab(5), write('This quaint and cozy inn is the most interesting thing in Portsmith.'), nl. describe(encampment) :- tab(5), write('A mass of tents and horses make up the Bulgar encampment.'), nl. describe(palace) :- tab(5), write('The palace in Constantinople is adorned with many lavish tapestries and women.'), nl. describe(prison) :- tab(5), write('It is a dreary prison infested with rats and flies.'), nl. describe(tent) :- tab(5), write('This is nothing more than a modest tent.'), nl. describe(constantinople) :- tab(5), write('This Ottoman capital is filled with life. The palace towers majestically above'), nl, tab(5), write('the rest of the enchanting city.'), nl. describe(venice) :- tab(5), write('The canals in this city are breaming with gandolas. The people are kind in the'), nl, tab(5), write('Italian tradition.'), nl. describe(marakesh) :- tab(5), write('This Moroccan city is critical in trade with the North African coast.'), nl, tab(5), write('Its commerce is embodied in its open air bazaar.'), nl. describe(lisbon) :- tab(5), write('The city is in the midst of rebuilding itself after a devastating earthquake.'), nl, tab(5), write('But the inhabitants still find time for the Auto-de-Fe.'), nl. describe(cadiz) :- tab(5), write('The docks in Cadiz are populated by fisherman, sailors, and merchants.'), nl, tab(5), write('Cadiz is one of the few ports open to travel to the Americas.'), nl. describe(paris) :- tab(5), write('Known for its culture, Paris has emerged as a philosphical center of the'), nl, tab(5), write('Enlightenment. Many great philosophers such as Voltaire are French.'), nl. describe(westphalia) :- tab(5), write('This German backwater is known for, if nothing else, its rustic charm'), nl, tab(5), write('Now in ruins, the Bulgar army has lain waste to this land.'), nl. describe(portsmith) :- tab(5), write('A quaint English town, Portsmith is just a quick trip from France and the'), nl, tab(5), write('rest of the nothern coast of Europe. It\'s nothing special.'), nl. describe('buenos aires') :- tab(5), write('This South American sea port has been a center for liberal and free-trade ideas.'), nl. describe(paraguay) :- tab(5), write('As a Spanish territory, Paraguay serves as the primary site of Jesuit missions'), nl, tab(5), write('in South America. They continually fear being overrun by heathens.'), nl. describe(eldorado) :- tab(5), write('This fabled land of gold is nothing special to its inhabitants.'), nl. describe(surinam) :- tab(5), write('As a Dutch province in the Americas, it serves as a major trading post.'), nl, tab(5), write('There isn\'t much to do here but fish and contract tropical diseases.'), nl. %/////////////////////////// %TALKING TO CHARACTERS %/////////////////////////// %candide talk(candide) :- in(prison), tab(5), write('CANDIDE:'), nl, tab(5), write('Oh how I miss Madamoiselle Cunegonde, though she is plain and ugly now.'), nl, tab(5), write('And how unfortunate it is that I am tried for crimes'), nl, tab(5), write('I did not commit. But in the best of all possible worlds,'), nl, tab(5), write('I can rest, knowing that a gentle soul as yourself can prove'), nl, tab(5), write('my innocence and once again reunite me with my beloved.'), nl, tab(5), write('(beggining to cry)... Westphalia... (sob)... attacked... flogged...'), nl, tab(5), write('(gasp)... robbed... New World... (wimper)... sheep... Venice... (sniffle)...'), nl. %cunegonde talk(cunegonde) :- in(constantinople), tab(5), write('CUNEGONDE:'), nl, tab(5), write('My dear Candide is locked away, and we are once again'), nl, tab(5), write('separated by this cruel world. You must go and find our serving maid,'), nl, tab(5), write('Paquette, for surely she can aid us. If only our wise teacher could be,'), nl, tab(5), write('here now to guide us in another time of need.'), nl. %old lady talk('old lady') :- in(constantinople), tab(5), write('OLD LADY:'), nl, tab(5), write('How my mistress worries for her beloved and after so many'), nl, tab(5), write('hardships and sufferings passed. Oy-yoy-yoy, what world could'), nl, tab(5), write('subject hearts so good and so pure to this incessent torture.'), nl. %paquette talk(paquette) :- in(venice), tab(5), write('PAQUETTE:'), nl, tab(5), write('So Master Candide is in distress? Locked in a prison in'), nl, tab(5), write('Constantinople? How can I be sure that is the truth?'), nl, tab(5), write('You will need to show me that you are a trusted family friend.'), nl. %governor talk(governor) :- in('mansion'), tab(5), write('GOVERNOR:'), nl, tab(5), write('This Candide is the companion of the lovely Cunegonde as I recall.'), nl, tab(5), write('She was a fine lady but I remember little of Candide. If I am correct,'), nl, tab(5), write('I believe he fled into the heart of Paraguay.'), nl. %sultan talk(sultan) :- in(palace), tab(5), write('SULTAN:'), nl, tab(5), write('This Candide fellow is surely responsible for all the crimes that have'), nl, tab(5), write('been committed in Constantinople in the last few years, after all, he is a foreigner.'), nl, tab(5), write('But if you can show me that he was nowhere near Constantinople then I will'), nl, tab(5), write('release him. Five pieces of evidence is adequate proof.'), nl. %cacambo talk(cacambo) :- in(cadiz), tab(5), write('CACAMBO:'), nl, tab(5), write('Master Candide is a good man and I am saddened by his imprisonment.'), nl, tab(5), write('If you can prove the validity of his story in the Americas. I\'d gladly take'), nl, tab(5), write('you if I wasn\'t taking my vacation here in Cadiz.'), nl. %martin talk(martin) :- in(paris), tab(5), write('MARTIN:'), nl, tab(5), write('Candide once mentioned how he was flogged in Portugal. He was blamed'), nl, tab(5), write('for the Lisbon earthquake, as an outsider of course. Perhaps something'), nl, tab(5), write('can be found there to assist him in his current predicament.'), nl. %innkeeper talk(inkeeper) :- in(inn), tab(5), write('INNKEEPER:'), nl, tab(5), write('I must apologize but we have no current vacancies.'), nl. %native talk(native) :- in(eldorado), tab(5), write('NATIVE:'), nl, tab(5), write('It\'s a simple life here in El Dorado. Sometimes we slip on the gold roads'), nl, tab(5), write('and sometimes the gold sheep run off into the hills. You are free to take a'), nl, tab(5), write('sheep as a memento of your time here.'), nl. %monk talk(monk) :- in(monastary), tab(5), write('MONK:'), nl, tab(5), write('Candide was sent here to protect us from heathens. If memory serves, I think'), nl, tab(5), write('he was directly responsible for the death of one of our brethren but no harm done.'), nl, tab(5), write('He was rather bothersome. We didn\'t care for him much.'), nl. %general talk(general) :- in(encampment), tab(5), write('GENERAL:'), nl, tab(5), write('I\'ve realized how unfulfilling pillaging and burning is in my life.'), nl, tab(5), write('Perhaps I will go East and search for enlightment. No longer do I need'), nl, tab(5), write('any of my warrior equipment. You are free to take what you wish from my tent.'), nl. %vendor talk(vendor) :- in(arena), have(ticket), tab(5), write('VENDOR:'), nl, tab(5), write('I\'m sorry but it looks like this evening\'s show is sold out.'), nl. talk(vendor) :- in(arena), tab(5), write('VENDOR:'), nl, tab(5), write('The name Candide seems familiar. Oh, he was Auto-de-Fe\'ed some time ago.'), nl, tab(5), write('I believe I have a left over ticket of that event. You can have it.'), nl, asserta(have(ticket)), write('You now have the ticket in your posession'), nl. %//////////////////////////// %SHOWING CHARACTERS ITEMS %//////////////////////////// show :- in(palace), have(crest), have(sword), have(chest), have(sheep), have(ticket), tab(5), write('SULTAN:'), nl, tab(5), write('So I see that you have brought me five pieces of evidence.'), nl, tab(5), write('I will release this Candide fellow from my prison though'), nl, tab(5), write('I must now find another way to meet my prison quotas.'), nl, end_game. show :- in(venice), have(crest), tab(5), write('PAQUETTE:'), nl, tab(5), write('That is the crest of the Baron so you must be telling the truth'), nl, tab(5), write('about dear Master Candide. I am certain you can talk to some friends'), nl, tab(5), write('in the New World to clear my dear Master\'s name.'), nl. %///////////////////////// %HELP COMMAND %///////////////////////// help :- tab(5), write('GAME COMMANDS:'), nl, tab(5), write('help. - Receive a list of in game commands.'), nl, tab(5), write('look. - Look around your present location.'), nl, tab(5), write('inventory. - List all your posessions.'), nl, tab(5), write('examine X. - Receive a description of something.'), nl, tab(5), write('go to X. - Go by land to this location.'), nl, tab(5), write('leave. - Leave an enclosed area to go outside.'), nl, tab(5), write('sail to X. - Sail to this location.'), nl, tab(5), write('talk to X. - Talk to someone.'), nl, tab(5), write('show. - Show nearby people your inventory.'), nl, tab(5), write('take X. - Take an item into your inventory.'), nl, tab(5), write('quit. - Quit the game.'), nl. %initial game conditions in(constantinople). %/////////////////////////////////// %MAIN - STARTS GAME AND ACTIVATES LANGUAGE PARSER %////////////////////////////////// start :- main. main :- write('Welcome to SAVE CANDIDE'), nl, story, repeat, write('>command: '), get_command(X), %read(X), do(X), nl, end_condition(end). %////////////////////////////////// %LANGUAGE PARSING CODE FROM AMZI %/////////////////////////////////// % End of rules for the game. The rest of the rules are for % simple natural language processing of the commands. % The following code was written by Amzi! inc. for reading a % whole line of text and converting it into a list. See: % http://www.amzi.com/AdventureInProlog/index.htm read_list(L) :- read_line(CL), wordlist(L,CL,[]), !. read_line(L) :- get0(C), buildlist(C,L). buildlist(46,[]) :- !. buildlist(C,[C|X]) :- get0(C2), buildlist(C2,X). wordlist([X|Y]) --> word(X), whitespace, wordlist(Y). wordlist([X]) --> whitespace, wordlist(X). wordlist([X]) --> word(X). wordlist([X]) --> word(X), whitespace. word(W) --> charlist(X), {name(W,X)}. charlist([X|Y]) --> chr(X), charlist(Y). charlist([X]) --> chr(X). chr(X) --> [X],{X>=48}. whitespace --> whsp, whitespace. whitespace --> whsp. whsp --> [X], {X<48}. % end of the code from Amzi! inc. % The elim predicate takes out the words "to" and "the" from % a list. We don't need them to process commands. elim(CL, [V,to,the,N]) :- CL = [V,N], !. elim(CL, [V,to,N]) :- CL = [V,N], !. elim(CL,[V,the,N]) :- CL = [V,N], !. elim(CL,[V,to,the,old,lady]) :- CL = [V,'old lady'], !. elim(CL,[V,to,old,lady]) :- CL = [V,'old lady'], !. elim(CL,[V,the,old,lady]) :- CL = [V,'old lady'], !. elim(CL,[V,old,lady]) :- CL = [V,'old lady'], !. elim(CL,[V,to,the,buenos,aires]) :- CL = [V,'buenos aires'], !. elim(CL,[V,to,buenos,aires]) :- CL = [V,'buenos aires'], !. elim(CL,[V,the,buenos,aires]) :- CL = [V,'buenos aires'], !. elim(CL,[V,buenos,aires]) :- CL = [V,'buenos aires'], !. elim(CL,Y) :- CL = Y. command(CL,L) :- CL =.. L, !. command(CL,L) :- L = [LH|_], elim(NL,LH), CL =.. NL, !. get_command(C) :- read_list(L), command(C,L), !. get_command(_) :- write('I don''t understand that command'), nl, fail. do(goto(X)) :- goto(X),!. do(go(X)) :- goto(X),!. do(inventory) :- inventory,!. do(look) :- look,!. do(sailto(X)) :- sailto(X),!. do(sail(X)) :- sailto(X),!. do(take(X)) :- take(X), !. do(talk(X)) :- talk(X), !. do(leave) :- leave, !. do(leave(X)) :- leave, !. do(show) :- show, !. do(show(X)) :- show, !. do(help) :- help, !. do(examine(X)) :- examine(X), !. do(quit) :- asserta(end_condition(end)). do(end). do(_) :- write('I don''t understand that command. Type "help." for assistance.'), nl, !.