Import of Release 4 r4
authorDavid Griffith <dave@661.org>
Fri, 2 Nov 2012 04:00:05 +0000 (21:00 -0700)
committerDavid Griffith <dave@661.org>
Fri, 2 Nov 2012 04:00:05 +0000 (21:00 -0700)
kitten.inf

index 4958596388307842a3e20fecb5abeed03aabc76a..315046d38156e8cd450b9e24c1a323bd6b6e7be1 100644 (file)
@@ -1,6 +1,6 @@
-! Robot Finds Kitten
+! robotfindskitten
 ! A Zen Simulation
-! Release 3 / Serial number 021221 / Inform v6.21
+! Release 4 / Serial number 030131 / Inform v6.21
 !
 !     [-]       |\_/|        http://www.robotfindskitten.org
 !     (+)=C     |o o|__      Leonard Richardson (C) 1997, 2000
@@ -13,7 +13,7 @@
 ! Written originally for the Nerth Pork robotfindskitten contest.
 ! Reimplemented in Inform by David Griffith (C) 2002.
 !
-! Lots more information on Robot Finds Kitten is available at
+! Lots more information on robotfindskitten is available at
 ! http://www.robotfindskitten.org.
 !
 !
@@ -21,9 +21,8 @@
 ! task is complicated by the existance of various things which are not
 ! kitten.  Robot must touch items to determine if they are Kitten or
 ! not.  Move Robot with the cursor keys, the numeric keypad, or
-! using the vi/rogue movement keys. The game ends when Robot finds
-! Kitten.  Alternatively, you may end the game by hitting the Esc or Q
-! keys.
+! using the vi/rogue movement keys. The game ends when robotfindskitten.
+! Alternatively, you may end the game by hitting the Esc or Q keys.
 !
 ! Developed with Inform 6.21.2 as installed from NetBSD's pkgsrc tree
 ! and Frotz 2.42.
 !
 ! Compile it with:
 !      inform "-~S" kitten.inf  <-- Assuming Unix
+!               ^
+!               | 
+!              Gets rid of debugging code which doesn't really do
+!              this sort of program any good in the first place.
 !
 ! Notes:
-!      1) More than half of the code is taken up by non-kitten
-!      messages.  When I compiled the code with just five messages and  
+!      1) More than half of the code is taken up by non kitten items
+!      (NKIs).  When I compiled the code with just five messages and
 !      no debugging code, the resulting binary was less than 10k bytes.
 !
 !      2) If it wasn't already abundantly obvious, this program won't
 !      compile to Glulx because of copious use of Z-machine assembly
 !      instructions.
-!
-!
-! Release History:
-!
-! Release 1 / Serial number 0211xx to 021214 or so
-! Initial private release.  Limited distribution for beta testing and
-! debugging purposes.
-!
-!
-! Release 2 / Serial Number 021216
-! First public release.
-!
-!
-! Release 3 / Serial Number 0212xx
-! Bugfix release.
-!   Movement keys 'J' and 'K' were swapped by mistake.  Fixed.
-!   Special PalmOS movement key support added.
-!   More NKIs added (401 total).
-!
 
 !Switches xv5s;
 
@@ -68,39 +52,51 @@ Switches v5;
 ! Number of messages
 ! This must be updated when adding new messages.
 !
-Constant MESSAGE_NUM   401;
+Constant MESSAGE_NUM   561;
 
 Constant Nonkitten_Default 20;
 
 ! Maxmimum possible number of non-kitten items on the playfield at once.
+! I don't know if there's a hard maximum for arrays built into the
+! Z-machine.  It's just that Inform won't let me set an array's 
+! dimensions at runtime.
 !
 Constant Nonkitten_Max 256;
 
 
-Release 3;
-Serial "021221";
-
+Release 4;
+Serial "030131";
 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-Constant Story "Robot Finds Kitten";
+Constant Story "robotfindskitten";
+
 Constant Headline "^A Zen Simulation^";
 
+! Number of spaces from the left where Robot and Kitten meet during the
+! animation.
+!
 Constant Anim_Meet     10;
 
-Global Palm_Movement = false;
-
+! These are set at runtime.
+!
 Global Height = 0;
 Global Width = 0;
 
+Global Back_def = 2;
+Global Fore_def = 9;
+
 Global TopBar = 5;
 
 Global player_x = 0;
 Global player_y = 0;
+Global player_x_last = 0;
+Global player_y_last = 0;
 
 Global kitten_x = 0;
 Global kitten_y = 0;
 Global kitten_char = 0;
+Global kitten_color = 0;
 
 Global last_message = "";
 
@@ -108,6 +104,7 @@ Global nonkitten_count = Nonkitten_Default;
 
 Array nonkitten_x --> Nonkitten_Max;
 Array nonkitten_y --> Nonkitten_Max;
+Array nonkitten_color --> Nonkitten_Max;
 Array nonkitten_char --> Nonkitten_Max;
 Array nonkitten_msg --> Nonkitten_Max;
 
