--- /dev/null
+============================
+ William Tell: in his prime
+============================
+
+.. highlight:: inform6
+
+.. epigraph::
+
+ | *O was an oyster girl, and went about town;*
+ | *P was a parson, and wore a black gown.*
+
+.. only:: html
+
+ .. image:: /images/picO.png
+ :align: left
+
+.. raw:: latex
+
+ \dropcap{o}
+
+ur game's action nears its climax in the town's central square. In this
+chapter we define the square's constituent rooms and deal with Wilhelm's
+approach to the hat on the pole -- does he salute it, or does he remain
+proudly defiant?
+
+The south side of the square
+============================
+
+The town square, notionally one enormous open space, is represented by
+three rooms. Here's the south side::
+
+ Room south_square "South side of the square"
+ with description
+ "The narrow street to the south has opened onto the town square,
+ and resumes at the far side of this cobbled meeting place.
+ To continue along the street towards your destination --
+ Johansson's tannery -- you must walk north across the square,
+ in the middle of which you see Gessler's hat set on that
+ loathsome pole. If you go on, there's no way you can avoid
+ passing it. Imperial soldiers jostle rudely through the throng,
+ pushing, kicking and swearing loudly.",
+ n_to mid_square,
+ s_to below_square;
+
+ Prop "hat on a pole"
+ with name 'hat' 'pole',
+ before [;
+ default:
+ print_ret "You're too far away at the moment.";
+ ],
+ found_in south_square north_square;
+
+ Prop "Gessler's soldiers"
+ with name 'soldier' 'soldiers' 'guard' 'guards',
+ description "They're uncouth, violent men, not from around here.",
+ before [;
+ FireAt:
+ print_ret "You're outnumbered many times.";
+ Talk:
+ print_ret "Such scum are beneath your contempt.";
+ ],
+ found_in south_square mid_square north_square marketplace,
+ has animate pluralname proper;
+
+It's all pretty standard stuff: just a ``Room`` and two ``Prop``\s. The
+"real" pole object is located in the ``mid_square`` room, which means that
+players can't EXAMINE it from this room (technically, it's "not in scope").
+However, since we're pretending that Wilhelm can see the whole of the
+square from where he's standing, we need to provide a dummy hat on a pole,
+``found_in`` both this room and the north side of the square, even if it's
+"too far away" for a detailed description.
+
+In fact, it's "too far away" for anything. We've replaced the standard
+``before`` action for the ``Prop`` class (which permits ``Examine``, but
+rejects other actions with "You don't need to worry about...") with one
+rejecting *all* actions. Since Wilhelm's hatred of the vogt's activities
+is central to our plot, a message saying "You don't need to worry about the
+hat" would be unacceptably misleading.
+
+The obnoxious soldiers are also implemented very sketchily; they need to be
+there, but they don't do much. Their most interesting characteristic is
+probably that they trap two actions -- ``FireAt`` and ``Talk`` -- which are
+*not* part of the library, but instead new actions that we've defined
+specially for this game. We'll talk about those actions in "Verbs, verbs,
+verbs" on page 111, at which time the role of this ``before`` property will
+make more sense.
+
+The middle of the square
+========================
+
+The activities here are pivotal to the game's plot. Wilhelm has arrived
+from the south side of the square, and now encounters the pole with the hat
+on top. He can do three things:
+
+#. Return south. That's allowed, but all it does is waste a little time --
+ there's nothing else to usefully do south of here.
+
+#. Salute the pole, and then proceed to the north. That's allowed, though
+ it rather subverts the folk story.
+
+#. Attempt to proceed northwards without saluting the pole. Twice, a
+ soldier will prevent this, and issue a verbal warning. On the third
+ attempt, patience runs out, and Wilhelm is hauled off to perform his
+ party piece.
+
+So, there are two actions that we need to look out for: ``Salute`` (trapped
+by the pole), and ``Go`` (which can be trapped by the room itself). ``Go``
+is a standard library action. ``Salute`` is one that we've devised; let's
+deal with it first. Here's a first cut of the room::
+
+ Room mid_square "Middle of the square"
+ with description
+ "There is less of a crush in the middle of the square; most
+ people prefer to keep as far away as possible from the pole
+ which towers here, topped with that absurd ceremonial hat. A
+ group of soldiers stands nearby, watching everyone who passes.",
+ n_to north_square,
+ s_to south_square;
+
+and the pole::
+
+ Furniture pole "hat on a pole" mid_square
+ with name 'wooden' 'pole' 'pine' 'hat' 'black' 'red' 'brim' 'feathers',
+ description
+ "The pole, the trunk of a small pine some few inches in diameter,
+ stands about nine or ten feet high. Set carefully on top is
+ Gessler's ludicrous black and red leather hat, with a widely
+ curving brim and a cluster of dyed goose feathers.",
+ has_been_saluted false,
+ before [;
+ FireAt:
+ print_ret "Tempting, but you're not looking for trouble.";
+ Salute:
+ self.has_been_saluted = true;
+ print_ret "You salute the hat on the pole. ^^
+ ~Why, thank you, sir,~ sneers the soldier.";
+ ],
+ has scenery;
+
+The room will need some more work in a minute, but the pole object is
+complete (note that we've simplified matters slightly by making one object
+represent both the pole and the hat which it supports). It mentions a
+property which we've not met before: ``has_been_saluted``. What a
+remarkable coincidence: the library provides a property with a name that's
+exactly right for our game; surely not?
+
+No, of course not. ``has_been_saluted`` isn't a standard library property;
+it's one that we've just invented. Notice how easily we did it -- we
+simply included the line::
+
+ has_been_saluted false,
+
+in the object definition and voilĂ , we've added our own home-made property,
+and initialised it to ``false``. To switch the state of the property, we
+can simply write::
+
+ pole.has_been_saluted = true;
+ pole.has_been_saluted = false;
+
+or just (within the pole object)::
+
+ self.has_been_saluted = true;
+ self.has_been_saluted = false;
+
+We could also test, if necessary, how the property currently fares::
+
+ if (pole.has_been_saluted == true) ...
+
+and that is exactly what we'll be doing in a minute to check whether
+Wilhelm has saluted the pole, and choose between different outcomes.
+
+Notice that we use ``==`` (that's two equals signs) to test for "is equal
+to"; don't confuse this usage with ``=`` (a single equals sign) which
+assigns a value to a variable. Compare these examples:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 1 1
+
+ * - Correct
+ - Incorrect
+
+ * - ``score = 10;``
+ - ``score == 10;``
+
+ * - assigns the value 10 to ``score``
+ - does nothing; ``score`` is unchanged
+
+ * - ``if (score == 10) ...``
+ - ``if (score = 10) ...``
+
+ * - executes the next statement only if the value of ``score`` is 10
+ - assigns 10 to ``score``, then always executes the next statement --
+ because ``score = 10`` evaluates to 10, which is treated as
+ ``true``, so the test is always ``true``
+
+Defining a new property variable which, instead of applying to every object
+in the game (as do the standard library properties), is specific only to a
+class of objects or even -- as here -- to a single object, is a common and
+powerful technique. In this game, we need a ``true/false`` variable to
+show whether Wilhelm has saluted the pole or not: the clearest way is to
+create one as part of the pole. So, when the pole object traps the Salute
+action, we do two things: use a ``self.has_been_saluted = true`` statement
+to record the fact, and then use a ``print_ret`` statement to tell players
+that the salute was "gratefully" received.
+
+.. note::
+
+ Creating new property variables like this -- at the drop of a hat, as it
+ were -- is the recommended approach, but it isn't the only possibility.
+ We briefly mention some alternative approaches in "Reading other
+ people's code" on page 181.
+
+Back to the ``mid_square`` room. We've said that we need to detect Wilhelm
+trying to leave this room, which we can do by trapping the ``Go`` action in
+a ``before`` property. Let's sketch the coding we'll need::
+
+ before [;
+ Go:
+ if (noun == s_obj) { Wilhelm is trying to move south }
+ if (noun == n_obj) { Wilhelm is trying to move north }
+ ];
+
+We can easily trap the ``Go`` action, but which direction is he moving?
+Well, it turns out that the interpreter turns a command of GO SOUTH (or
+just SOUTH) into an action of ``Go`` applied to an object ``s_obj``. This
+object is defined by the library; so why isn't it called just "``south``"?
+Well, because we already have another kind of south, the property ``s_to``
+used to say what lies in a southerly direction when defining a room. To
+avoid confusing them, ``s_to`` means "south to" and ``s_obj`` means "south
+when the player types it as the object of a verb".
+
+The identity of the object which is the target of the current action is
+stored in the ``noun`` variable, so we can write the statement ``if (noun
+== s_obj)`` to test whether the contents of the ``noun`` variable are equal
+to the ID of the ``s_obj`` object -- and, if so, Wilhelm is trying to move
+south. Another similar statement tests whether he's trying to move north,
+and that's all that we're interested in; we can let other movements take
+care of themselves.
+
+The words :samp:`{Wilhelm is trying to move south}` aren't part of our
+game; they're just a temporary reminder that, if we need to execute any
+statements in this situation, here's the place to put them. Actually,
+that's the simpler case; it's when :samp:`{Wilhelm is trying to move
+north}` that the fun starts. We need to behave in one of two ways,
+depending on whether or not he's saluted the pole. But we *know* when he's
+done that; the pole's ``has_been_saluted`` property tells us. So we can
+expand our sketch like this::
+
+ before [;
+ Go:
+ if (noun == s_obj) { Wilhelm is trying to move south [1] }
+ if (noun == n_obj) { Wilhelm is trying to move north...
+ if (pole.has_been_saluted == true)
+ { ...and he's saluted the pole [2] }
+ else { ...but he hasn't saluted the pole [3] }
+ }
+ ];
+
+Here we have one ``if`` statement nested inside another. And there's more:
+the inner ``if`` has an ``else`` clause, meaning that we can execute one
+statement block when the test ``if (pole.has_been_saluted == true)`` is
+true, and an alternative block when the test isn't true. Read that again
+carefully, checking how the braces ``{...}`` pair up; it's quite complex,
+and you need to understand what's going on. One important point to
+remember is that, unless you insert braces to change this, an ``else``
+clause always pairs with the most recent ``if``. Compare these two
+examples::
+
+ if (condition1) {
+ if (condition2) { here when condition1 is true and condition2 is true }
+ else { here when condition1 is true and condition2 is false }
+ }
+
+ if (condition1) {
+ if (condition2) { here when condition1 is true and condition2 is true }
+ }
+ else { here when condition1 is false }
+
+In the first example, the ``else`` pairs with the most recent :samp:`if
+({condition2})`, whereas in the second example the revised positioning of
+the braces causes the ``else`` to pair with the earlier :samp:`if
+({condition1})`.
+
+.. note::
+
+ We've used indentation as a visual guide to how the ``if`` and ``else``
+ are related. Be careful, though; the compiler matches an ``else`` to
+ its ``if`` purely on the basis of logical grouping, regardless of how
+ you've laid out the code.
+
+Back to the before property. You should be able to see that the cases
+marked ``[1]``, ``[2]`` and ``[3]`` correspond to the three possible
+courses of action we listed at the start of this section. Let's write the
+code for those, one at a time.
+
+.. rubric:: Case 1: Returning south
+
+First, :samp:`{Wilhelm is trying to move south}`; not very much to this::
+
+ warnings_count 0, ! for counting the soldier's warnings
+ before [;
+ Go:
+ if (noun == s_obj) {
+ self.warnings_count = 0;
+ pole.has_been_saluted = false;
+ }
+ if (noun == n_obj) {
+ if (pole.has_been_saluted == true)
+ { moving north...and he's saluted the pole }
+ else { moving north...but he hasn't saluted the pole }
+ }
+ ];
+
+Wilhelm might wander into the middle of the square, take one look at the
+pole and promptly return south. Or, he might make one or two (but not
+three) attempts to move north first, and then head south. *Or*, he might
+be really perverse, salute the pole and only then head south. In all of
+these cases, we take him back to square one, as though he'd received no
+soldier's warnings (irrespective of how many he'd actually had) and as
+though the pole had not been saluted (irrespective of whether it was or
+not). In effect, we're pretending that the soldier has such a short
+memory, he'll completely forget Wilhelm if our hero should move away from
+the pole.
+
+To do all this, we've added a new property and two statements. The
+property is ``warnings_count``, and its value will count how many times
+Wilhelm has tried to go north without saluting the pole: 0 initially, 1
+after his first warning, 2 after his second warning, 3 when the soldier's
+patience finally runs out. The property ``warnings_count`` isn't a
+standard library property; like the pole's ``has_been_saluted`` property,
+it's one that we've created to meet a specific need.
+
+Our first statement is ``self.warnings_count = 0``, which resets the value
+of the ``warnings_count`` property of the current object -- the
+``mid_square`` room -- to 0. The second statement is
+``pole.has_been_saluted = false``, which signifies that the pole has not be
+saluted. That's it: the soldier's memory is erased, and Wilhelm's actions
+are forgotten.
+
+.. rubric:: Case 2: Moving north after saluting
+
+:samp:`{Wilhelm is moving north...and he's saluted the pole}`; another easy
+one::
+
+ warnings_count 0, ! for counting the soldier's warnings
+ before [;
+ Go:
+ if (noun == s_obj) {
+ self.warnings_count = 0;
+ pole.has_been_saluted = false;
+ }
+ if (noun == n_obj) {
+ if (pole.has_been_saluted == true) {
+ print "^~Be sure to have a nice day.~^";
+ return false;
+ }
+ else { moving north...but he hasn't saluted the pole }
+ }
+ ];
+
+All that we need do is print a sarcastic goodbye from the soldier, and then
+``return false``. You'll remember that doing so tells the interpreter to
+continue handling the action, which in this case is an attempt to move
+north. Since this is a permitted connection, Wilhelm thus ends up in the
+``north_square`` room, defined shortly.
+
+.. rubric:: Case 3: Moving north before saluting
+
+So that just leaves the final case: :samp:`{moving north...but he hasn't
+saluted the pole}`. This one has more to it than the others, because we
+need the "three strikes and you're out" coding. Let's sketch a little
+more::
+
+ warnings_count 0, ! for counting the soldier's warnings
+ before [;
+ Go:
+ if (noun == s_obj) {
+ self.warnings_count = 0;
+ pole.has_been_saluted = false;
+ }
+ if (noun == n_obj) {
+ if (pole.has_been_saluted == true) {
+ print "^~Be sure to have a nice day.~^";
+ return false;
+ }
+ else {
+ self.warnings_count = self.warnings_count + 1;
+ switch (self.warnings_count) {
+ 1: First attempt at moving north
+ 2: Second attempt at moving north
+ default: Final attempt at moving north
+ }
+ }
+ }
+ ];
+
+First of all, we need to count how many times he's tried to move north.
+``self.warnings_count`` is the variable containing his current tally, so we
+add 1 to whatever value it contains: ``self.warnings_count =
+self.warnings_count + 1``. Then, determined by the value of the variable,
+we must decide what action to take: first attempt, second attempt, or final
+confrontation. We could have used three separate ``if`` statements::
+
+ if (self.warnings_count == 1) { First attempt at moving north }
+ if (self.warnings_count == 2) { Second attempt at moving north }
+ if (self.warnings_count == 3) { Final attempt at moving north }
+
+or a couple of nested ``if`` statements::
+
+ if (self.warnings_count == 1) { First attempt at moving north }
+ else {
+ if (self.warnings_count == 2) { Second attempt at moving north }
+ else { Final attempt at moving north }
+ }
+
+but for a series of tests all involving the same variable, a ``switch``
+statement is usually a clearer way of achieving the same effect. The
+generic syntax for a ``switch`` statement is::
+
+ switch (expression) {
+ value1: whatever happens when the expression evaluates to value1
+ value2: whatever happens when the expression evaluates to value2
+ ...
+ valueN: whatever happens when the expression evaluates to valueN
+ default: whatever happens when the expression evaluates to something else
+ }
+
+This means that, according to the current value of an expression, we can
+get different outcomes. Remember that the :samp:`{expression}` may be a
+``Global`` or local variable, an object's property, one of the variables
+defined in the library, or any other expression capable of having more than
+one value. You could write ``switch (x)`` if ``x`` is a defined variable,
+or even, for instance, ``switch (x+y)`` if both ``x`` and ``y`` are defined
+variables. Those :samp:`{whatever happens when...}` are collections of
+statements which implement the desired effect for a particular value of the
+switched variable.
+
+Although a switch statement :samp:`switch ({expression}) { ... }` needs
+that one pair of braces, it doesn't need braces around each of the
+individual "cases", no matter how many statements each of them includes.
+As it happens, case 1 and case 2 contain only a single ``print_ret``
+statement each, so we'll move swiftly past them to the third, more
+interesting, case -- when ``self.warnings_count`` is 3. Again, we could
+have written this::
+
+ switch (self.warnings_count) {
+ 1: First attempt at moving north
+ 2: Second attempt at moving north
+ 3: Final attempt at moving north
+ }
+
+but using the word ``default`` -- meaning "any value not already catered
+for" -- is better design practice; it's less likely to produce misleading
+results if for some unforeseen reason the value of ``self.warnings_count``
+isn't the 1, 2 or 3 you'd anticipated. Here's the remainder of the code
+(with some of the printed text omitted)::
+
+ self.warnings_count = self.warnings_count + 1;
+ switch (self.warnings_count) {
+ 1: print_ret "...";
+ 2: print_ret "...";
+ default:
+ print "^~OK, ";
+ style underline; print "Herr"; style roman;
+ print " Tell, now you're in real trouble. I asked you
+ ...
+ old lime tree growing in the marketplace.^";
+ move apple to son;
+ PlayerTo(marketplace);
+ return true;
+ }
+
+The first part is really just displaying a lot of text, made slightly
+messier because we're adding emphasis to the word "Herr" by using
+underlining (which actually comes out as *italic type* on most
+interpreters). Then, we make sure that Walter has the apple (just in case
+we didn't give it to him earlier in the game), relocate to the final room
+using ``PlayerTo(marketplace)``, and finally ``return true`` to tell the
+interpreter that we've handled this part of the ``Go`` action ourselves.
+And so, at long last, here's the complete code for the ``mid_square``, the
+most complicated object in the whole game::
+
+ Room mid_square "Middle of the square"
+ with description
+ "There is less of a crush in the middle of the square; most
+ people prefer to keep as far away as possible from the pole
+ which towers here, topped with that absurd ceremonial hat. A
+ group of soldiers stands nearby, watching everyone who passes.",
+ n_to north_square,
+ s_to south_square,
+ warnings_count 0, ! for counting the soldier's warnings
+ before [;
+ Go:
+ if (noun == s_obj) {
+ self.warnings_count = 0;
+ pole.has_been_saluted = false;
+ }
+ if (noun == n_obj) {
+ if (pole.has_been_saluted == true) {
+ print "^~Be sure to have a nice day.~^";
+ return false;
+ } ! end of (pole has_been_saluted)
+ else {
+ self.warnings_count = self.warnings_count + 1;
+ switch (self.warnings_count) {
+ 1: print_ret "A soldier bars your way. ^^
+ ~Oi, you, lofty; forgot yer manners, didn't you?
+ How's about a nice salute for the vogt's hat?~";
+ 2: print_ret "^~I know you, Tell, yer a troublemaker,
+ ain't you? Well, we don't want no bovver here,
+ so just be a good boy and salute the friggin'
+ hat. Do it now: I ain't gonna ask you again...~";
+ default:
+ print "^~OK, ";
+ style underline; print "Herr"; style roman;
+ print " Tell, now you're in real trouble. I asked you
+ nice, but you was too proud and too stupid. I
+ think it's time that the vogt had a little word
+ with you.~
+ ^^
+ And with that the soldiers seize you and Walter
+ and, while the sergeant hurries off to fetch
+ Gessler, the rest drag you roughly towards the
+ old lime tree growing in the marketplace.^";
+ move apple to son;
+ PlayerTo(marketplace);
+ return true;
+ } ! end of switch
+ } ! end of (pole has_NOT_been_saluted)
+ } ! end of (noun == n_obj)
+ ];
+
+The north side of the square
+============================
+
+The only way to get here is by saluting the pole and then moving north; not
+very likely, but good game design is about predicting the unpredictable. ::
+
+ Room north_square "North side of the square"
+ with description
+ "A narrow street leads north from the cobbled square. In its
+ centre, a little way south, you catch a last glimpse of the pole
+ and hat.",
+ n_to [;
+ deadflag = 3;
+ print_ret "With Walter at your side, you leave the square by the
+ north street, heading for Johansson's tannery.";
+ ],
+ s_to "You hardly feel like going through all that again.";
+
+There's one new feature in this room: the value of the ``n_to`` property is
+a routine, which the interpreter runs when Wilhelm tries to exit the square
+northwards. All that the routine does is set the value of the library
+variable ``deadflag`` to 3, print a confirmation message, and ``return
+true``, thus ending the action.
+
+At this point, the interpreter notices that ``deadflag`` is no longer zero,
+and terminates the game. In fact, the interpreter checks ``deadflag`` at
+the end of every turn; these are the values that it's expecting to find:
+
+* 0 -- this is the normal state; the game continues.
+* 1 -- the game is over. The interpreter displays "You have died".
+* 2 -- the game is over. The interpreter displays "You have won".
+* any other value -- the game is over, but there aren't any appropriate
+ messages built into the library. Instead, the interpreter looks for an
+ **entry point** routine called ``DeathMessage`` -- which we must provide
+ -- where we can define our own tailored "end messages".
+
+In this game, we never set ``deadflag`` to 1, but we do use values of 2
+and 3. So we'd better define a ``DeathMessage`` routine to tell players
+what they've done::
+
+ [ DeathMessage; print "You have screwed up a favourite folk story"; ];
+
+Our game has only one customised ending, so the simple ``DeathMessage``
+routine we've written is sufficient for our purposes. Were you to conceive
+multiple endings for a game, you could specify suitable messages by
+checking for the current value of the ``deadflag`` variable::
+
+ [ DeathMessage;
+ if (deadflag == 3) print "You leave Scarlett O'Hara for good";
+ if (deadflag == 4) print "You crush Scarlett with a passionate embrace";
+ if (deadflag == 5) print "You've managed to divorce Scarlett";
+ ...
+ ];
+
+Of course, you must assign the appropriate value to ``deadflag`` at the
+point when the game arrives at each of those possible endings.
+
+We've nearly finished. In the concluding chapter of this game, we'll talk
+about the fateful shooting of the arrow.