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, &noterm, &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