While I have since written a number of Prolog programs, I was first drawn to Prolog while I was in the middle of writing, for fun, an adventure game in program by building the basic tools needed for the game, which included a dynamic database to record the changing state of the game, and the ability to search for symbolic patterns in the state that indicated some action needed to be taken. The action was usually represented by a message to the user and a change of state of the game.
Because of all of this procedural power built into the language, the code the programmer writes looks much more declarative. An application, such as my adventure game, winds up being reduced to an elegant set of logical declarations describing what the program does. (Developers often claim up to a 10-fold reduction in code size going to Prolog. See for example the PCAI article on KnowledgeWare`s use of Prolog in the May/June 1993 issue.) For me, this was truly a fun way to program, capturing the essence of the joy of programming-building logical structures that perform interesting tasks.
While in retrospect, the power of Prolog for writing adventure games might be obvious, think of how many other applications contain elements of remembering program state, searching for pattern matches in that state and taking conditional actions based on them. Further, how many of us think of our programs in logical terms, declaratively at first, and then spend the time translating that into procedural code?
The applications described are an adventure game, a part of an object? oriented program shell, a game based on a decision tree, and taxes (yes, even taxes are fun in Prolog).
This is a skeleton adventure game in which the object is to go from the house, across the yard, to the duck pen to fetch a duck egg, being careful not to let the fox get any of the ducks.
Now that the basic state is defined, the commands that manipulate the state can be added. The fundamental operation in an adventure game is moving about, so we first implement a goto command that will move you from where you are to where you want to be, if you can get there.
The fun part of any adventure game is the various side effects, or demons. Here are two for this game. If you enter the duck pen, and the gate is open, then the ducks will go into the yard, and, the fox is in the woods waiting for the ducks to be accessible and unguarded.
Prolog was originally designed for natural language work, and is excellent for that, but it is also ideal for experimenting with different ideas for computer languages. For example, Prolog can be used to implement an object?oriented programming extension to itself. Here are a few lines of code that implement polymorphism much better than C++ does. (Polymorphism is the ability of different types of objects to respond to the same message.)
To implement polymorphism we will write a predicate, oo_send/2 which sends a message to an object. For an example we will define classes of objects corresponding to geometric shapes, and methods for each shape to compute it`s area and perimeter. To do this we first need to define structures to represent the classes.
Note how powerful unification is in this example. The variable Ms becomes unified with the whole complex list of methods for the given object, and, despite being passed to member, the relationship between all the logical variables is preserved so the right answer winds up in the variable used in the message.
This simple example can be expanded to include multiple inheritance, flavors, persistent objects and any thing else you might desire in an OOP system. As with the adventure game example, the code will continue to look like a logical specification of an OOP system.
An object`s Setup tab lets you choose the type of object. Select the “TV” object we created in the last section.
Rooms and objects are really the same thing in Quest - the option you select here simply lets the editor show you only what`s relevant for the current object. If you wanted to create a cupboard inside a room that the player could get in, you might want to select “object and/or room” here - but in this tutorial, just leave this option set to the default.
Whichever type you select, the object will behave in pretty much the same way, except that Quest`s default responses will make a lot more sense if you set this correctly. This is because setting the type will update the Gender and Article (you can also override these manually).
The “Scenery” option means that the object won’t be displayed automatically in the room description, or the “Places and Objects” on the right of the screen.
Although the wallpaper isn’t an important object, we should still have a response for “look at wallpaper”. If we make it a scenery object, it`s “in the background” as far as the game goes, as it won’t appear in the “Places and Objects” list, or in the list of objects in the description of the room. We won’t be cluttering things unnecessarily, but we will still be providing responses for anything the player might reasonably type in.
So, create a new object called “wallpaper” and tick the Scenery box. Enter a description like “The horrible beige wallpaper hangs loosely on the walls.”
Remember that we also mentioned the carpet in the room description as well. As an exercise, add this as another scenery object, and give it a sensible description.
Create a new object called “Bob” and change his type to “Male character”. Give him a “look” description of “Bob is lying on the floor, a lot more still than usual.”
A prefix and a suffix let you insert text before and after the object name when it`s displayed in a room description. When you leave “Use default prefix and suffix” checked, the suffix is blank, and the prefix (for English games) is either “a” or “an” depending on whether the object name (or alias) begins with a vowel.
You can specify your own text by unchecking the box. Two new textboxes will appear, and for our “Bob” character you can just leave them blank, as we don’t want any text added around our object name.
You should have added a newspaper object as an exercise at the end of the previous section. If you didn’t, add one now. We’re going to make this an object that the player can take.
Default behaviour: You’ll want to use this for most of your take-able objects. This option gives you the “Object can be taken” checkbox, and the ability to specify a “take message” which is printed when the player takes (or attempts to take) the object.
Run script: If you want full control over what happens when the player attempts to take the object, choose this option. We will cover scripts later on in the tutorial, so don’t choose this for now.
We offer adventure objects
adventure objects, adventure, objects,