! Here's the illustrious source for my game, "The Chicken Under the
! Window". You should be able to find the game itself somewhere within:
!
ftp://ftp.gmd.de/if-archive/games/mini-comps/
! Note that I hacked the libraries a bit--if you want to fully replicate
! the .z5 game, you'll have to do the following:
! In Grammar.h: Delete all verb information except for the meta
! verbs (but delete score, brief, verbose, and superbrief)
! In parserm.h: Delete lines 3743-6 (deadflag==1 stuff) and replace with
! print "^"; Also, delete a couple ^'s from line 3748, and the ScoreSub()
! line.
! In verblibm.h: Comment or delete lines 1331 through 1345 (beginning
! with 'style bold;' and ending with 'new_line;'
! That's it! Happy Clucking!
Constant Story "The Chicken Under The Window";
Constant Headline "^An Interactive Farce^
If you don't get it, type ABOUT.^
Copyright (c) 1998 by Lucian Smith.^";
Release 2;
Constant DEATH_MENTION_UNDO;
Replace DrawStatusLine;
Include "Parser";
Include "VerbLib";
Include ">style.h";
[ Initialise;
ChangePlayer(Handle);
location = Here;
lookmode=2;
"^";
];
Global typed_word;
[ UnknownVerb word x n i flag;
typed_word = 0;
objectloop(x in location)
{
n = x.&name;
if (n~=0)
{
for (i=0:(2*i)<x.#name:i++)
{
if (word==n-->i)
{
typed_word = x;
flag++;
}
}
}
}
#ifdef DEBUG;
if (flag>1) print "^Warning: ", (number) flag, " words matched.^";
#endif;
if (typed_word)
{
return 'sutw,style';
}
else return 'unknown,';
];
[ DrawStatusLine width posb;
@split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
width = 0->33;
spaces (width);
posb = (width/2) - 14;
if (posb<2) posb=2;
@set_cursor 1 posb; PrintShortName(location);
@set_cursor 1 1; style roman; @set_window 0;
];
Class CutObj
with next 0,
prev 0,
describe [; rtrue;],
called [;
"BUG: ", (the) self, " does not have a 'called' property.";
],
has proper;
!!Routines for the doubly-linked list.
[Exchange x y;
#ifdef DEBUG;
print "Exchanging ", (the) x, " and ", (the) y, ".^";
#endif;
if (x in Void)
replace(y, x);
else replace (x, y);
];
[Replace out in;
#ifdef DEBUG;
print "Replacing ", (the) out, " with ", (the) in, ".^";
#endif;
in.next = out.next;
in.prev = out.prev;
(in.next).prev = in;
(in.prev).next = in;
out.next = 0;
out.prev = 0;
move in to Here;
move out to Void;
];
[ReplaceAll out in;
#ifdef DEBUG;
print "Replacing All after ", (the) out, " with ", (the) in, ".^";
#endif;
while (out.next ~= Handle)
{
MyRemove (out.next);
}
replace(out,in);
];
[AddAfter place in1 in2 in3 in4;
#ifdef DEBUG;
print "Adding ", (the) in1, " After ", (the) place, ".^";
#endif;
in1.prev = place;
in1.next = place.next;
place.next = in1;
(in1.next).prev = in1;
move in1 to Here;
if (in2 ~= 0) addafter(in1, in2, in3, in4);
];
[AddBefore place in;
#ifdef DEBUG;
print "Adding ", (the) in, " Before ", (the) place, ".^";
#endif;
AddAfter(place.prev, in);
];
[MyRemove out;
#ifdef DEBUG;
print "Removing ", (the) out, ".^";
#endif;
(out.prev).next = out.next;
(out.next).prev = out.prev;
out.prev = 0;
out.next = 0;
move out to Void;
];
[RemoveAll out;
#ifdef DEBUG;
print "Removing all after and including ", (the) out, ".^";
#endif;
while (out.next ~= Handle)
MyRemove(out.next);
MyRemove(out);
];
Object Here "The Chicken Under the Window"
with description [current;
current=Handle.next;
while (current ~= Handle)
{
PrintOrRun(current, description, 1);
current = current.next;
}
if ((Handle.prev) == final)
{
deadflag=3;
}
else " ***";
],
each_turn [x;
if (self hasnt general) return;
print "[ Forward: ";
x = Handle.next;
while (x ~= Handle)
{
print (the) x, ", ";
x = x.next;
}
print " Handle.^Backwards: ";
x = Handle.prev;
while (x ~= Handle)
{
print (the)x, ", ";
x = x.prev;
}
print " Handle.]^";
],
has light;
CutObj -> Handle
with next cars,
prev nocross,
description [; rtrue; ];
CutObj -> cars
with name 'cars' 'zoom',
next nocross,
prev Handle,
description "The cars zoom by, ",
called [x;
if (self.next==nocross or nocross2) x=opening;
else x=nocross;
replaceAll(self.next, x);
];
CutObj -> nocross
with name 'chicken',
next Handle,
prev cars,
description "so the chicken can't cross.^^",
called [;
exchange(self, nocross2);
];
Object Void "There"
with name 'void',
description "Just a storage area.";
CutObj -> opening
with name 'opening',
description "but an opening appears.^^",
called [;
replace(self, traffic);
addafter(traffic, surge, left_right);
];
CutObj -> nocross2
with name 'chicken' 'feathered',
description "so the feathered chicken can't cross.^^",
called [;
replace(self, nocross);
];
CutObj -> traffic
with name 'opening' 'darts' 'traffic',
description "but an opening appears.^^The chicken darts into
the traffic, ",
called [;
replaceall(self, opening);
];
CutObj -> surge
with name 'cars' 'surging' 'surge',
description "cars surging ",
called [;
replaceall(self, faceless);
addafter(faceless, around);
];
CutObj -> left_right
with name 'left' 'right',
description "left and right.^^",
called [;
replaceall(surge, l_r_l_r);
addafter(l_r_l_r, pattern1);
];
CutObj -> faceless
with name 'faceless' 'cars' 'car',
description "faceless cars ",
called [;
replace(self, maelstrom);
addafter(maelstrom, facecars);
];
CutObj -> around
with name 'surging' 'surge' 'around',
description "surging all around.^^",
called [;
replace(self, surgtwist);
addafter(surgtwist, encroach);
];
CutObj -> maelstrom
with name 'swirl' 'swirling' 'maelstrom',
description "a swirling maelstrom ",
called [;
if (chessboard in Here) removeall(chessboard);
else if (lost in Here) removeall(lost);
else if (too_close in Here) removeall(too_close);
else
{
addbefore(Handle, confusion);
addbefore(confusion, lost);
}
];
CutObj -> facecars
with name 'faceless' 'cars',
description "of faceless cars ",
called [;
if (chessboard in Here) removeall(chessboard);
else if (lost in Here) removeall(lost);
else if (too_close in Here) removeall(too_close);
else
{
addbefore(Handle, gamelost);
addbefore(gamelost, chessboard);
}
];
CutObj -> surgtwist
with name 'surging' 'surge' 'twisting' 'twist',
description "surging, twisting, ",
called [;
if (chessboard in Here) removeall(chessboard);
else if (lost in Here) removeall(lost);
else if (too_close in Here) removeall(too_close);
else
{
addbefore(Handle, confusion);
addbefore(confusion, lost);
}
];
CutObj -> encroach
with name 'encroach' 'encroaching' 'sides',
description "encroaching on all sides.^^",
called [;
if (chessboard in Here) removeall(chessboard);
else if (lost in Here) removeall(lost);
else if (too_close in Here) removeall(too_close);
else
{
addbefore(Handle, hit);
addbefore(hit, too_close);
}
];
CutObj -> lost
with name 'amidst' 'raging' 'current',
description "Amidst the raging current, ",
called [;
exchange(confusion, quagmire);
if (self.next.next ~= Handle) removeall(self.next.next);
];
CutObj -> confusion
with name 'confusion',
description "confusion.^^",
called [;
if (where in Here) removeall(where);
else addafter(self, where, brain, limit, period);
];
CutObj -> quagmire
with name 'quagmire' 'decision' 'decisions',
description "confusion: a quagmire of decisions, ",
called [;
replace(self.next, slow);
addafter(slow, final);
];
CutObj -> hopeless
with name 'each' 'hopeless' 'last',
description "each more hopeless than the last.^^",
called [;
replace(self, paralyze);
addafter(paralyze, final);
];
CutObj -> slow
with description "each more hopeless than the last. Time seems to
slow down as step by step the chicken advances,...^^",;
CutObj -> paralyze
with description "each more hopeless than the last. Paralyzed,
frozen mid-stream, never to be able to get to where,...^^";
CutObj -> where
with name 'where' 'turn',
description "Where to turn? ",
called [;
MyRemove(period);
addafter(limit, perpendicular, final);
];
CutObj -> brain
with name 'small' 'avian' 'brain',
description "The small avian brain, ",
called [;
MyRemove(period);
addafter(limit, evolve, final);
];
CutObj -> limit
with name 'stretch' 'stretched' 'limit',
description "stretched to its limit",
called [;
MyRemove(period);
addafter(self, flutter, final);
];
CutObj -> perpendicular
with description ", finally turns perpendicular, following endless
dotted lines to the horizon itself, where,...^^";
CutObj -> evolve
with description ". Outmoded, out-evolved, and out-classed, but driven
by Desire, finally darting towards the Other
Side,...^^";
CutObj -> flutter
with description ". A half-hearted flutter of atrophied wings, but
heartlessly mown down, the impact flinging the chicken
towards the Other Side,...^^";
CutObj -> chessboard
with name 'generic' 'chess' 'board' 'chessboard',
description "A generic chessboard: ",
called [;
if (pawn in Here) removeall(pawn);
else addafter(gamelost, pawn, progress, period);
];
CutObj -> gamelost
with name 'game' 'often' 'lost',
description "a game all too often lost.^^",
called [;
if (self.next ~= Handle) removeall(self.next);
addafter(self, deck, final);
];
CutObj -> pawn
with name 'chicken' 'pawn',
description "The chicken: The pawn, ",
called [;
MyRemove(period);
addafter(progress, passant, final);
];
CutObj -> progress
with name 'unable' 'progress' 'step' 'time',
description "unable to to anything but progress, one step at a
time",
called [;
MyRemove(period);
addafter(self, two_toned, final);
];
CutObj -> passant
with description [;
". The cars: Too busy to care that ", (i) "en passant", ",^";
];
CutObj -> two_toned
with description ". The road: A two-toned variation over which, ^^";
CutObj -> deck
with description "A stacked deck: Unrealistic, really, to believe that it
could ever make it to where,^^";
CutObj -> too_close
with name 'too' 'close' 'close!',
description "Too close! ",
called [;
exchange(hit, smashed);
];
CutObj -> hit
with name 'chicken' 'hit',
description "The chicken is hit!^^",
called [;
addafter(self, buffet, final);
];
CutObj -> smashed
with name 'chicken' 'smashed' 'smash',
description "The chicken is smashed!^^",
called [;
addafter(self, sweep, final);
];
CutObj -> sweep
with description "Days later, the sweeper washes it away.^^";
CutObj -> buffet
with description "Buffeted by a car, then grazed by a truck; a flighless
fowl flung in a wide arc toward the Other Side,...^^";
CutObj -> l_r_l_r
with name 'left' 'right',
description "cars surging left, right, left, right,...^^",
called [;
replaceall(self, surge);
addafter(surge, left_right);
];
CutObj -> pattern1
with name 'pattern' 'form',
description "A pattern begins to form.^^",
called [;
replace(self, patternB);
addafter(patternB, tires1, wheels1, dance1);
];
CutObj -> patternB
with name 'pattern' 'form',
description "A pattern begins to form: ",
called [;
replaceall(self, pattern1);
];
CutObj -> tires1
with name 'tires' 'tire' 'spin' 'spinning',
description "tires spinning, ",
called [;
replace (self, tires2);
if (((wheels2 in Here) || (dance2 in Here))
&& (assimilate notin Here) && assimforward notin Here)
{
addafter(tires2.next.next, assimilate, forward);
}
];
CutObj -> wheels1
with name 'screaming' 'scream' 'wheel' 'wheels',
description "screaming wheels ",
called [;
replace(self, wheels2);
if (((tires2 in Here) || (dance2 in Here))
&& (assimilate notin Here) && assimforward notin Here)
{
addafter(wheels2.next, assimilate, forward);
}
];
CutObj -> dance1
with name 'artless' 'dance',
description "in an artless dance.^^",
called [;
replace(self,dance2);
if (((wheels2 in Here) || (tires2 in Here))
&& (assimilate notin Here) && assimforward notin Here)
{
addafter(dance2, assimilate, forward);
}
];
CutObj -> tires2
with name 'spinning' 'freeform' 'tires' 'tire',
description "spinning, freeform tires, ",
called [;
replace(self, tires1);
if ((wheels1 in Here) || (dance1 in Here))
if (tires1.next.next.next ~= Handle)
{
removeall(tires1.next.next.next);
}
];
CutObj -> wheels2
with name 'scream' 'screaming' 'sing' 'singing' 'wheel' 'wheels',
description "screaming, singing wheels ",
called [;
replace(self, wheels1);
if ((tires1 in Here) || (dance1 in Here))
if (wheels1.next.next ~= Handle)
{
removeall(wheels1.next.next);
}
];
CutObj -> dance2
with name 'endless' 'hypnotic' 'dance',
description "in an endless hypnotic dance.^^",
called [;
replace(self, dance1);
if ((wheels1 in Here) || (tires1 in Here))
if (dance1.next ~= Handle)
{
removeall(dance1.next);
}
];
CutObj -> assimilate
with name 'assimilate' 'assimilating',
description "Assimilating the dance, ",
called [;
replaceall(self, assimforward);
addafter(assimforward, self_ex, chick, period);
];
CutObj -> forward
with name 'chicken' 'forward' 'moves',
description "the chicken moves forward.^^",
called [;
replaceall(assimilate, assimforward);
addafter(assimforward, blur, tango, period);
];
CutObj -> assimforward
with name 'assimilate' 'assimilating' 'chicken' 'forward' 'moves',
description "Assimilating the dance, the chicken moves forward",
called [;
replaceall(self, assimilate);
addafter(assimilate, forward);
];
CutObj -> self_ex
with name 'self-expression' 'self' 'expression',
description ", the self-expression ",
called [;
replace(period, waltz);
addafter(waltz, final);
];
CutObj -> chick
with name 'freeing' 'inner' 'chick',
description "freeing its inner chick",
called [;
replace(period, leads);
addafter(leads, final);
];
CutObj -> period
with description ".^^";
CutObj -> waltz
with description " into a joyous waltz of freedom,...^^";
CutObj -> leads
with description [;
print " which leads it ";
if (tires1 in Here) print "freely";
else if (wheels1 in Here) print ", singing";
else if (dance1 in Here) print "hypnotically";
else print "transcendantly";
" towards the Other Side,...^^";
];
CutObj -> blur
with name 'relentlessly' 'blur',
description " relentlessly, almost a blur ",
called [;
replace(period, cyclone);
addafter(cyclone, final);
];
CutObj -> tango
with name 'amidst' 'tango' 'traffic',
description "amidst the tango of traffic",
called [;
replace(period, magic);
addafter(magic, final);
];
CutObj -> cyclone
with description " as it spins in a feathered cyclone towards the
Other Side,...^^";
CutObj -> magic
with description " which, though ever present, seems to magically part
wenever the chicken approaches,...^^";
CutObj -> final
with description "The chicken crosses.";
Include "Grammar";
Verb meta 'about' 'info' 'information' 'help' 'hint'
* ->About;
[AboutSub;
print (b) "~The Chicken Under the Window~", " draws its literary
background from Andrew Plotkin's excellent, ", (b) "~The Space Under
the Window,~", " which you should go and play. You don't 'play' it
like you would a normal text adventure game; instead, you type in
words that you see in the text, and see what happens. Eventually,
you'll have produced a full 'story'.^^
To recap the current state of affairs, type 'look' or 'l'. This is
particularly useful after an 'undo', which I was unable to implement
as neatly as Andrew seemed to.^^
~The Chicken Under the Window~ is fully redistributable, providing no
modifications have been made.^";
rtrue;
];
Verb 'unknown,'
* ->Unknown
* topic ->Unknown;
[UnknownSub;
"That word is not near the narrative.";
];
Verb 'sutw,style'
* ->SUTW
* topic ->TooMuch;
[SUTWsub;
@erase_window -1;
print "^^";
typed_word.called();
<<Look>>;
];
[TooMuchSub;
"You only need to type in one word at a time.";
];
Verb 'look' 'l//' 'x//'
* -> MyLook;
[MyLookSub;
@erase_window -1;
print "^^";
<<Look>>;
];
#ifdef DEBUG;
Verb 'list'
* -> List
* 'on' -> List
* 'off' -> ListOff;
[ListSub;
give Here general;
"[Listing on]";
];
[ListOffSub;
give Here ~general;
"[Listing off]";
];
#endif;