3 ! Release 7 / Serial number 130320 / Inform v6.33
5 ! [-] |\_/| http://www.robotfindskitten.org
6 ! (+)=C |o o|__ Leonard Richardson (C) 1997, 2000
7 ! | | --*--__\ David Griffith (C) 2002 (Inform Edition)
11 ! This Zen simulation is based on the C version v1600003.248b
12 ! by Leonard Richardson (C) 1997, 2000.
13 ! Written originally for the Nerth Pork robotfindskitten contest.
14 ! Reimplemented in Inform by David Griffith (C) 2002.
16 ! Lots more information on robotfindskitten is available at
17 ! http://www.robotfindskitten.org.
20 ! In this game, you are Robot (#). Your job is to find Kitten. This
21 ! task is complicated by the existance of various things which are not
22 ! kitten. Robot must touch items to determine if they are Kitten or
23 ! not. Move Robot with the cursor keys, the numeric keypad, or
24 ! using the vi/rogue movement keys. The game ends when robotfindskitten.
25 ! Alternatively, you may end the game by hitting the Esc or Q keys.
27 ! Developed with Inform 6.21.4 as installed from NetBSD's pkgsrc tree
32 ! 1) More than half of the code is taken up by non kitten items
33 ! (NKIs). When I compiled the code with just five messages and
34 ! no debugging code, the resulting binary was less than 10k bytes.
36 ! 2) If it wasn't already abundantly obvious, this program won't
37 ! compile to Glulx because of copious use of Z-machine assembly
40 ! 3) Compiling for V5 or higher is required due to "style" calls.
41 ! Is there a reason why someone would want to compile this for V4
49 Constant Nonkitten_Default 20;
51 ! Maxmimum possible number of non-kitten items on the playfield at once.
52 ! For whatever reason, this cannot be set dynamically.
54 Constant Nonkitten_Max 589;
59 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
61 Constant Story "robotfindskitten";
62 Constant Headline "^A Zen Simulation^";
64 ! NKIs are generated with nki2inf.pl and put into nki.inf
67 Constant Anim_Meet 10; ! Number of spaces from the left where
68 ! Robot and Kitten meet during animation.
70 Global Height = 0; ! These are set at runtime.
73 Global Back_def = 2; ! Black.
74 Global Fore_def = 9; ! White.
76 Global TopBar = 5; ! Lines from the top.
78 Global player_x = 0; ! Keeping track of where the player was
79 Global player_y = 0; ! 1 move ago allows us to keep the
80 Global player_x_last = 0; ! player from walking through obstacles.
81 Global player_y_last = 0;
85 Global kitten_char = 0;
86 Global kitten_color = 0;
88 Global last_message = ""; ! Always show the last-encountered message.
90 Global nonkitten_count = Nonkitten_Default;
92 Array nonkitten_x --> Nonkitten_Max;
93 Array nonkitten_y --> Nonkitten_Max;
94 Array nonkitten_color --> Nonkitten_Max;
95 Array nonkitten_char --> Nonkitten_Max;
96 Array nonkitten_msg --> Nonkitten_Max;
98 Global already_msg_count = 0;
99 Global already_count = 0;
100 Array already_x --> Nonkitten_Max + 2;
101 Array already_y --> Nonkitten_Max + 2;
102 Array already_msg --> Nonkitten_Max;
104 ! If a key is held down while the found_kitten animation is playing,
105 ! (0-->1) & $03ff gets corrupted. Seems like it might be a bug
106 ! somewhere in Unix Frotz.
108 Global Real_Release = 0;
112 @set_colour Fore_def Back_def;
114 ! if (MESSAGE_NUM < Nonkitten_Max) {
115 ! nonkitten_count = MESSAGE_NUM;
117 ! nonkitten_count = Nonkitten_Default;
120 nonkitten_count = Nonkitten_Default;
122 Real_Release = (0-->1)&$03ff;
131 'F': already_count = 0;
137 'D': set_nonkitten_count();
138 'I': print_instructions();
140 'T': print_thoughts();
142 if (key == 'Q' || key == $1b) ! $1b == ESC
152 ! There's a 1:50 chance that the kitten in the title screen
153 ! will have a "psycho" appearance.
168 draw_big_robot(3, 7);
171 draw_big_kitten_psycho(14, 7);
173 draw_big_kitten(15, 7);
176 print "http://www.robotfindskitten.org";
178 print "Leonard Richardson (C) 1997, 2000";
180 print "David Griffith (C) 2002 (Inform Edition)";
182 print " ", MESSAGE_NUM, " different nonkittens!";
186 print " F) Find Kitten^",
187 " D) Difficulty (", nonkitten_count, ")^",
196 ! Copied from module/verblibm.h of the Inform 6.21.3 standard library.
201 print (string) Story;
205 print (string) Headline;
207 print "Release ", Real_Release, " / Serial number ";
208 for (i=18:i<24:i++) print (char) 0->i;
209 print " / Inform v"; inversion; print "";
214 Constant INBUFSIZE 80;
215 Array inbuf -> INBUFSIZE;
217 [ set_nonkitten_count maxnum val;
227 if (MESSAGE_NUM < Nonkitten_Max) {
228 maxnum = MESSAGE_NUM;
230 maxnum = Nonkitten_Max;
233 print "^Please enter the number of nonkittens you
234 wish to search through.^(1 to ", maxnum, " only)^^> ";
237 val = get_number(1, maxnum, nonkitten_count);
241 nonkitten_count = val;
249 [ get_number min max init inbufvar ix cx len val;
252 inbuf->0 = (INBUFSIZE-3);
260 while (cx < len && inbuf->(2+cx) == ' ')
262 if (cx < len && inbuf->(2+cx) == '.')
265 ! If user just hits return, use what we have already.
268 if (cx == len || inbuf->(2+cx) < '0' || inbuf->(2+cx) > '9') {
269 print "Please enter a value from ", min, " to ", max,
270 ", or Enter by itself to exit.^
271 [Press any key to continue.] ";
276 while (cx < len && inbuf->(2+cx) >= '0' && inbuf->(2+cx) <= '9') {
277 val = val * 10 + (inbuf->(2+cx) - '0');
280 if (val < min || val > max) {
281 print "Please enter a value from ", min, " to ", max,
282 ", or Enter by itself to exit.^
283 [Press any key to continue.] ";
295 @split_window TopBar;
302 This Zen simulation is based on the C version v1600003.248b^
303 by Leonard Richardson (C) 1997, 2000.^
304 Written originally for the Nerth Pork robotfindskitten contest.^
305 Reimplemented in Inform by David Griffith (C) 2002.^
307 This code is freely redistributable. Do with it what you will, but
308 don't go about claiming you wrote it. I, David Griffith, retain
309 copyright on this program except for the NKIs imported from the master
312 Lots more information on robotfindskitten is available at
313 http://www.robotfindskitten.org.^
315 To submit new NKI's, please go to the above URL.^
320 Release 1 / Serial number 0211xx to 021214 or so^
321 Initial private release. Limited distribution for beta testing and
324 Release 2 / Serial Number 021216^
325 First public release.^
327 Release 3 / Serial Number 021221^
329 - Movement keys 'J' and 'K' were swapped by mistake. Fixed.^
330 - Special PalmOS movement key support added.^
331 - More NKIs added (401 total).^
333 Release 4 / Serial Number 030131^
334 Light overhaul release.^
335 - Now an official port of robotfindskitten.^
336 - Typos in NKIs fixed.^
337 - Fixed diagonal collision-detection strangeness.^
338 - Added color support.^
339 - Added an easter egg. Can you find it?^
340 - Removed PalmOS movement key support (superfluous and ugly).^
341 - Removed playfield resizing code (superfluous and ugly).^
342 - It's ~robotfindskitten~, not ~Robot Finds Kitten~.^
343 - Merged in new NKIs from the new POSIX release of robotfindskitten.^
344 - More NKIs added (561 total).^
346 Release 5 / Serial Number 030524^
347 Even more NKIs release.^
348 - Idiotic typos fixed.^
349 - More NKIs added (602 total).^
351 Release 6 / Serial Number 031116^
353 - More NKIs added (764 total).^
354 - Increased maximum difficulty to 589.^
355 - Lots more comments in the source code.^
356 - Assorted cleanups in the source code.^
358 Release 7 / Serial Number 130320^
360 - Synchronized NKIs and removed redundancies with the POSIX port.^
361 - NKIs now generated from an external file using nki2inf.pl.^
362 - NKIs reduced to 723 because of redundancies and recommended deletions.^
367 1) I still don't know why already_seen_xy() occasionally causes Robot to
368 get placed on top of another object when a game is started. Fortunately
369 this seems to happen only very rarely and typically only if the
370 difficulty is set to more than 200. This bug also seems to very
371 occasionally put Kitten underneath an NKI.^
373 2) Under earlier versions of Windows Frotz, Robot used to appear as a
374 solid block. This was because of a bug in Windows Frotz which
375 incorrectly makes the cursor opaque. The cursor is now moved off to
376 the upper-right corner so that the game looks okay on terminals that use
377 something other than reverse for the cursor. I still can't figure out
378 how to make Inform hide the cursor completely. At least on xterm and
379 NetBSD's console, @@64set_cursor -1 doesn't work.^
381 3) Under Windows Frotz, an annoying [MORE] prompt might appear at the
382 main menu. This is another bug in Windows Frotz which causes the
383 interpreter to follow Windows' suggestion that something less than 24 or
386 [Press any key to continue.] ";
391 [ print_instructions;
393 @split_window TopBar;
399 In this game, you are Robot ( ";
400 style reverse; print "#"; style roman;
401 print " ). Your job is to find Kitten. This task is complicated by the
402 existance of various things which are not Kitten. Robot must touch
403 items to determine if they are Kitten or not. Move Robot with the
404 cursor keys, the numeric keypad (make sure numlock is on), or using the
405 vi/rogue/nethack movement keys. The game ends when robotfindskitten.
406 Alternatively, you may end the game by hitting the Esc or Q keys.^
408 [Press any key to continue.] ";
416 @split_window TopBar;
424 Day and night I feverishly worked upon the machine, creating both a soul
425 which could desire its goal, and a body with which it could realize
426 it. Many who saw my creation called it an abomination, and denied me
427 grant money. But they could not dissuade me from my impossible
428 task. It was a spectre that tormented me always, a ghost I had to give
429 a form and a life, lest it consume me from the inside. And when at last
430 my task was done, when the grey box on wheels was complete and when it,
431 as well as I, knew what had to be done, I felt deep sympathy for the
432 machine. For I had not destroyed the phantom, but merely exorcized it
433 into another body. The robot knew not why this task had to be
434 performed, for I could not imbue it with knowledge I did not myself
435 posess. And at the same time, I felt a sweeping sense of relief sweep
436 over me, that somehow, the dream that had driven me for my entire life
437 had come one step closer to fruition.^
439 ~Gort, Klaatu Verada Nikto~^
441 As I vocally activated the robot, I realized that it was following my
442 instructions, but not out of any desire to obey me. Had I remained
443 silent, it would have performed exactly the same operations. We were
444 two beings controlled by the same force now. And yet, seeking vainly to
445 hold some illusion of control over the machine I thought I had created,
446 I gave my final command.^
448 ~GO!~ I told the box as it began to roll out of my workshop into the
449 frozen desert beyond. ~FIND KITTEN!~^
451 -- The Book of Found Kittens, pages 43-4, author unknown.^
453 [Press any key to continue.] ";
458 [ draw_big_robot x y;
465 @set_colour 6 Back_def;
467 @set_colour 4 Back_def;
469 @set_colour 6 Back_def;
474 @set_colour 6 Back_def;
476 @set_colour 3 Back_def;
478 @set_colour 6 Back_def;
480 @set_colour 8 Back_def;
485 @set_colour 6 Back_def;
490 @set_colour 8 Back_def;
493 @set_colour Fore_def Back_def;
497 [ draw_big_kitten x y;
505 @set_colour 5 Back_def;
506 print "|", (char) 92, "_/|";
510 @set_colour 4 Back_def;
512 @set_colour 5 Back_def;
516 @set_colour 9 Back_def;
518 @set_colour 3 Back_def;
520 @set_colour 9 Back_def;
522 @set_colour 5 Back_def;
523 print "__", (char) 92;
528 @set_colour Fore_def Back_def;
532 [ draw_big_kitten_psycho x y;
540 @set_colour 5 Back_def;
541 print " |", (char) 92, "_/|";
544 @set_colour 4 Back_def;
546 @set_colour 5 Back_def;
550 @set_colour 9 Back_def;
552 @set_colour 3 Back_def;
554 @set_colour 9 Back_def;
556 @set_colour 5 Back_def;
557 print "__", (char) 92;
562 @set_colour Fore_def Back_def;
566 ! Something gets messed up if I make this local to findkitten()
567 ! When going right or left, then up or down to hit the Kitten, the
568 ! animation gets reversed.
570 Global last_right = false;
575 @split_window TopBar;
580 print (string) last_message;
583 draw_object(kitten_x, kitten_y, kitten_char, kitten_color);
587 draw_object(player_x, player_y, '#');
598 player_x_last = player_x;
599 player_y_last = player_y;
601 'Q', $1b: rfalse; ! exit game ($1b == Esc)
602 '8', 'K', 129: player_y--; ! up
603 '2', 'J', 130: player_y++; ! down
604 '4', 'H', 131: player_x--; ! left
606 '6', 'L', 132: player_x++; ! right
609 '7', 'Y': player_y--; player_x--; ! up-left
611 '9', 'U': player_y--; player_x++; ! up-right
613 '1', 'B': player_y++; player_x--; ! down-left
615 '3', 'N': player_y++; player_x++; ! down-right
619 ! Keep Robot from falling off edges of playfield.
621 if (player_y == TopBar || player_y > Height) {
622 player_y = player_y_last;
624 if (player_x < 1 || player_x > Width) {
625 player_x = player_x_last;
628 ! Detect and handle collisions.
630 if (player_x == kitten_x && player_y == kitten_y) {
631 animate_kitten(key, last_right);
635 for (i = 0: i < nonkitten_count: i++) {
636 if (player_x == nonkitten_x-->i
637 && player_y == nonkitten_y-->i) {
639 last_message = lookup_msg(nonkitten_msg-->i);
640 player_x = player_x_last;
641 player_y = player_y_last;
648 [ animate_kitten key my_last_right i j junk robot_x anim_finished;
651 '8', 'J', 129: player_y++;
652 '2', 'K', 130: player_y--;
653 '4', 'H', 131: player_x++;
654 '6', 'L', 132: player_x--;
655 '7', 'Y': player_y++; player_x++;
656 '9', 'U': player_y++; player_x--;
657 '1', 'B': player_y--; player_x++;
658 '3', 'N': player_y--; player_x--;
661 anim_finished = false;
662 for (i = 4: i >= 0: i--) {
664 @split_window TopBar;
673 robot_x = Anim_Meet - i;
675 draw_object(robot_x, TopBar - 1, '#');
677 draw_object(Anim_Meet - 1 + i, TopBar - 1,
678 kitten_char, kitten_color);
680 robot_x = Anim_Meet - 1 + i;
682 draw_object(robot_x, TopBar - 1, '#');
684 draw_object(Anim_Meet - i, TopBar - 1,
685 kitten_char, kitten_color);
690 print "You found Kitten! Way to go, Robot!";
691 anim_finished = true;
694 draw_object(kitten_x, kitten_y, kitten_char, kitten_color);
697 draw_object(player_x, player_y, '#');
701 if (anim_finished == false) {
704 @aread junk 0 10 pause -> junk;
707 draw_object(player_x, player_y, '#');
715 [ already_seen_xy x y i;
716 for (i = 0: i < already_count: i++) {
717 if (already_x-->already_count == x &&
718 already_y-->already_count ==y) {
722 already_x-->already_count = x;
723 already_y-->already_count = y;
735 kitten_x = get_random_x();
736 kitten_y = get_random_y();
737 kitten_color = get_random_color();
738 while (already_seen_xy(kitten_x, kitten_y) == true) {
739 kitten_x = get_random_x();
740 kitten_y = get_random_y();
742 kitten_char = get_random_char();
747 player_x = get_random_x();
748 player_y = get_random_y();
749 while (already_seen_xy(player_x, player_y) == true) {
750 player_x = get_random_x();
751 player_y = get_random_y();
757 already_msg_count = 0;
759 for (i = 0: i < nonkitten_count: i++) {
760 nonkitten_x-->i = get_random_x();
761 nonkitten_y-->i = get_random_y();
762 nonkitten_color-->i = get_random_color();
763 while (already_seen_xy(nonkitten_x-->i,
764 nonkitten_y-->i) == true) {
765 nonkitten_x-->i = get_random_x();
766 nonkitten_y-->i = get_random_y();
768 nonkitten_char-->i = get_random_char();
769 nonkitten_msg-->i = get_random_msg();
775 for (i = 0: i < nonkitten_count: i++) {
776 draw_object(nonkitten_x-->i,
779 nonkitten_color-->i);
784 [ draw_object x y character fore back;
792 @set_colour fore Back_def;
794 print (char) character;
796 @set_colour Fore_def Back_def;
802 for (i = 0 : i < Width : i++)
809 if (x >= 'a' && x <= 'z')
815 [ get_random_char num;
818 while (num == 35) { ! avoid choosing '#'
826 [ get_random_msg num;
827 num = random(MESSAGE_NUM);
828 while (is_duplicate_msg(num) == true) {
829 num = random(MESSAGE_NUM);
835 [ get_random_color num;
837 ! 0 and 1 are default color and current color
838 ! and we want to avoid picking the default color explicitly
839 while (num == $2c-->0) {
846 [ is_duplicate_msg num i;
847 for (i = 0: i < already_msg_count: i++) {
848 if (already_msg-->i==num) {
852 already_msg-->already_msg_count = num;
859 ! Maybe this will need to do something more in the future.
860 return random(Width);
865 ! Make sure we don't draw in the status bar.
867 num = random(Height);