! 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;