@@ -122,6 +119,8 @@ Global Real_Release = 0;
 
 [ Main key;
 
+       @set_colour Fore_def Back_def;
+
        if (MESSAGE_NUM < Nonkitten_Max) {
                nonkitten_count = MESSAGE_NUM;
        } else {
@@ -148,12 +147,10 @@ Global Real_Release = 0;
                        while (findkitten())
                                ;
                'D':    set_nonkitten_count();
-               'P':    set_palm_mode();
-!              'W':    set_width(10, 255);
-!              'H':    set_height(10, 255);
                'I':    print_instructions();
                'A':    print_about();
                'T':    print_thoughts();
+!              'P':    print_all_nki();
                }
                if (key == 'Q' || key == $1b)   ! $1b == ESC
                        break;
@@ -161,9 +158,16 @@ Global Real_Release = 0;
        }
        quit;
 ];
-       
 
-[ main_menu;
+
+[ main_menu psycho;
+
+       psycho = random(50);
+       if (psycho == 1)
+               psycho = true;
+       else
+               psycho = false;
+
        @erase_window $ffff;
        @split_window 11;
        @set_window 1;
@@ -172,7 +176,11 @@ Global Real_Release = 0;
        draw_horiz(TopBar);
 
        draw_big_robot(3, 7);
-       draw_big_kitten(15, 7);
+
+       if (psycho)
+               draw_big_kitten_psycho(14, 7);
+       else
+               draw_big_kitten(15, 7);
 
        @set_cursor 7 30;
        print "http://www.robotfindskitten.org";
@@ -180,6 +188,7 @@ Global Real_Release = 0;
        print "Leonard Richardson (C) 1997, 2000";
        @set_cursor 9 30;
        print "David Griffith (C) 2002  (Inform Edition)";
+
        @set_cursor 10 30;
        print "    ", MESSAGE_NUM, " different nonkittens!";
 
@@ -187,11 +196,6 @@ Global Real_Release = 0;
 
        print "  F) Find Kitten^";
        print "  D) Difficulty  (", nonkitten_count, ")^";
-       print "  P) Palm movement keys (";
-               if (palm_movement) print "on"; else print "off";
-               print ")^";
-!      print "  W) Width  (", Width, ")^";
-!      print "  H) Height (", Height, ")^";
        print "  I) Instructions^";
        print "  T) Thoughts^";
        print "  A) About^";
@@ -230,45 +234,12 @@ Global Real_Release = 0;
        new_line;
 ];
 
-[ set_palm_mode key;
-
-       @erase_window $ffff;
-       @split_window 5;
-       @set_window 1;
-       Banner();
-       draw_horiz(TopBar);
-       @set_window 0;
-
-       print "This mode allows you to use the compass rose
-       control commonly presented by PalmOS-based Z-machine
-       interpreters.^
-       ^
-       Turn on PalmOS mode? (y/n) > ";
-
-       key = getkey();
-       switch (key) {
-       'Y':
-               Palm_Movement = true;
-               print "Y^^PalmOS mode activated.";
-       'N':
-               Palm_Movement = false;
-               print "N^^PalmOS mode deactivated.";
-       default: 
-               if (key ~= $000d)
-                       print (char) key;
-
-               print "^^No change.";
-       }
-
-       print "^^[Press any key to continue.] ";
-       getkey();
-       return;
-];
 
 Constant INBUFSIZE 80;
 Array inbuf -> INBUFSIZE;
 
 [ set_nonkitten_count maxnum val;
+
        while (true) {
                @erase_window $ffff;
                @split_window 5;
@@ -299,53 +270,8 @@ Array inbuf -> INBUFSIZE;
 ];
 
 
-![ set_width min max val;
-!      while (true) {
-!              @erase_window $ffff;
-!              @split_window 5;
-!              @set_window 1;
-!              Banner();
-!              draw_horiz(TopBar);
-!              @set_window 0;
-!              print "^Set playfield width 
-!                      (", min, " to ", max, ")^^> ";
-!              while (true) {
-!                      val = get_number(min, max, Width);
-!                      if (val == -1) {
-!                              break;
-!                      } else {
-!                              Width = val;                            
-!                              return;
-!                      }
-!              }
-!      }
-!];
-
-
-![ set_height min max val;
-!      while (true) {
-!              @erase_window $ffff;
-!              @split_window 5;
-!              @set_window 1;
-!              Banner();
-!              draw_horiz(TopBar);
-!              @set_window 0;
-!              print "^Set playfield height
-!                      (", min, " to ", max, ")^^> ";
-!              while (true) {
-!                      val = get_number(min, max, Height);
-!                      if (val == -1) {
-!                              break;
-!                      } else {
-!                              Height = val;                           
-!                              return;
-!                      }
-!              }
-!      }
-!];
-
-
 [ get_number min max init inbufvar ix cx len val;
+
        while (true) {
                inbuf->0 = (INBUFSIZE-3);
                inbuf->1 = 0;
@@ -388,6 +314,7 @@ Array inbuf -> INBUFSIZE;
 
 
 [ print_about;
+
        @erase_window $ffff;
        @split_window TopBar;
        @set_window 1;
@@ -402,11 +329,15 @@ Written originally for the Nerth Pork robotfindskitten contest.^
 Reimplemented in Inform by David Griffith (C) 2002.^
 ^
 This code is freely redistributable.  Do with it what you will, but
-don't go about claiming you wrote it.^
+don't go about claiming you wrote it.  I, David Griffith, retain
+copyright on this program except for the NKIs imported from the POSIX
+imported from the master (aka POSIX) port.^
 ^
-Lots more information on Robot Finds Kitten is available at
+Lots more information on robotfindskitten is available at
 http://www.robotfindskitten.org.^
 ^
+To submit new NKI's please go to the above URL.^
+^
 ^
 Release History:^
 ^
@@ -423,14 +354,29 @@ Bugfix release.^
 - Special PalmOS movement key support added.^
 - More NKIs added (401 total).^
 ^
+Release 4 / Serial Number 030131^
+Light overhaul release.^
+- Now an official port of robotfindskitten.^
+- Typos in NKIs fixed.^
+- Fixed diagonal collision-detection strangeness.^
+- Added color support.^
+- Added an easter egg.  Can you find it?^
+- Removed PalmOS movement key support (superfluous and ugly).^
+- Removed playfield resizing code (superfluous and ugly).^
+- It's ~robotfindskitten~, not ~Robot Finds Kitten~.^
+- Merged in new NKIs from the new POSIX release of robotfindskitten.^
+- More NKIs added (561 total).^
+^
 ^
 Known Bugs:^
 ^
-1) Some bug (I don't know where) in already_seen_xv() causes Robot to
-occasionally get placed on top of another object.^
+1) I still don't know why already_seen_xy() occasionally causes Robot to
+get placed on top of another object.  Fortunately this seems to happen
+only very rarely and typically only if the difficulty is set to more
+than 200.^
 ^
-2) Under Windows Frotz, the Robot used to appear as a solid block.  This
-was because of a bug in Windows Frotz which incorrectly makes the cursor 
+2) Under Windows Frotz, Robot used to appear as a solid block.  This was
+because of a bug in Windows Frotz which incorrectly makes the cursor 
 opaque.  The cursor is now moved off to the upper-right corner so that
 the game looks okay on terminals that use something other than reverse
 for the cursor.  I still can't figure out how to make Inform hide the
@@ -445,31 +391,24 @@ lines is okay.^
 ^
 Other Stuff:^
 ^
-1) Is it worth the trouble to implement colors?^
-^
-2) The PalmOS mode works by getting a one or two key sequence from the
-keyboard (N, S, E, W, NW, SW, NE, SE) followed by a carriage return.
-These are translated into the numbers found on a typical numeric
-keypad (8, 2, 6, 4, 7, 1, 9, 3).^
-^
-3) Implemented control of the playfield size for Frobnitz
-users.  Results were not satisfactory.  The code for this remain in the
-source, but commented out.^
+1) PalmOS mode and screen-resizing was removed because PalmOS mode stunk
+and screen-resizing was a failed attempt to make PalmOS mode work.  The
+native PalmOS port of robotfindskitten looks much better than the Inform
+version running on a PalmOS Z-machine interpreter.^
 ^
 [Press any key to continue.] "; 
