Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10 5/3/83; site cmu-cs-cad.ARPA Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!rochester!cmu-cs-pt!cmu-cs-cad!mlm From: mlm@cmu-cs-cad.ARPA (Michael Mauldin) Newsgroups: net.sources Subject: Rog-O-Matic XIV (part 05 of 10) Message-ID: <275@cmu-cs-cad.ARPA> Date: Fri, 1-Feb-85 13:34:05 EST Article-I.D.: cmu-cs-c.275 Posted: Fri Feb 1 13:34:05 1985 Date-Received: Sun, 3-Feb-85 09:48:40 EST Organization: Carnegie-Mellon University, CS/RI Lines: 1493 #!/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 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@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 X# include X# include X# include 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= 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 X# include 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 0)) X return (i); X X /* Find one with unknown charges */ X for (i=0; i 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