Rog-O-Matic XIV (part 05 of 10)
Michael Mauldin
mlm at cmu-cs-cad.ARPA
Sat Feb 2 04:34:05 AEST 1985
#!/bin/sh
#
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @ Here is part of your new automatic Rogue player, Rog-O-Matic XIV! @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#
# [Note: this is a Beta-Test release of version XIV, and almost
# certainly contains bugs. A new version will be made available
# soon. If you experience any problems with this version, please
# contact Michael Mauldin as soon as possible, so your input can be
# included in the new release]
#
# Rog-O-Matic XIV is shipped via mail in pieces, files rgm14.01, rgm14.02,
# ..., rgm14.nn. Each piece contains some number of smaller files. To
# retrieve them, run each file through the shell 'sh', as follows:
#
# sh <rgm14.01
# sh <rgm14.02
# ...
# sh <rgm14.nn
#
# or do it all at once:
#
# cat rgm14.* | sh
#
# The README file contains all necessary information to edit the "install.h"
# file, after which "make" will build the rogomatic and player binary files.
# Please note that file 'Bugreport' contains modifications you may wish to
# make to the code BEFORE you compile it. You can safely install ALL of
# them; depending on your version of Rogue, you may HAVE to install SOME of
# them.
#
# Rog-O-Matic is copyrighted, but permission is given to copy and modify the
# source provided that (1) it is not used for profit (2) all authorship and
# copyright notices remain intact and (3) any person or site with a copy has
# notified Michael Mauldin either by electronic mail or US Post that they
# have Rog-O-Matic XIV.
#
# We would appreciate hearing about any interesting additions or modifi-
# cations, and would especially like to know how well the program plays
# against your Rogue. And we really, really want to know if Rog-O-Matic
# becomes a "Total Winner" against Rogue 5.2 or Rogue 5.3 again.
#
# Michael Mauldin (Fuzzy)
# Department of Computer Science
# Carnegie-Mellon University
# Pittsburgh, PA 15213
# (412) 578-3065, mauldin at cmu-cs-a.arpa
#
echo 'Start of Rog-O-Matic XIV, part 05 of 10:'
echo 'x - main.c'
sed 's/^X//' > main.c << '/'
X/*
X * main.c: Rog-O-Matic XIV (CMU) Thu Jan 31 18:12:14 1985 - mlm
X */
X
X/*=========================================================================
X * Rog-O-Matic XIV
X * Automatically exploring the dungeons of doom
X * Copyright (C) 1985 by Appel, Jacobson, Hamey, and Mauldin
X *
X * The right is granted to any person, university, or company
X * to copy, modify, or distribute (for free) these files,
X * provided that any person receiving a copy notifies Michael Mauldin
X *
X * (1) by electronic mail to Mauldin at CMU-CS-A.ARPA or
X *
X * (2) by US Mail to Michael Mauldin
X * Dept. of Computer Science
X * Carnegie-Mellon University
X * Pittsburgh, PA 15213
X *
X * All other rights, including those of publication and sale, are reserved.
X *========================================================================/
X
X/*****************************************************************
X * History: I. Andrew Appel & Guy Jacobson, 10/81 [created]
X * II. Andrew Appel & Guy Jacobson, 1/82 [added search]
X * III. Michael Mauldin, 3/82 [added termcap]
X * IV. Michael Mauldin, 3/82 [searching]
X * V. Michael Mauldin, 4/82 [cheat mode]
X * VI. Michael Mauldin, 4/82 [object database]
X * VII. All three, 5/82 [running away]
X * VIII. Michael Mauldin, 9/82 [improved cheating]
X * IX. Michael Mauldin, 10/82 [replaced termcap]
X * X. Mauldin, Hamey, 11/82 [Fixes, Rogue 5.2]
X * XI. Mauldin, 11/82 [Fixes, Score lock]
X * XII. Hamey, Mauldin, 06/83 [Fixes, New Replay]
X * XIII. Mauldin, Hamey, 11/83 [Fixes, Rogue 5.3]
X * XIV. Mauldin 01/85 [Fixes, UT mods]
X *
X * General:
X *
X * This is the main routine for the player process, which decodes the
X * Rogue output and sends commands back. This process is execl'd by the
X * rogomatic process (cf. setup.c) which also execl's the Rogue process,
X * conveniently connecting the two via two pipes.
X *
X * Source Files:
X *
X * arms.c Armor, Weapon, and Ring handling functions
X * command.c Effector interface, sends cmds to Rogue
X * database.c Memory for objects "discovered"
X * debug.c Contains the debugging functions
X * explore.c Path searching functions, exploration
X * findscore.c Reads Rogue scoreboard
X * io.c I/O functions, Sensory interface
X * main.c Main Program for 'player' (this file)
X * mess.c Handles messages from Rogue
X * monsters.c Monster handling utilities
X * mover.c Creates command strings to accomplish moves
X * rooms.c Room specific functions, new levels
X * scorefile.c Score file handling utilities
X * search.c Does shortest path
X * setup.c Main program for 'rogomatic'
X * strategy.c Makes high level decisions
X * survival.c Find cycles and places to run to
X * tactics.c Medium level intelligence
X * things.c Builds commands, part of Effector interface
X * titlepage.c Prints the animated copyright notice
X * utility.c Miscellaneous Unix (tm) functions
X * worth.c Evaluates the items in the pack
X *
X * Include files:
X *
X * globals.h External defs for all global variables
X * install.h Machine dependent DEFINES
X * termtokens.h Defines various tokens to/from Rogue
X * types.h Global DEFINES, macros, and typedefs.
X *
X * Other files which may be included with your distribution include
X *
X * rplot A shell script, prints a scatter plot of Rog's scores.
X * rgmplot.c A program used by rplot.
X * datesub.l A program used by rplot.
X * histplot.c A program which plots a histogram of Rgm's scores.
X *
X * Acknowledgments
X *
X * The UTexas modifications included in this distribution
X * came from Dan Reynolds, and are included by permission.
X * Rog-O-Matics first total winner against version 5.3 was
X * on a UTexas computer.
X *****************************************************************/
X
X# include <curses.h>
X# include <ctype.h>
X# include <signal.h>
X# include <setjmp.h>
X# include "types.h"
X# include "termtokens.h"
X# include "install.h"
X
X/* global data - see globals.h for current definitions */
X
X/* Files */
XFILE *fecho=NULL; /* Game record file 'echo' option */
XFILE *frogue=NULL; /* Pipe from Rogue process */
XFILE *logfile=NULL; /* File for score log */
XFILE *realstdout=NULL; /* Real stdout for Emacs, terse mode */
XFILE *snapshot=NULL; /* File for snapshot command */
XFILE *trogue=NULL; /* Pipe to Rogue process */
X
X/* Characters */
Xchar *logfilename = ""; /* Name of log file */
Xchar afterid = '\0'; /* Letter of obj after identify */
Xchar genelock[100]; /* Gene pool lock file */
Xchar genelog[100]; /* Genetic learning log file */
Xchar genepool[100]; /* Gene pool */
Xchar *genocide; /* List of monsters to be genocided */
Xchar genocided[100]; /* List of monsters genocided */
Xchar lastcmd[64]; /* Copy of last command sent to Rogue */
Xchar lastname[64]; /* Name of last potion/scroll/wand */
Xchar nextid = '\0'; /* Next object to identify */
Xchar screen[24][80]; /* Map of current Rogue screen */
Xchar sumline[128]; /* Termination message for Rogomatic */
Xchar ourkiller[64]; /* How we died */
Xchar versionstr[32]; /* Version of Rogue being used */
Xchar *parmstr; /* Pointer to process arguments */
X
X/* Integers */
Xint aggravated = 0; /* True if we have aggravated this level */
Xint agoalc = NONE; /* Goal square to arch from (col) */
Xint agoalr = NONE; /* Goal square to arch from (row) */
Xint arglen = 0; /* Length in bytes of argument space */
Xint ammo = 0; /* How many missiles? */
Xint arrowshot = 0; /* True if an arrow shot us last turn */
Xint atrow, atcol; /* Current position of the Rogue (@) */
Xint atrow0, atcol0; /* Position at start of turn */
Xint attempt = 0; /* Number times we searched whole level */
Xint badarrow = 0; /* True if cursed/lousy arrow in hand */
Xint beingheld = 0; /* True if a fungus has ahold of us */
Xint beingstalked = 0; /* True if recently hit by inv. stalker */
Xint blinded = 0; /* True if blinded */
Xint blindir = 0; /* Last direction we moved when blind */
Xint cancelled = 0; /* True ==> recently zapped w/cancel */
Xint cecho = 0; /* Last kind of message to echo file */
Xint cheat = 0; /* True ==> cheat, use bugs, etc. */
Xint checkrange = 0; /* True ==> check range */
Xint chicken = 0; /* True ==> check run away code */
Xint compression = 1; /* True ==> move more than one square/turn */
Xint confused = 0; /* True if we are confused */
Xint cosmic = 0; /* True if we are hallucinating */
Xint currentarmor = NONE; /* Index of our armor */
Xint currentweapon = NONE; /* Index of our weapon */
Xint cursedarmor = 0; /* True if our armor is cursed */
Xint cursedweapon = 0; /* True if we are wielding cursed weapon */
Xint darkdir = NONE; /* Direction of monster being arched */
Xint darkturns = 0; /* Distance to monster being arched */
Xint debugging = D_NORMAL; /* Debugging options in effect */
Xint didreadmap = 0; /* Last level we read a map on */
Xint doorlist[40]; /* List of doors on this level */
Xint doublehasted = 0; /* True if double hasted (Rogue 3.6) */
Xint droppedscare = 0; /* True if we dropped 'scare' on this level */
Xint emacs = 0; /* True ==> format output for Emacs */
Xint exploredlevel = 0; /* We completely explored this level */
Xint floating = 0; /* True if we are levitating */
Xint foughtmonster = 0; /* True if recently fought a monster */
Xint foundarrowtrap = 0; /* Found arrow trap this level */
Xint foundtrapdoor = 0; /* Found trap door this level */
Xint goalc = NONE; /* Current goal square (col) */
Xint goalr = NONE; /* Current goal square (row) */
Xint goodarrow = 0; /* True if good (magic) arrow in hand */
Xint goodweapon = 0; /* True if weapon in hand worth >= 100 */
Xint gplusdam = 1; /* Our plus damage from strength */
Xint gplushit = 0; /* Our plus to hit from strength */
Xint hasted = 0; /* True if hasted */
Xint hitstokill = 0; /* # times we hit last monster killed */
Xint interrupted = 0; /* True if at commandtop from onintr() */
Xint knowident = 0; /* Found an identify scroll? */
Xint larder = 1; /* How much food? */
Xint lastate = 0; /* Time we last ate */
Xint lastdamage = 0; /* Amount of last hit by a monster */
Xint lastdrop = NONE; /* Last object we tried to drop */
Xint lastfoodlevel = 1; /* Last level we found food */
Xint lastmonster = NONE; /* Last monster we tried to hit */
Xint lastobj = NONE; /* What did we last use */
Xint lastwand = NONE; /* Index of last wand */
Xint leftring = NONE; /* Index of our left ring */
Xint logdigested = 0; /* True if log file has been read by replay */
Xint logging = 0; /* True if keeping record of game */
Xint lyinginwait = 0; /* True if we waited for a monster */
Xint maxobj = 22; /* How much can we carry */
Xint missedstairs = 0; /* True if we searched everywhere */
Xint morecount = 0; /* Number of messages since last command */
Xint msgonscreen = 0; /* Set implies message at top */
Xint newarmor = 1; /* Change in armor status? */
Xint *newdoors = NULL; /* New doors on screen */
Xint newring = 1; /* Change in ring status? */
Xint newweapon = 1; /* Change in weapon status? */
Xint nohalf = 0; /* True ==> no halftime show */
Xint noterm = 0; /* True ==> no user watching */
Xint objcount = 0; /* Number of objects */
Xint ourscore = 0; /* Final score when killed */
Xint playing = 1; /* True if still playing game */
Xint poorarrow = 0; /* True if arrow has missed */
Xint protected = 0; /* True if we protected our armor */
Xint putonseeinv = 0; /* Turn when last put on see inv ring */
Xint quitat = BOGUS; /* Score to beat, quit if within 10% more */
Xint redhands = 0; /* True if we have red hands */
Xint replaying = 0; /* True if replaying old game */
Xint revvideo = 0; /* True if in rev. video mode */
Xint rightring = NONE; /* Index of our right ring */
Xint rogpid = 0; /* Pid of rogue process */
Xint room[9]; /* Flags for each room */
Xint row, col; /* Current cursor position */
Xint scrmap[24][80]; /* Flags bits for level map */
Xint singlestep = 0; /* True ==> go one turn */
Xint slowed = 0; /* True ==> recently zapped w/slow monster */
Xint stairrow, staircol; /* Position of stairs on this level */
Xint startecho = 0; /* True ==> turn on echoing on startup */
Xint teleported = 0; /* # times teleported this level */
Xint terse = 0; /* True ==> terse mode */
Xint transparent = 0; /* True ==> user command mode */
Xint trapc = NONE; /* Location of arrow trap, this level (col) */
Xint trapr = NONE; /* Location of arrow trap, this level (row) */
Xint urocnt = 0; /* Un-identified Rogue Object count */
Xint usesynch = 0; /* Set when the inventory is correct */
Xint usingarrow = 0; /* True ==> wielding an arrow froma trap */
Xint version; /* Rogue version, integer */
Xint wplusdam = 2; /* Our plus damage from weapon bonus */
Xint wplushit = 1; /* Our plus hit from weapon bonus */
Xint zone = NONE; /* Current screen zone, 0..8 */
Xint zonemap[9][9]; /* Map of zones connections */
X
X/* Functions */
Xint (*istat)(), onintr ();
Xchar getroguetoken (), *getname();
X
X/* Stuff list, list of objects on this level */
Xstuffrec slist[MAXSTUFF]; int slistlen=0;
X
X/* Monster list, list of monsters on this level */
Xmonrec mlist[MAXMONST]; int mlistlen=0;
X
Xchar targetmonster = '@'; /* Monster we are arching at */
X
X/* Monster attribute and Long term memory arrays */
Xattrec monatt[26]; /* Monster attributes */
Xlrnrec ltm; /* Long term memory -- general */
Xltmrec monhist[MAXMON]; /* Long term memory -- creatures */
Xint nextmon = 0; /* Length of LTM */
Xint monindex[27]; /* Index into monhist array */
X
X/* Genetic learning parameters (and defaults) */
Xint geneid = 0; /* Id of genotype */
Xint genebest = 0; /* Best score of genotype */
Xint geneavg = 0; /* Average score of genotype */
Xint k_srch = 50; /* Propensity for searching for traps */
Xint k_door = 50; /* Propensity for searching for doors */
Xint k_rest = 50; /* Propensity for resting */
Xint k_arch = 50; /* Propensity for firing arrows */
Xint k_exper = 50; /* Level*10 on which to experiment with items */
Xint k_run = 50; /* Propensity for retreating */
Xint k_wake = 50; /* Propensity for waking things up */
Xint k_food = 50; /* Propensity for hoarding food (affects rings) */
Xint knob[MAXKNOB] = {50, 50, 50, 50, 50, 50, 50, 50};
X
X/* Door search map */
Xchar timessearched[24][80], timestosearch;
Xint searchstartr = NONE, searchstartc = NONE, reusepsd=0;
Xint new_mark=1, new_findroom=1, new_search=1, new_stairs=1, new_arch=1;
X
X/* Results of last call to makemove() */
Xint ontarget= 0, targetrow= NONE, targetcol= NONE;
X
X/* Rog-O-Matics model of his stats */
Xint Level = 0, MaxLevel = 0, Gold = 0, Hp = 12, Hpmax = 12;
Xint Str = 16, Strmax = 16, Ac = 6, Exp = 0, Explev = 1, turns = 0;
Xchar Ms[30]; /* The message about his state of hunger */
X
X/* Miscellaneous movement tables */
Xint deltrc[8] = { 1,-79,-80,-81,-1,79,80,81 };
Xint deltc[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
Xint deltr[8] = { 0, -1, -1, -1, 0, 1, 1, 1 };
Xchar keydir[8] = { 'l', 'u', 'k', 'y', 'h', 'b', 'j', 'n' };
Xint movedir;
X
X/* Map characters on screen into object types */
Xstuff translate[128] =
X{ /* \00x */ none, none, none, none, none, none, none, none,
X /* \01x */ none, none, none, none, none, none, none, none,
X /* \02x */ none, none, none, none, none, none, none, none,
X /* \03x */ none, none, none, none, none, none, none, none,
X /* \04x */ none, potion, none, none, none, none, none, none,
X /* \05x */ hitter, hitter, gold, none, amulet, none, none, wand,
X /* \06x */ none, none, none, none, none, none, none, none,
X /* \07x */ none, none, food, none, none, ring, none, scroll,
X /* \10x */ none, none, none, none, none, none, none, none,
X /* \11x */ none, none, none, none, none, none, none, none,
X /* \12x */ none, none, none, none, none, none, none, none,
X /* \13x */ none, none, none, armor, none, armor, none, none,
X /* \14x */ none, none, none, none, none, none, none, none,
X /* \15x */ none, none, none, none, none, none, none, none,
X /* \16x */ none, none, none, none, none, none, none, none,
X /* \17x */ none, none, none, none, none, none, none, none
X};
X
X/* Inventory, contents of our pack */
Xinvrec inven[MAXINV]; int invcount = 0;
X
X/* Time history */
Xtimerec timespent[50];
X
X/* End of the game messages */
Xchar *termination = "perditus";
Xchar *gamename = "Rog-O-Matic";
Xchar *roguename = "Rog-O-Matic ";
X
X/* Used by onintr() to restart Rgm at top of command loop */
Xjmp_buf commandtop;
X
X/*
X * Main program
X */
X
Xmain (argc, argv)
Xint argc;
Xchar *argv[];
X{ char ch, *s, *getenv(), *statusline(), msg[128];
X int startingup = 1;
X register int i;
X
X /*
X * Initialize some storage
X */
X
X sprintf (genocided, "");
X sprintf (lastcmd, "i");
X sprintf (ourkiller, "unknown");
X sprintf (sumline, "");
X for (i = 80 * 24; i--; ) screen[0][i] = ' ';
X
X /*
X * The first argument to player is a two character string encoding
X * the file descriptors of the pipe ends. See setup.c for call.
X *
X * If we get 'ZZ', then we are replaying an old game, and there
X * are no pipes to read/write.
X */
X
X if (argv[1][0] == 'Z')
X { replaying = 1;
X gamename = "Iteratum Rog-O-Maticus";
X termination = "finis";
X logfilename = argv[4];
X startreplay (&logfile, logfilename);
X }
X else
X { frogue = fdopen (argv[1][0] - 'a', "r");
X trogue = fdopen (argv[1][1] - 'a', "w");
X setbuf (trogue, NULL);
X }
X
X /* The second argument to player is the process id of Rogue */
X if (argc > 2) rogpid = atoi (argv[2]);
X
X /* The third argument is an option list */
X if (argc > 3) sscanf (argv[3], "%d,%d,%d,%d,%d,%d,%d,%d",
X &cheat, ¬erm, &startecho, &nohalf,
X &emacs, &terse, &transparent, &quitat);
X
X /* The fourth argument is the Rogue name */
X if (argc > 4) strcpy (roguename, argv[4]);
X else sprintf (roguename, "Rog-O-Matic %s", RGMVER);
X
X /* Now count argument space and assign a global pointer to it */
X arglen = 0;
X for (i=0; i<argc; i++)
X { register int len = strlen (argv[i]);
X arglen += len + 1;
X while (len >= 0) argv[i][len--] = ' ';
X }
X parmstr = argv[0]; arglen--;
X
X /* If we are in one-line mode, then squirrel away stdout */
X if (emacs || terse)
X { realstdout = fdopen (dup (fileno (stdout)), "w");
X freopen ("/dev/null", "w", stdout);
X }
X
X initscr (); crmode (); noecho (); /* Initialize the Curses package */
X if (startecho) toggleecho (); /* Start logging? */
X clear (); /* Clear the screen */
X getrogver (); /* Figure out Rogue version */
X
X if (!replaying)
X { restoreltm (); /* Get long term memory of version */
X startlesson (); /* Start genetic learning */
X }
X
X /*
X * Give a hello message
X */
X
X sprintf (msg, " %s: version %s, genotype %d, quit at %d.",
X roguename, versionstr, geneid, quitat);
X
X if (emacs)
X { fprintf (realstdout, "%s (%%b)", msg); fflush (realstdout); }
X else if (terse)
X { fprintf (realstdout, "%s\n", msg); fflush (realstdout); }
X else
X { saynow (msg); }
X
X /*
X * Now that we have the version figured out, we can properly
X * interpret the screen. Force a redraw by sending a redraw
X * screen command (^L for old, ^R for new).
X *
X * Also identify wands (/), so that we can differentiate
X * older Rogue 3.6 from Rogue 3.6 with extra magic...
X */
X
X if (version < RV53A)
X sendnow ("%c//;", ctrl('l'));
X else
X sendnow ("%c;", ctrl('r'));
X
X /*
X * If we are not replaying an old game, we must position the
X * input after the next form feed, which signals the start of
X * the level drawing.
X */
X
X if (!replaying)
X while ((int) (ch = GETROGUECHAR) != CL_TOK && (int) ch != EOF);
X
X /*
X * Note: If we are replaying, the logfile is now in synch
X */
X
X getrogue (ill, 2); /* Read the input up to end of first command */
X
X /* Identify all 26 monsters */
X if (!replaying)
X for (ch = 'A'; ch <= 'Z'; ch++) send ("/%c", ch);
X
X /*
X * Signal handling. On an interrupt, Rogomatic goes into transparent
X * mode and clears what state information it can. This code is styled
X * after that in "UNIX Programming -- Second Edition" by Brian
X * Kernigan & Dennis Ritchie. I sure wouldn't have thought of it.
X */
X
X istat = signal (SIGINT, SIG_IGN); /* save original status */
X setjmp (commandtop); /* save stack position */
X if (istat != SIG_IGN)
X signal (SIGINT, onintr);
X
X if (interrupted)
X { saynow ("Interrupt [enter command]:");
X interrupted = 0;
X transparent = 1;
X }
X
X if (transparent) noterm = 0;
X
X while (playing)
X { refresh ();
X
X /* If we have any commands to send, send them */
X while (resend ())
X { if (startingup) showcommand (lastcmd);
X sendnow (";"); getrogue (ill, 2);
X }
X
X if (startingup) /* All monsters identified */
X { versiondep (); /* Do version specific things */
X startingup = 0; /* Clear starting flag */
X }
X
X if (!playing) break; /* In case we died */
X
X /*
X * No more stored commands, so either get a command from the
X * user (if we are in transparent mode or the user has typed
X * something), or let the strategize module try its luck. If
X * strategize fails we wait for the user to type something. If
X * there is no user (noterm mode) then use ROGQUIT to signal a
X * quit command.
X */
X
X if ((transparent && !singlestep) ||
X (!emacs && charsavail ()) ||
X !strategize())
X { ch = (noterm) ? ROGQUIT : getch ();
X
X switch (ch)
X { case '?': givehelp (); break;
X
X case '\n': if (terse)
X { printsnap (realstdout); fflush (realstdout); }
X else
X { singlestep = 1; transparent = 1; }
X break;
X
X /* Rogue Command Characters */
X case 'H': case 'J': case 'K': case 'L':
X case 'Y': case 'U': case 'B': case 'N':
X case 'h': case 'j': case 'k': case 'l':
X case 'y': case 'u': case 'b': case 'n':
X case 's': command (T_OTHER, "%c", ch); transparent = 1; break;
X
X case 'f': ch = getch ();
X for (s = "hjklyubnHJKLYUBN"; *s; s++)
X { if (ch == *s)
X { if (version < RV53A) command (T_OTHER, "f%c", ch);
X else command (T_OTHER, "%c", ctrl (ch));
X }
X }
X transparent = 1; break;
X
X case '\f': redrawscreen (); break;
X
X case 'm': dumpmonstertable (); break;
X
X case 'M': dumpmazedoor (); break;
X
X case '>': if (atrow == stairrow && atcol == staircol)
X command (T_OTHER, ">");
X transparent = 1; break;
X
X case '<': if (atrow == stairrow && atcol == staircol &&
X have (amulet) != NONE) command (T_OTHER, "<");
X transparent = 1; break;
X
X case 't': transparent = !transparent; break;
X
X case ')': markcycles (DOPRINT); at (row, col); break;
X
X case '+': setpsd (DOPRINT); at (row, col); break;
X
X case 'A': attempt = (attempt+1) % 5;
X saynow ("Attempt %d", attempt); break;
X
X case 'G': mvprintw (0, 0,
X "%d: Sr %d Dr %d Re %d Ar %d Ex %d Rn %d Wk %d Fd %d, %d/%d",
X geneid, k_srch, k_door, k_rest, k_arch,
X k_exper, k_run, k_wake, k_food, genebest, geneavg);
X clrtoeol (); at (row, col); refresh (); break;
X
X case ':': chicken = !chicken;
X say (chicken ? "chicken" : "aggressive");
X break;
X
X case '~': saynow
X ("Rogomatic version %s, Rogue version %s (%d), quit at %d",
X RGMVER, versionstr, version, quitat);
X break;
X
X case '[': at (0,0);
X printw ("%s = %d, %s = %d, %s = %d, %s = %d.",
X "hitstokill", hitstokill,
X "goodweapon", goodweapon,
X "usingarrow", usingarrow,
X "goodarrow", goodarrow);
X clrtoeol ();
X at (row, col);
X refresh ();
X break;
X
X case '-': saynow (statusline ());
X break;
X
X case '`': clear ();
X summary (NULL, '\n');
X pauserogue ();
X break;
X
X case '|': clear ();
X timehistory (NULL, '\n', 0);
X pauserogue ();
X break;
X
X case 'r': resetinv (); say ("Inventory reset."); break;
X
X case 'i': clear (); dumpinv (NULL); pauserogue (); break;
X
X case '/': dosnapshot ();
X break;
X
X case '(': clear (); dumpdatabase (); pauserogue (); break;
X
X case 'c': cheat = !cheat;
X say (cheat ? "cheating" : "righteous");
X break;
X
X case 'd': toggledebug (); break;
X
X case 'e': toggleecho (); break;
X
X case '!': dumpstuff (); break;
X
X case '@': dumpmonster (); break;
X
X case '#': dumpwalls (); break;
X
X case '%': clear (); havearmor (1, DOPRINT, ANY); pauserogue (); break;
X
X case '=': clear (); havering (1, DOPRINT); pauserogue (); break;
X
X case '$': clear (); haveweapon (1, DOPRINT); pauserogue (); break;
X
X case '^': clear (); havebow (1, DOPRINT); pauserogue (); break;
X
X case '{': promptforflags (); break;
X
X case '&': saynow ("Object count is %d.", objcount); break;
X
X case '*': blinded = !blinded;
X saynow (blinded ? "blinded" : "sighted");
X break;
X
X case 'C': cosmic = !cosmic;
X saynow (cosmic ? "cosmic" : "boring");
X break;
X
X case 'E': dwait (D_ERROR, "Testing the ERROR trap..."); break;
X
X case 'F': dwait (D_FATAL, "Testing the FATAL trap..."); break;
X
X case 'R': if (replaying)
X { positionreplay (); getrogue (ill, 2);
X if (transparent) singlestep = 1; }
X else
X saynow ("Replay position only works in replay mode.");
X break;
X
X case 'S': quitrogue ("saved", Gold, SAVED);
X playing = 0; break;
X
X case 'Q': quitrogue ("user typing quit", Gold, FINISHED);
X playing = 0; break;
X
X case ROGQUIT: dwait (D_ERROR, "Strategize failed, gave up.");
X quitrogue ("gave up", Gold, SAVED); break;
X }
X }
X else
X { singlestep = 0;
X }
X }
X
X if (! replaying)
X { saveltm (Gold); /* Save new long term memory */
X endlesson (); /* End genetic learning */
X }
X
X /* Print termination messages */
X at (23, 0); clrtoeol (); refresh ();
X endwin (); nocrmode (); noraw (); echo ();
X
X if (emacs)
X { if (*sumline) fprintf (realstdout, " %s", sumline);
X }
X else if (terse)
X { if (*sumline) fprintf (realstdout, "%s\n",sumline);
X fprintf (realstdout, "%s %s est.\n", gamename, termination);
X }
X else
X { if (*sumline) printf ("%s\n",sumline);
X printf ("%s %s est.\n", gamename, termination);
X }
X
X /*
X * Rename log file, if it is open
X */
X
X if (logging)
X { char lognam[128];
X
X /* Make up a new log file name */
X sprintf (lognam, "%0.4s.%d.%d", ourkiller, MaxLevel, ourscore);
X
X /* Close the open file */
X toggleecho ();
X
X /* Rename the log file */
X if (link (ROGUELOG, lognam) == 0)
X { unlink (ROGUELOG);
X printf ("Log file left on %s\n", lognam);
X }
X else
X printf ("Log file left on %s\n", ROGUELOG);
X }
X
X exit (0);
X}
X
X/*
X * onintr: The SIGINT handler. Pass interrupts to main loop, setting
X * transparent mode. Also send some synchronization characters to Rogue,
X * and reset some goal variables.
X */
X
Xonintr ()
X{ sendnow ("n\033"); /* Tell Rogue we don't want to quit */
X if (logging) fflush (fecho); /* Print out everything */
X refresh (); /* Clear terminal output */
X clearsendqueue (); /* Clear command queue */
X setnewgoal (); /* Don't believe ex */
X transparent = 1; /* Drop into transprent mode */
X interrupted = 1; /* Mark as an interrupt */
X noterm = 0; /* Allow commands */
X longjmp (commandtop); /* Back to command Process */
X}
X
X/*
X * startlesson: Genetic learning algorithm, pick a genotype to
X * test this game, and set the parameters (or "knobs") accordingly.
X */
X
Xstartlesson ()
X{ sprintf (genelog, "%s/GeneLog%d", RGMDIR, version);
X sprintf (genepool, "%s/GenePool%d", RGMDIR, version);
X sprintf (genelock, "%s/GeneLock%d", RGMDIR, version);
X
X srand (0); /* Start random number generator */
X critical (); /* Disable interrupts */
X
X /* Serialize access to the gene pool */
X if (lock_file (genelock, MAXLOCK)) /* Lock the gene pool */
X { if (openlog (genelog) == NULL) /* Open the gene log file */
X saynow ("Could not open file %s", genelog);
X if (! readgenes (genepool)) /* Read the gene pool */
X initpool (MAXKNOB, 20); /* Random starting point */
X setknobs (&geneid, knob, &genebest, &geneavg); /* Select a genotype */
X writegenes (genepool); /* Write out the gene pool */
X closelog (); /* Close the gene log file */
X unlock_file (genelock); /* Unlock the gene pool */
X }
X else
X fprintf (stderr, "Cannot lock gene pool to read '%s'\n", genepool);
X
X uncritical (); /* Reenable interrupts */
X
X /* Cache the parameters for easier use */
X k_srch = knob[K_SRCH]; k_door = knob[K_DOOR];
X k_rest = knob[K_REST]; k_arch = knob[K_ARCH];
X k_exper = knob[K_EXPER]; k_run = knob[K_RUN];
X k_wake = knob[K_WAKE]; k_food = knob[K_FOOD];
X}
X
X/*
X * endlesson: if killed, total winner, or quit for scoreboard,
X * evaluate the performance of this genotype and save in genepool.
X */
X
Xendlesson ()
X{ if (geneid > 0 &&
X (stlmatch (termination, "perditus") ||
X stlmatch (termination, "victorius") ||
X stlmatch (termination, "callidus")))
X { critical (); /* Disable interrupts */
X
X if (lock_file (genelock, MAXLOCK)) /* Lock the score file */
X { openlog (genelog); /* Open the gene log file */
X if (readgenes (genepool)) /* Read the gene pool */
X { evalknobs (geneid,Gold,Level); /* Add the trial to the pool */
X writegenes (genepool); } /* Write out the gene pool */
X closelog ();
X unlock_file (genelock); /* Disable interrupts */
X }
X else
X fprintf (stderr, "Cannot lock gene pool to evaluate '%s'\n", genepool);
X
X uncritical (); /* Re-enable interrupts */
X }
X}
/
echo 'x - rand.c'
sed 's/^X//' > rand.c << '/'
X/*
X * rand.c: Rog-O-Matic XIV (CMU) Fri Dec 28 23:42:39 1984 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * A very random generator, period approx 6.8064e16.
X *
X * Uses algorithm M, "Art of Computer Programming", Vol 2. 1969, D.E.Knuth.
X *
X * Two generators are used to derive the high and low parts of sequence X,
X * and another for sequence Y. These were derived by Michael Mauldin.
X *
X * Usage: initialize by calling srand(seed), then rand() returns a random
X * number from 0..2147483647. srand(0) uses the current time as
X * the seed.
X *
X * Author: Michael Mauldin, June 14, 1983.
X */
X
X/* Rand 1, period length 444674 */
X# define MUL1 1156
X# define OFF1 312342
X# define MOD1 1334025
X# define RAND1 (seed1=((seed1*MUL1+OFF1)%MOD1))
X# define Y RAND1
X
X/* Rand 2, period length 690709 */
X# define MUL2 1366
X# define OFF2 827291
X# define MOD2 1519572
X# define RAND2 (seed2=((seed2*MUL2+OFF2)%MOD2))
X
X/* Rand 3, period length 221605 */
X# define MUL3 1156
X# define OFF3 198273
X# define MOD3 1329657
X# define RAND3 (seed3=((seed3*MUL3+OFF3)%MOD3))
X
X/*
X * RAND2 generates 19 random bits, RAND3 generates 17. The X sequence
X * is made up off both, and thus has 31 random bits.
X */
X
X# define X ((RAND2<<13 ^ RAND3>>3) & 017777777777)
X
X# define AUXLEN 97
Xstatic int seed1=872978, seed2=518652, seed3=226543, auxtab[AUXLEN];
X
Xsrand (seed)
Xint seed;
X{ register int i;
X
X if (seed == 0) seed = time();
X
X /* Set the three random number seeds */
X seed1 = (seed1+seed) % MOD1;
X seed2 = (seed2+seed) % MOD2;
X seed3 = (seed3+seed) % MOD3;
X
X for (i=AUXLEN; i--; )
X auxtab[i] = X;
X}
X
Xint rand ()
X{ register int j, result;
X
X j = AUXLEN * Y / MOD1; /* j random from 0..AUXLEN-1 */
X result = auxtab[j];
X auxtab[j] = X;
X return (result);
X}
X
Xrandint (max)
Xregister int max;
X{ register int j, result;
X
X j = AUXLEN * Y / MOD1; /* j random from 0..AUXLEN-1 */
X result = auxtab[j];
X auxtab[j] = X;
X return (result % max);
X}
/
echo 'x - rplot'
sed 's/^X//' > rplot << '/'
Xcolrm 48 < /usr/mlm/games/rlog/rgmscore5.2 | datesub | sort -u +0n +1n +2n +4n +5 | rgmplot $*
/
echo 'x - termtokens.h'
sed 's/^X//' > termtokens.h << '/'
X/*
X * termtokens.h: Rog-O-Matic XIV (CMU) Fri Dec 28 22:16:05 1984 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * Various tokens used by the screen reading package.
X */
X
X# define BS_TOK ctrl('H')
X# define CE_CHR ctrl('S')
X# define CE_TOK -2
X# define CL_CHR ctrl('L')
X# define CL_TOK ctrl('L')
X# define CM_CHR 'a'
X# define CM_TOK -3
X# define CR_TOK ctrl('M')
X# define DO_CHR '<'
X# define DO_TOK -4
X# define ER_TOK -5
X# define LF_TOK ctrl('J')
X# define ND_CHR '='
X# define ND_TOK -6
X# define SE_CHR 'd'
X# define SE_TOK -7
X# define SO_CHR 'D'
X# define SO_TOK -8
X# define TA_TOK ctrl('I')
X# define UP_CHR ';'
X# define UP_TOK -9
/
echo 'x - things.c'
sed 's/^X//' > things.c << '/'
X/*
X * things.c: Rog-O-Matic XIV (CMU) Thu Jan 31 18:13:32 1985 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * This file contains much of the code to handle Rog-O-Matics inventory.
X */
X
X# include <ctype.h>
X# include <curses.h>
X# include "types.h"
X# include "globals.h"
X
X/*
X * wear: This primitive function issues a command to put on armor.
X */
X
Xwear (obj)
Xint obj;
X{
X if (currentarmor != NONE)
X { dwait (D_FATAL, "Trying to put on a second coat of armor");
X return (0);
X }
X
X if (cursedarmor) return (0);
X
X command (T_HANDLING, "W%cI%c", LETTER (obj), LETTER (obj));
X return (1);
X}
X
X/*
X * takeoff: Remove the current armor.
X */
X
Xtakeoff ()
X{
X if (currentarmor == NONE)
X { dwait (D_ERROR, "Trying to take off armor we don't have on!");
X return (0);
X }
X
X if (cursedarmor) return (0);
X
X command (T_HANDLING, "T");
X return (1);
X}
X
X/*
X * wield: This primitive function issues a command to wield a weapon.
X */
X
Xwield (obj)
Xint obj;
X{
X if (cursedweapon) return (0);
X
X if (version < RV53A)
X command (T_HANDLING, "w%cw%c%c", LETTER (obj), ESC, ctrl('r'));
X else
X command (T_HANDLING, "w%cw%c%c", LETTER (obj), ESC, ctrl('p'));
X
X return (1);
X}
X
X/*
X * drop: called with an integer from 0 to 25, drops the object if possible
X * and returns 1 if it wins and 0 if it fails. Could be extended to
X * throw object into a wall to destroy it, but currently it merely sets
X * the USELESS bit for that square.
X */
X
Xdrop (obj)
Xint obj;
X{
X /* Cant if there is not something there */
X if (inven[obj].count < 1) return (0);
X
X /* read unknown scrolls rather than dropping them */
X if (inven[obj].type == scroll && !itemis (obj, KNOWN) && reads (obj))
X { prepareident (pickident (), obj);
X return (1);
X }
X
X /* quaff unknown potions rather than dropping them */
X if (inven[obj].type == potion && !itemis (obj, KNOWN) && quaff (obj))
X return (1);
X
X if (itemis (obj, INUSE) || on (STUFF | TRAP | STAIRS | DOOR))
X return (0);
X
X command (T_HANDLING, "d%c", LETTER (obj));
X return (1);
X}
X
X/*
X * quaff: build and send a quaff potion command.
X */
X
Xquaff (obj)
Xint obj;
X{
X if (inven[obj].type != potion)
X { dwait (D_ERROR, "Trying to quaff %c", LETTER (obj));
X usesynch = 0;
X return (0);
X }
X
X command (T_HANDLING, "q%c", LETTER (obj));
X return (1);
X}
X
X/*
X * reads: build and send a read scroll command.
X */
X
Xreads (obj)
Xint obj;
X{
X if (inven[obj].type != scroll)
X { dwait (D_ERROR, "Trying to read %c", LETTER (obj));
X usesynch = 0;
X return (0);
X }
X
X command (T_HANDLING, "r%c", LETTER (obj));
X return (1);
X}
X
X/*
X * build and send a point with wand command.
X */
X
Xpoint (obj, dir)
Xint obj, dir;
X{
X if (inven[obj].type != wand)
X { dwait (D_ERROR, "Trying to point %c", LETTER (obj));
X return (0);
X }
X
X command (T_HANDLING, "%c%c%c",
X (version < RV52A) ? 'p' : 'z', /* R5.2 MLM */
X keydir[dir], LETTER (obj));
X return (1);
X}
X
X/*
X * throw: build and send a throw object command.
X */
X
Xthrow (obj, dir)
Xint obj, dir;
X{
X if (obj < 0 || obj >= invcount)
X { dwait (D_ERROR, "Trying to throw %c", LETTER (obj));
X return (0);
X }
X
X command (T_HANDLING, "t%c%c", keydir[dir], LETTER (obj));
X return (1);
X}
X
X/*
X * puton: build and send a command to put on a ring.
X */
X
Xputon (obj)
Xint obj;
X{
X if (leftring == NONE && rightring == NONE)
X { command (T_HANDLING, "P%cl", LETTER (obj)); return (1); }
X
X if (leftring == NONE || rightring == NONE)
X { command (T_HANDLING, "P%c", LETTER (obj)); return (1); }
X
X return (0);
X}
X
X/*
X * removering: build a command to remove a ring. It is left in the pack.
X */
X
Xremovering (obj)
Xint obj;
X{
X if (leftring != NONE && rightring != NONE && leftring == obj)
X { command (T_HANDLING, "Rl"); return (1); }
X
X if (leftring != NONE && rightring != NONE && rightring == obj)
X { command (T_HANDLING, "Rr"); return (1); }
X
X if (leftring == obj || rightring == obj)
X { command (T_HANDLING, "R"); return (1); }
X
X return (0);
X}
X
X/*
X * initstufflist: clear the list of objects on this level.
X */
X
Xinitstufflist ()
X{ slistlen = 0;
X}
X
X/*
X * addstuff: add an item to the list of items on this level.
X */
X
Xaddstuff (ch, row, col)
Xchar ch;
Xint row, col;
X{ /* if (seerc ('@', row, col)) return (0); */ /* Removed MLM 10/28/83 */
X if (onrc (STUFF, row, col))
X deletestuff (row, col);
X slist[slistlen].what = translate[ch];
X slist[slistlen].srow = row;
X slist[slistlen].scol = col;
X if (++slistlen >= MAXSTUFF) dwait (D_FATAL, "Too much stuff");
X setrc (STUFF, row, col);
X}
X
X/*
X * deletestuff: remove the object from the stuff list at location (x,y)
X */
X
Xdeletestuff (row, col)
Xint row, col;
X{ register int i;
X unsetrc (STUFF, row, col);
X for (i = 0; i < slistlen; ++i)
X if (slist[i].scol == col && slist[i].srow == row)
X { slist[i] = slist[--slistlen];
X i--; /* MLM 10/23/82 */
X }
X}
X
X/*
X * dumpstuff: (debugging) dump the list of objects on this level.
X */
X
Xdumpstuff ()
X{ register int i;
X at (1, 0);
X for (i = 0; i < slistlen; ++i)
X printw ("%d at %d,%d (%c)\n",
X slist[i].what, slist[i].srow, slist[i].scol,
X screen[slist[i].srow][slist[i].scol]);
X printw ("You are at %d,%d.", atrow, atcol);
X at (row, col);
X}
X
X/*
X * display: Print a message on line 1 of the screen.
X */
X
Xdisplay (s)
Xchar *s;
X{ saynow (s);
X msgonscreen=1;
X}
X
X/*
X * prepareident: Set nextid and afterid to proper values
X */
X
Xprepareident (obj, iscroll)
Xint obj, iscroll;
X{ nextid = LETTER (obj);
X afterid = (iscroll > obj || inven[iscroll].count > 1) ? nextid : nextid-1;
X}
X
X/*
X * pickident: Pick an object to be identified. This is a preference
X * ordering of objects. If nothing else, return 0 (the index of the
X * first item in the pack).
X */
X
Xint pickident ()
X{ register int obj;
X
X if ((obj=unknown (ring)) != NONE);
X else if ((obj=unidentified (wand)) != NONE);
X else if ((obj=unidentified (scroll)) != NONE);
X else if ((obj=unidentified (potion)) != NONE);
X else if ((obj=unknown (scroll)) != NONE);
X else if ((obj=unknown (potion)) != NONE);
X else if ((obj=unknown (hitter)) != NONE);
X else obj = 0;
X
X return (obj);
X}
X
X/*
X * unknown: Return the index of any unknown object of type otype
X */
X
Xint unknown (otype)
Xstuff otype;
X{ register int i;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X (inven[i].type == otype) &&
X (itemis (i, KNOWN) == 0) &&
X (!used (inven[i].str)))
X return (i);
X
X return (NONE);
X}
X
X/*
X * unidentified: Return the index of any unidentified object of type otype
X */
X
Xint unidentified (otype)
Xstuff otype;
X{ register int i;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X (inven[i].type == otype) &&
X (itemis (i, KNOWN) == 0) &&
X (used (inven[i].str)))
X return (i);
X
X return (NONE);
X}
X
X/*
X * haveother: Return the index of any unknown object of type 'otype',
X * but not 'other'.
X */
X
Xint haveother (otype,other)
Xstuff otype;
Xint other;
X{ register int i;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X (inven[i].type == otype) &&
X (itemis (i, KNOWN) == 0) &&
X (i != other))
X return (i);
X
X return (NONE);
X}
X
X/*
X * have: Return the index of any object of type otype
X */
X
Xint have (otype)
Xstuff otype;
X{ register int i;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X inven[i].type == otype) return (i);
X
X return (NONE);
X}
X
X/*
X * havenamed: Return the index of any object of type otype named
X * name which is not in use .
X */
X
Xint havenamed (otype,name)
Xstuff otype;
Xchar *name;
X{ register int i;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X inven[i].type == otype &&
X (*name == 0 || streq (inven[i].str,name)) &&
X !itemis (i, INUSE))
X return (i);
X
X return (NONE);
X}
X
X/*
X * havewand: Return the index of a charged wand or staff
X */
X
Xint havewand (name)
Xchar *name;
X{ register int i;
X
X /* Find one with positive charges */
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X inven[i].type == wand &&
X (*name == 0 || streq (inven[i].str,name)) &&
X (inven[i].charges > 0))
X return (i);
X
X /* Find one with unknown charges */
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X inven[i].type == wand &&
X (*name == 0 || streq (inven[i].str,name)) &&
X inven[i].charges == UNKNOWN)
X return (i);
X
X return (NONE);
X}
X
X/*
X * wearing: Return the index if wearing a ring with this title
X */
X
Xwearing (name)
Xchar *name;
X{ register int result = NONE;
X
X if (leftring != NONE && itemis (leftring, INUSE) &&
X streq (inven[leftring].str, name))
X result = leftring;
X
X else if (rightring != NONE && itemis (rightring, INUSE) &&
X streq (inven[rightring].str, name))
X result = rightring;
X
X return (result);
X}
X
X/*
X * Return the index of any object of type otype and name name only
X * if we have count or more of them. This way we can avoid using the
X * last of something .
X */
X
Xint havemult (otype, name, count)
Xstuff otype;
Xchar *name;
Xint count;
X{ register int i, num=count;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X inven[i].type == otype &&
X (*name == 0 || streq (inven[i].str,name)) &&
X (num -= inven[i].count) <= 0)
X return (i);
X
X return (NONE);
X}
X
X/*
X * haveminus: Return the index of something if it is a minus item
X * (used to throw away stuff at end)
X */
X
Xint haveminus ()
X{ register int i;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X inven[i].phit != UNKNOWN &&
X inven[i].phit < 0)
X return (i);
X
X return (NONE);
X}
X
X/*
X * haveuseless: return the index of useless arrows, and empty wands.
X */
X
Xint haveuseless ()
X{ register int i;
X for (i=0; i<invcount; ++i)
X if (inven[i].count &&
X inven[i].type == wand && inven[i].charges == 0 ||
X itemis (i, WORTHLESS) && streq (inven[i].str, "arrow"))
X return (i);
X
X return (NONE);
X}
X
X/*
X * willrust: return true if a suit of armor can rust
X */
X
Xwillrust (obj)
Xint obj;
X{ return (! (armorclass (obj) > 8 || armorclass (obj) < -5 ||
X itemis (obj, PROTECTED) ||
X stlmatch (inven[obj].str, "leather")));
X}
X
X/*
X * wielding: return true if we are wielding an object of type 'otype'
X */
X
Xwielding (otype)
Xstuff otype;
X{
X return (inven[currentweapon].type == otype);
X}
X
X/*
X * hungry: return true if we are hungry, weak, or fainting
X */
X
Xhungry ()
X{ return (*Ms == 'H' || *Ms == 'W' || *Ms == 'F'); }
X
X/*
X * weak: return true if we are weak or fainting
X */
X
Xweak ()
X{ return (*Ms == 'W' || *Ms == 'F'); }
X
X/*
X * fainting: return true if we are fainting
X */
X
Xfainting ()
X{ return (*Ms == 'F'); }
X
X/*
X * havefood: return true if we have more than 'n' foods, modified
X * by the genetic variable k_food (higher values of k_food mean this
X * routine returns true less often).
X */
X
Xint havefood (n)
Xint n;
X{ int remaining, foodest, desired;
X
X if (hungry () || weak () || fainting ())
X return (0);
X
X remaining = 800 - turns + lastate;
X if (remaining < 0) remaining = 0;
X foodest = larder * 1000 + remaining;
X desired = n * 1000 * 50 / (100-k_food);
X
X return (foodest > desired);
X}
/
echo 'Part 05 of Rog-O-Matic XIV complete.'
exit
More information about the Comp.sources.unix
mailing list