-
        getkey();
 ];
 
 
 [ print_instructions;
+
        @erase_window $ffff;
        @split_window TopBar;
        @set_window 1;
        Banner();
        draw_horiz(TopBar);
        @set_window 0;
-
 print "^
 In this game, you are Robot ( ";
 #IFV5; style reverse; #ENDIF;
@@ -479,12 +418,11 @@ print " ).  Your job is to find Kitten.  This task
 is complicated by the existance of various things which are not 
 Kitten.  Robot must touch items to determine if they are Kitten or
 not.  Move Robot with the cursor keys, the numeric keypad (make sure
-numlock is on), or using the vi/rogue movement keys.  The game ends when
-Robot finds Kitten.  Alternatively, you may end the game by hitting the
-Esc or Q keys.^
+numlock is on), or using the vi/rogue/nethack movement keys.  The game
+ends when robotfindskitten.  Alternatively, you may end the game by
+hitting the Esc or Q keys.^
 ^
 [Press any key to continue.] "; 
-
        getkey();
 ];
 
@@ -496,24 +434,23 @@ Esc or Q keys.^
        Banner();
        draw_horiz(TopBar);
        @set_window 0;
-
 print "^
 A Final Thought.^
 ^
 Day and night I feverishly worked upon the machine, creating both a soul
-which could desire its goal, and a body with which it could realize it.
-Many who saw my creation called it an abomination, and denied me grant
-money.  But they could not dissuade me from my impossible task.  It was
-a spectre that tormented me always, a ghost I had to give a form and a
-life, lest it consume me from the inside.  And when at last my task was
-done, when the grey box on wheels was complete and when it, as well as
-I, knew what had to be done, I felt deep sympathy for the machine.  For
-I had not destroyed the phantom, but merely exorcized it into another
-body.  The robot knew not why this task had to be performed, for I could
-not imbue it with knowledge I did not myself posess. And at the same
-time, I felt a sweeping sense of relief sweep over me, that somehow, the
-dream that had driven me for my entire life had come one step closer to
-fruition.^
+which could desire its goal, and a body with which it could realize 
+it. Many who saw my creation called it an abomination, and denied me
+grant money.  But they could not dissuade me from my impossible 
+task.  It was a spectre that tormented me always, a ghost I had to give
+a form and a life, lest it consume me from the inside.  And when at last
+my task was done, when the grey box on wheels was complete and when it,
+as well as I, knew what had to be done, I felt deep sympathy for the
+machine.  For I had not destroyed the phantom, but merely exorcized it
+into another body.  The robot knew not why this task had to be
+performed, for I could not imbue it with knowledge I did not myself
+posess.  And at the same time, I felt a sweeping sense of relief sweep
+over me, that somehow, the dream that had driven me for my entire life
+had come one step closer to fruition.^
 ^
 ~Gort, Klaatu Verada Nikto~^
 ^
@@ -530,55 +467,125 @@ frozen desert beyond. ~FIND KITTEN!~^
 -- The Book of Found Kittens, pages 43-4, author unknown.^
 ^
 [Press any key to continue.] "; 
-
        getkey();
 ];
 
+
 [ draw_big_robot x y; 
+
        if (x == 0)
                x = 1;
        if (y == 0)
                y = 1;
        @set_cursor y x;
-       print "[-]";
+       @set_colour 6 Back_def;
+       print "[";
+       @set_colour 4 Back_def;
+       print "-";
+       @set_colour 6 Back_def;
+       print "]";
+
        y = y+1;
        @set_cursor y x;
-       print "(+)=C";
+       @set_colour 6 Back_def;
+       print "(";
+       @set_colour 3 Back_def;
+       print "+";
+       @set_colour 6 Back_def;
+       print ")";
+       @set_colour 8 Back_def;
+       print "=C";
 
        y = y+1;
        @set_cursor y x;
+       @set_colour 6 Back_def;
        print "| |";
 
        y = y+1;
        @set_cursor y x;
+       @set_colour 8 Back_def;
        print "OOO";
+
+       @set_colour Fore_def Back_def;
 ];
 
+
 [ draw_big_kitten x y;
+
        if (x == 0)
                x = 1;
        if (y == 0)
                y = 1;
        @set_cursor y x;
+
+       @set_colour 5 Back_def;
        print "|", (char) 92, "_/|";
        y++;
        @set_cursor y x;
-       print "|o o|__";
+       print "|";
+       @set_colour 4 Back_def;
+       print "o o";
+       @set_colour 5 Back_def;
+       print "|__";
        y++;
        @set_cursor y x;
-       print "--*--__", (char) 92;
+       @set_colour 9 Back_def;
+       print "--";
+       @set_colour 3 Back_def;
+       print "*";
+       @set_colour 9 Back_def;
+       print "--";
+       @set_colour 5 Back_def;
+       print "__", (char) 92;
        y++;
        @set_cursor y x;
        print "C_C(____)";      
+
+       @set_colour Fore_def Back_def;
 ];
 
-! Something gets mucked up if make this local to findkitten()
+
+[ draw_big_kitten_psycho x y;
+
+       if (x == 0)
+               x = 1;
+       if (y == 0)
+               y = 1;
+       @set_cursor y x;
+
+       @set_colour 5 Back_def;
+       print " |", (char) 92, "_/|";
+       y++;
+       @set_cursor y x;
+       @set_colour 4 Back_def;
+       print "(|) (|)";
+       @set_colour 5 Back_def;
+       print "_";
+       y++;
+       @set_cursor y x;
+       @set_colour 9 Back_def;
+       print " --";
+       @set_colour 3 Back_def;
+       print "O";
+       @set_colour 9 Back_def;
+       print "--";
+       @set_colour 5 Back_def;
+       print "__", (char) 92;
+       y++;
+       @set_cursor y x;
+       print " 3_3(____)";     
+
+       @set_colour Fore_def Back_def;
+];
+
+! Something gets messed up if I make this local to findkitten()
 ! When going right or left, then up or down to hit the Kitten, the
 ! animation gets reversed.
 ! 
 Global last_right = false;
 
 [ findkitten key i;
+
        @erase_window $ffff;
        @split_window TopBar;
        @set_window 1;
@@ -588,7 +595,7 @@ Global last_right = false;
        print (string) last_message;
        draw_horiz(TopBar);
 
-       draw_object(kitten_x, kitten_y, kitten_char);
+       draw_object(kitten_x, kitten_y, kitten_char, kitten_color);
        draw_nonkittens();
 
        #IFV5; style reverse; #ENDIF;
@@ -597,13 +604,14 @@ Global last_right = false;
 
        @set_cursor 1 Width;
 
+       ! Get movement key
+       !
+       key = getkey();
 
-       if (Palm_Movement) {
-               key = get_palm_move();
-       } else {
-               key = getkey();
-       }
-
+       ! Move Robot
+       !
+       player_x_last = player_x;
+       player_y_last = player_y;
        switch (key) {
        'Q', $1b:       rfalse;                 ! exit game ($1b == Esc)
        '8', 'K', 129:  player_y--;             ! up
@@ -623,16 +631,16 @@ Global last_right = false;
                        last_right = true;
        }
 
-       if (player_y <= TopBar+1)
-               player_y = TopBar + 1;
-       if (player_y > Height)
-               player_y = Height;
-       if (player_x < 1)
-               player_x = 1;
-       if (player_x > Width)
-               player_x = Width;
+       ! Keep Robot from falling off edges of playfield.
+       !
+       if (player_y == TopBar || player_y > Height) {
+               player_y = player_y_last;
+       }
+       if (player_x < 1 || player_x > Width) {
+               player_x = player_x_last;
+       }
 
-       ! detect and handle collisions
+       ! Detect and handle collisions.
        !
        if (player_x == kitten_x && player_y == kitten_y) {
                animate_kitten(key, last_right);
@@ -644,60 +652,16 @@ Global last_right = false;
                && player_y == nonkitten_y-->i) {
                        @set_cursor 1 1;
                        last_message = lookup_msg(nonkitten_msg-->i);
-
-                       ! prevent Robot from walking through the object.
-                       switch (key) {
-                       '8', 'K', 129:  player_y++;
-                       '2', 'J', 130:  player_y--;
-                       '4', 'H', 131:  player_x++;
-                       '6', 'L', 132:  player_x--;
-                       '7', 'Y':       player_y++; player_x++;
-                       '9', 'U':       player_y++; player_x--;
-                       '1', 'B':       player_y--; player_x++;
-                       '3', 'N':       player_y--; player_x--;
-                       }
+                       player_x = player_x_last;
+                       player_y = player_y_last;
                }
        }
        rtrue;
 ];
 
 
-[ get_palm_move key1 key2 key3;
-       key1 = getkey();
-       key2 = getkey();
-       if (key2 == $000d) {
-               switch (key1) {
-               'N': return '8';
-               'S': return '2';
-               'E': return '6';
-               'W': return '4';
-               'Q': return 'Q';
-               $1b: return $1b;
-               default: return 'Z';
-               }
-       }
-       key3 = getkey();
-       if (key3 == $000d) {
-               switch (key1) {
-               'N':
-                       if (key2 == 'W') return '7';
-                       if (key2 == 'E') return '9';
-                       return 'Z';
-               'S':
-                       if (key2 == 'W') return '1';
-                       if (key2 == 'E') return '3';
-                       return 'Z';
-               default:
-                       return 'Z';
-               }
-       } else return 'Z';
-];
-
-
 [ animate_kitten key my_last_right i j junk robot_x anim_finished;
 
-       anim_finished = false;
-
        switch (key) {
        '8', 'J', 129:  player_y++;
        '2', 'K', 130:  player_y--;
@@ -709,6 +673,7 @@ Global last_right = false;
        '3', 'N':       player_y--; player_x--;
        }
 
+       anim_finished = false;
        for (i = 4: i >= 0: i--) {
                @erase_window $ffff;
                @split_window TopBar;
@@ -724,13 +689,15 @@ Global last_right = false;
                                #IFV5; style reverse; #ENDIF;
                                draw_object(robot_x, TopBar - 1, '#');
                                #IFV5; style roman; #ENDIF;
-                               draw_object(Anim_Meet - 1 + i, TopBar - 1, kitten_char);
+                               draw_object(Anim_Meet - 1 + i, TopBar - 1, 
+                                       kitten_char, kitten_color);
                        } else {
                                robot_x = Anim_Meet - 1 + i;
                                #IFV5; style reverse; #ENDIF;
                                draw_object(robot_x, TopBar - 1, '#');
                                #IFV5; style roman; #ENDIF;
-                               draw_object(Anim_Meet - i, TopBar - 1, kitten_char);
+                               draw_object(Anim_Meet - i, TopBar - 1,
+                                       kitten_char, kitten_color);
                        }
                } else {
                        j = TopBar - 1;
@@ -739,7 +706,7 @@ Global last_right = false;
                        anim_finished = true;
                }
 
-               draw_object(kitten_x, kitten_y, kitten_char);
+               draw_object(kitten_x, kitten_y, kitten_char, kitten_color);
 
                #IFV5; style reverse; #ENDIF;
                draw_object(player_x, player_y, '#');
@@ -749,10 +716,6 @@ Global last_right = false;
                if (anim_finished == false) {
                        j = TopBar - 1;
                        @set_cursor 1 Width;
-
-                       ! simply using "10" as the third argument causes
-                       ! the release number to mysteriously change
-                       ! if a key is held down during the animation.
                        @aread junk 0 10 pause -> junk;
                } else {
                        #IFV5; style reverse; #ENDIF;
@@ -785,6 +748,7 @@ Global last_right = false;
 [ init_kitten;
        kitten_x = get_random_x();
        kitten_y = get_random_y();
+       kitten_color = get_random_color();
 
        while (already_seen_xy(kitten_x, kitten_y) == true) {
                kitten_x = get_random_x();
@@ -812,6 +776,7 @@ Global last_right = false;
        for (i = 0: i < nonkitten_count: i++) {
                nonkitten_x-->i = get_random_x();
                nonkitten_y-->i = get_random_y();
+               nonkitten_color-->i = get_random_color();
 
                while (already_seen_xy(nonkitten_x-->i, 
                        nonkitten_y-->i) == true) {
@@ -828,15 +793,27 @@ Global last_right = false;
        for (i = 0: i < nonkitten_count: i++) {
                draw_object(nonkitten_x-->i,
                                nonkitten_y-->i,
-                               nonkitten_char-->i);
+                               nonkitten_char-->i,
+                               nonkitten_color-->i);
        }
 ];
 
 
-[ draw_object x y c;
+[ draw_object x y character fore back;
        @set_cursor y x;
-       if (c)
-               print (char) c;
+
+       if (fore == "")
+               fore = Back_def;
+       if (back == "")
+               back = Back_def;
+       
+
+       @set_colour fore Back_def;
+       if (character)
+               print (char) character;
+
+       @set_colour Fore_def Back_def;
+
 ];
 
 
@@ -874,6 +851,16 @@ Global last_right = false;
        return num;
 ];
 
+[ get_random_color num;
+       num = random(7) + 2;
+       ! 0 and 1 are default color and current color
+       ! and we want to avoid picking the default color explicitly
+       while (num == $2c-->0) {
+               num = random(7) + 2;
+       }
+       return num;
+];
+
 
 [ is_duplicate_msg num i;
        for (i = 0: i < already_msg_count: i++) {
@@ -904,6 +891,23 @@ Global last_right = false;
 ];
 
 
+! This function is mainly of use to members of the robotfindskitten
+! development team.
+!
+! When this function is uncommented and enabled in
+! the menu, this will cause a script file to be emitted which contains
+! all NKIs properly formatted.
+
+![ print_all_nki num mystring;
+!      @output_stream 2; @output_stream -1;
+!      for (num = 1: num <= MESSAGE_NUM: num++) {
+!              mystring = lookup_msg(num);
+!              print (string)lookup_msg(num), "^";
+!      }
+!      @output_stream -2; @output_stream 1;
+!];
+
+
 ! Note:
 ! @@126 == '~'
 ! @@64 == '@'
@@ -930,7 +934,7 @@ Global last_right = false;
 18:    return "It's Lucy Ricardo. ~Aaaah, Ricky!~, she says.";
 19:    return "You stumble upon Bill Gates' stand-up act.";
 20:    return "Just an autographed copy of the Kama Sutra.";
-21:    return "It's the Will Rogers Highway. Who was Will Rogers, anyway?";
+21:    return "It's the Will Rogers Highway.  Who was Will Rogers, anyway?";
 22:    return "It's another robot, more advanced in design than you but strangely immobile.";
 23:    return "Leonard Richardson is here, asking people to lick him.";
 24:    return "It's a stupid mask, fashioned after a beagle.";
@@ -1082,7 +1086,7 @@ Global last_right = false;
 168:   return "A parrot, kipping on its back.";
 169:   return "A forgotten telephone switchboard.";
 170:   return "A forgotten telephone switchboard operator.";
-171:   return "It's an automated robot-disdainer. It pretends you're not there.";
+171:   return "It's an automated robot-disdainer.  It pretends you're not there.";
 172:   return "It's a portable hole.  A sign reads: ~Closed for the winter~.";
 173:   return "Just a moldy loaf of bread.";
 174:   return "A little glass tub of Carmex. ($.89)  Too bad you have no lips.";
@@ -1121,7 +1125,7 @@ Global last_right = false;
 207:   return "Vladimir Lenin's casket rests here.";
 208:   return "It's a copy of ~Zen and The Art of Robot Maintenance~.";
 209:   return "This invisible box contains a pantomime horse.";
-210:   return "A mason jar lies here open. It's label reads: ~do not open!~.";
+210:   return "A mason jar lies here open.  It's label reads: ~do not open!~.";
 211:   return "A train of thought chugs through here.";
 212:   return "This jar of pickles expired in 1957.";
 213:   return "Someone's identity disk lies here.";
@@ -1198,7 +1202,7 @@ Global last_right = false;
 281:   return "Nipples, dimples, knuckles, NICKLES, wrinkles, pimples!!";
 282:   return "A bottle of hair tonic.";
 283:   return "A packet of catnip.";
-284:   return "It's Cal Worthington and his dog ~Spot~!";
+284:   return "Here's Cal Worthington and his dog ~Spot~!";
 285:   return "It's Uncle Doctor Hurkamur!";
 286:   return "YEEEEEEEEEEEHAAAAAAAA!!!!!";
 287:   return "Thunder, Thunder, Thunder, Thunder Cats!!!";
@@ -1239,10 +1243,10 @@ Global last_right = false;
 322:   return "A ketchup bottle (nearly empty).";
 323:   return "A large pile of rubber bands.";
 324:   return "A ton of feathers.";
-325:   return "This non kitten may contain peanuts.";
+325:   return "This nonkitten may contain peanuts.";
 326:   return "A tree with some jelly nailed to it.";
 327:   return "Ah, the skirl of the pipes and the rustle of the silicon...";
-328:   return "You found Parakeet.  To bad this isn't ~Robot Finds Parakeet~.";
+328:   return "You found Parakeet.  Too bad this isn't ~Robot Finds Parakeet~.";
 329:   return "A ball of yarn.";
 330:   return "A big chunk of frozen chocolate pudding.";
 331:   return "There is no tea here.";
@@ -1280,7 +1284,7 @@ Global last_right = false;
 ! Release 3
 !
 361:   return "Ten yards of avocado-green shag carpet.";
-362:   return "A zorkmid coin!";
+362:   return "A zorkmid coin.";
 363:   return "It's Babe Flathead's favorite bat.";
 364:   return "It's cute like a kitten, but isn't a kitten.";
 365:   return "A cyclops glowers angrily at you.";
@@ -1320,5 +1324,178 @@ Global last_right = false;
 399:   return "A jar of library paste.";
 400:   return "These aren't ordinary beans.  They're magic beans!";
 401:   return "Some sort of electronic handheld game from the 1970s.";
+
+! The following Non Kitten Items were added by David Griffith for
+! Release 4
+!
+402:   return "Just some glop of some sort.";
+403:   return "A bottle of distilled water.";
+404:   return "A rusty slinky.  It was such a wonderful toy!";
+405:   return "Some coconut crabs are milling about here.";
+406:   return "Dancing cold water pipes.  Mikey must have been here.";
+407:   return "Ash is mumbling ~KLAATU BARATA NI<coughcough>~ here.";
+408:   return "It's a blob of white goo.";
+
+! The following Non Kitten Items were added by David Griffith from the
+! official list of NKIs.
+!
+409:   return "A gravestone stands here.  ~Izchak Miller, ascended.~";
+410:   return "Someone has written ~ad aerarium~ on the ground here.";
+410:   return "A large blue eye floats in midair.";
+411:   return "This appears to be a statue of Perseus.";
+412:   return "There is an opulent throne here.";
+413:   return "It's a squad of Keystone Kops.";
+414:   return "This seems to be junk mail addressed to the finder of the Eye of Larn.";
+415:   return "A wondrous and intricate golden amulet.  Too bad you have no neck.";
+416:   return "The swampy ground around you seems to stink with disease.";
+417:   return "An animate blob of acid.  Being metallic, you keep well away.";
+418:   return "It's a copy of Knuth with the chapter on kitten-search algorithms torn out.";
+419:   return "A crowd of people, and at the center, a popular misconception.";
+420:   return "It's a blind man.  When you touch, he exclaims ~It's a kitten prospecting robot!~";
+421:   return "It's a lost wallet.  It's owner didn't have pets, so you discard it.";
+422:   return "This place is called Antarctica.  There is no kitten here.";
+423:   return "It's a mousetrap, baited with soap.";
+424:   return "A book with ~Don't Panic~ in large friendly letters across the cover.";
+425:   return "A compendium of haiku about metals.";
+426:   return "A discredited cosmology, relic of a bygone era.";
+427:   return "A hollow voice says ~Plugh~.";
+428:   return "A knight who says ~Either I am an insane knave, or you will find kitten.~";
+429:   return "A neural net -- maybe it's trying to recognize kitten.";
+430:   return "A screwdriver.";
+431:   return "A statue of a girl holding a goose like the one in Gottingen, Germany.";
+432:   return "A tetradrachm dated ~42 B.C.~";
+433:   return "A voice booms out ~Onward, kitten soldiers...~";
+434:   return "An eminently forgettable zahir.";
+435:   return "Apparently, it's Edmund Burke.";
+436:   return "For a moment, you feel something in your hands, but it disappears!";
+437:   return "Here is a book about Robert Kennedy.";
+438:   return "Hey, robot, leave those lists alone.";
+439:   return "Ho hum.  Another synthetic a posteriori.";
+440:   return "It's Asimov's Laws of Robotics.  You feel a strange affinity for them.";
+441:   return "It's Bach's Mass in B-minor!";
+442:   return "It's a bug.";
+443:   return "It's a synthetic a priori truth!  Immanuel would be so pleased!";
+444:   return "It's the Tiki Room.";
+445:   return "Just some old play by a Czech playwright, and you can't read Czech.";
+446:   return "Kitten is the letter 'Q'.  Oh, wait, maybe not.";
+447:   return "Quidquid Latine dictum sit, kitten non est.";
+448:   return "Sutro Tower is visible at some distance through the fog.";
+449:   return "The Digital Millennium Copyright Act of 1998.";
+450:   return "The United States Court of Appeals for the Federal Circuit.";
+451:   return "The non-kitten item like this but with ~false~ and ~true~ switched is true.";
+452:   return "This is the chapter called ~A Map of the Cat?~ from Feynman's autobiography.";
+453:   return "This is the forest primeval.";
+454:   return "Werner's ~Pocket Field Guide to Things That Are Not Kitten~.";
+455:   return "You found nettik, but that's backwards.";
+456:   return "You have found some zinc, but you must not stop here, for you must find kitten.";
+457:   return "~50 Years Among the Non-Kitten Items~, by Ann Droyd.";
+458:   return "~Robot may not injure kitten, or, through inaction, ...~";
+459:   return "~Address Allocation for Private Internets~ by Yakov Rekhter et al.";
+460:   return "~Mail Routing and the Domain System~ by Craig Partridge.";
+461:   return "~The Theory and Practice of Oligarchical Collectivism~ by Emmanuel Goldstein.";
+462:   return "~201 Kitten Verbs, Fully Conjugated~.  You look for ~find~.";
+463:   return "A card shark sits here, practicing his Faro shuffle.  He ignores you.";
+463:   return "A copy of DeCSS.  They're a dime a dozen these days.";
+464:   return "A demonic voice proclaims ~There is no kitten, only Zuul~.  You flee.";
+465:   return "A lotus.  You make an interesting pair.";
+466:   return "A milk carton, with a black and white picture of kitten on the side.";
+467:   return "Any ordinary robot could see from a mile away that this wasn't kitten.";
+468:   return "A stegosaurus, escaped from the stegosaurusfindsrobot game.  It finds you.";
+469:   return "Baling wire and chewing gum.";
+470:   return "Chewing gum and baling wire.";
+471:   return "Here is no kitten but only rock, rock and no kitten and the sandy road.";
+472:   return "Hey, I bet you thought this was kitten.";
+473:   return "It is an ancient mariner, and he stoppeth one of three.";
+474:   return "It pleases you to be kind to what appears to be kitten -- but it's not!";
+475:   return "It's a blatant plug for Ogg Vorbis, http://www.vorbis.com/";
+476:   return "It's a business plan for a new startup, kitten.net.";
+477:   return "It's a revised business plan for a new startup, my.kitten.net.";
+478:   return "It's a square.";
+479:   return "It seems to be a copy of ~A Tail of Two Kitties~.";
+480:   return "It's the Donation of Constantine!";
+481:   return "It's this message, nothing more.";
+482:   return "Lysine, an essential amino acid.  Well, maybe not for robots.";
+483:   return "No kitten here.";
+484:   return "The score for a Czech composer's ~Kitten-Finding Symphony in C~.";
+485:   return "This looks like Bradley's ~Appearance and Reality~, but it's really not.";
+486:   return "This non-kitten item no verb.";
+487:   return "You feel strangely unfulfilled.";
+488:   return "You hit the non-kitten item.  The non-kitten item fails to yowl.";
+489:   return "You suddenly yearn for your distant homeland.";
+490:   return "You've found the snows of yesteryear!  So that's where they all went to.";
+491:   return "Approaching.  One car.  J.  Followed by.  Two car.  M, M.  In five. Minutes.";
+491:   return "Free Jon Johansen!";
+492:   return "Free Dmitry Sklyarov!";
+493:   return "One person shouts ~What do we want?~ The crowd answers ~Free Dmitry!~";
+494:   return "Judith Platt insults librarians.";
+495:   return "This map is not the territory.";
+496:   return "~Go back to Libraria!~, says Pat Schroeder.";
+497:   return "This is a porcelain kitten-counter.  0, 0, 0, 0, 0...";
+498:   return "An old bootable business card, unfortunately cracked down the middle.";
+499:   return "A kitten sink, for washing kitten (if only kitten liked water).";
+500:   return "A kitten source (to match the kitten sink).";
+501:   return "If it's one thing, it's not another.";
+502:   return "If it's not one thing, it's another.";
+503:   return "A caboodle.";
+504:   return "A grin.";
+505:   return "A hedgehog.  It looks like it knows something important.";
+506:   return "You've found... Oh wait, that's just a cat.";
+507:   return "Robot should not be touching that.";
+508:   return "Air Guitar!!!  NA na NA na!!";
+509:   return "An aromatherapy candle burns with healing light.";
+510:   return "You find a bright shiny penny.";
+511:   return "It's a free Jon Johansen!";
+512:   return "It's a free Dmitry Sklyarov!";
+513:   return "The rothe hits!  The rothe hits!";
+514:   return "It's an Internet chain letter about sodium laureth sulfate.";
+515:   return "Ed Witten sits here, pondering string theory.";
+516:   return "Something is written here in the dust.  You read: ~rJbotfndQkttten~.";
+517:   return "We wish you a merry kitten, and a happy New Year!";
+518:   return "Run away!  Run away!";
+519:   return "You can see right through this copy of Brin's ~Transparent Society~.";
+520:   return "This copy of ~Steal This Book~ has been stolen from a bookstore.";
+521:   return "It's Roya Naini.";
+522:   return "This kit is the fourteenth in a series of kits named with Roman letters.";
+523:   return "This is the tenth key you've found so far.";
+524:   return "You find a fraud scheme in which loans are used as security for other loans.";
+525:   return "It's the phrase ~and her~, written in ancient Greek.";
+526:   return "It's the author of ~Randomness and Mathematical Proof~.";
+527:   return "It's the crusty exoskeleton of an arthropod!";
+528:   return "It's Emporer Shaddam the 4th's planet!";
+529:   return "It's the triangle leg adjacent to an angle divided by the leg opposite it.";
+530:   return "It's a bottle of nail polish remover.";
+531:   return "You found netkit!  Way to go, robot!";
+532:   return "It's the ASCII Floating Head of Seth David Schoen!";
+533:   return "A frosted pink party-cake, half eaten.";
+534:   return "A bitchin' homemade tesla coil.";
+535:   return "Conan O'Brian, sans jawbone.";
+536:   return "It's either a mirror, or another soulless kitten-seeking robot.";
+537:   return "Preoccupation with finding kitten prevents you from investigating further.";
+538:   return "Fonzie sits here, mumbling incoherently about a shark and a pair of waterskis.";
+539:   return "The ghost of your dance instructor, his face a paper-white mask of evil.";
+540:   return "A bag of groceries taken off the shelf before the expiration date.";
+541:   return "A book: Feng Shui, Zen: the art of randomly arranging items that are not kitten.";
+542:   return "This might be the fountain of youth, but you'll never know.";
+543:   return "Tigerbot Hesh.";
+544:   return "Stimutacs.";
+545:   return "A canister of pressurized whipped cream, sans whipped cream.";
+546:   return "The non-kitten item bites!";
+547:   return "A chain hanging from two posts reminds you of the Gateway Arch.";
+548:   return "A mathematician calculates the halting probability of a Turing machine.";
+549:   return "A number of short theatrical productions are indexed 1, 2, 3, ... n.";
+550:   return "A technical university in Australia.";
+551:   return "It is -- I just feel something wonderful is about to happen.";
+552:   return "It's a Cat 5 cable.";
+553:   return "It's a U.S. president.";
+554:   return "It's a piece of cloth used to cover a stage in between performances.";
+555:   return "The ionosphere seems charged with meaning.";
+556:   return "This tomography is like, hella axial, man!";
+557:   return "It's your favorite game -- robotfindscatan!";
+558:   return "Just a man selling an albatross.";
+559:   return "The intermission from a 1930s silent movie.";
+560:   return "It's an inverted billiard ball!";
+561:   return "The spectre of Sherlock Holmes wills you onwards.";
+
+default: return "Unknown NKI";
        }
 ];