Rog-O-Matic XIV (part 06 of 10)

Michael Mauldin mlm at cmu-cs-cad.ARPA
Sat Feb 2 02:30:21 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 06 of 10:'
echo 'x - rogomatic.6'
sed 's/^X//' > rogomatic.6 << '/'
X.TH ROGOMATIC 6 02/01/85
X.UC 4
X.SH NAME
Xrogomatic \- Automatically Exploring The Dungeons of Doom
X.SH SYNOPSIS
X.I rogomatic
X[
X.I -cefprstuw
Xor
X.I save_file
X]
X.SH DESCRIPTION
X.PP
X.I Rog-O-Matic
Xis a computer fantasy game with a newer twist.  It is crt oriented and the
Xobject of the game is to automatically survive the attacks of various
Xmonsters and get a lot of gold, rather than having to actually type the
Xrequired commands yourself.
X.PP
XOnce you have entered the world of 
X.I Rog-O-Matic
Xyou will stay there, passively watching the game unfold before you much
Xlike a catatonic teenager watching television.
XShould you wish to intervene, type the 
X.B t
Xcommand and 
X.I Rog-O-Matic
Xwill enter transparent mode. Here you can type several commands, the
Xmost useful of which is the
X.B ?
Xcommand, which prints out the next help line. Press the 
X.B ?
Xkey repeatedly to see all of the help. 
XSome useful commands are:
X.B h
X.B j
X.B k
X.B l
X.B H
X.B J
X.B K
X.B L
X.B b
X.B n
X.B y
X.B u
X.B f
X.B s
X.B >
X.B <
X.B S
X.B Q.
XThese have the same meaning as in normal Rogue. To return to 
X.I Rog-O-Matic
Xmode, type the 
X.B t
Xcommand again.
X.PP
XSome useful commands are:
X.TP
X.B t
X.I Toggle,
Xtoggles the setting of the
X.I transparent
Xmode flag. In transparent mode, 
X.I Rog-O-Matic
Xwill not automatically attack monsters, pick up treasure, or explore
Xaround.  Unfortunately, there is no way to enter complicated commands
Xlike 
X.I quaff
Xor
X.I read
Xin transparent mode.  Typing any 
X.I Rogue
Xcommand, or single-step command also enables transparent mode.
X.TP
X.B Q
X.I Quit,
Xtells 
X.I Rog-O-Matic 
Xto quit the game. The score is logged in the score file, and possibly the
X.I Rogue
Xtop ten, and the game is terminated.
X.TP
X.B S
X.I Save,
Xthe game is saved to the default save file, set by the
X.I <file>
Xargument to 
X.I rogomatic
Xor the 
X.I ROGUEOPTS
Xenvironment variable. The game may be restarted later.
X.TP
X.B c
X.I Cheat,
Xtells 
X.I Rog-O-Matic
Xto take advantage of idiosyncracies in the
X.I Rogue
Xgame to get a higher score. This is unfortunately necessary to allow fair
Xcompetition with other human top ten players who take advantage of the same
Xbugs. Note that this option should only be used on the Unix version
Xof Rogue, since the VMS version does not exhibit the same bugs.
XNote too that when playing against 
X.I Rogue 5.2
Xand
X.I Rogue 5.3
Xno cheating is done, since the bugs are not widely known and used by
Xhuman competition.
X.TP
X.B d
X.I Debugging,
Xtoggles the debugging flag, which is useless to non-wizard
Xplayers (although it is entertaining if your terminal has reverse video).
X.TP
X.B e
X.I Echoing,
Xcauses a copy of the game to be written to file 
X.I roguelog
Xin the current directory. Typing 
X.B e
Xa second time closes the log file.  When the game is ended, the roguelog
Xfile is renamed to <killer>.<level>.<score> so if a troll killed poor
X.I Rog-O-Matic
Xon level 14 leaving him with a score of 3088, the file would be named
X.I trol.14.3088.
XNote that only the first four characters of the killer are used.
XThe
X.B -p
Xoption will replay a saved game.  Additionally, a stop action command
X(carriage return gives a single step) has been added.  Pigs didn't fly
Xfirst!
X.TP
X.B i
X.I Inventory,
Xdumps the current inventory on the screen.
X.TP
X.B m
X.I Monster list,
Xshows the current long term memory evaluation of the monsters.
X.I Rog-O-Matic
Xnows keeps a long term memory file (for each version of Rogue) in the
Xscore directory, and records the meanness of each monster it finds.
XThis command prints out the letter, name, and strength of each monster.
XStrength is listed as three numbers: expected damage (scaled by 10) and
Xmaximum damage (unscaled) are shown in parentheses, and the mean number
Xof arrows required to kill a monster is shown in square brackets.
X.TP
X.B CR
X.I Single step,
Xa carriage return enables
X.I transparent
Xmode, and causes
X.I Rog-O-Matic
Xto single-step. The command sent is printed at the
Xbottom right hand of the screen.
X.TP
X.B /
X.I Snapshot,
Xa timestamp, the current screen, and the current inventory are appended
Xto file
X.I rgm.snapshot
Xin the current directory.
X.TP
X.B $
X.I Weaponrank,
Xdumps 
X.I Rog-O-Matic's 
Xcurrent estimate of his weapons rankings.
X.TP
X.B %
X.I Armorrank,
Xdumps 
X.I Rog-O-Matic's 
Xcurrent estimate of his armor rankings.
X.TP
X.B =
X.I Ringrank,
Xdumps 
X.I Rog-O-Matic's 
Xcurrent estimate of his ring rankings.
X.TP
X.B -
X.I Status,
Xprints out a status line indicating various things like whether 
X.I Rog-O-Matic
Xis confused, has red hands, is wearing cursed armor or wielding a cursed
Xweapon, and which monsters have been genocided.
XIt also prints the number of turns elapsed in the game.
X.TP
X.B `
X.I Summary,
Xa backquote prints a short summary of the game.
X.TP
X.B ~
X.I Version,
Xprints the version of
X.I Rogue
Xand
X.I Rog-O-Matic
Xbeing used. It also prints the current goal score.
X.TP
X.B G
X.I Genotype,
Xdisplays the settings of the genetically learned parameters of the
Xgenotype playing now.
X.TP
X.B R
X.I Replay position,
Xallows you to skip around in a log file when replaying an old game.
XThis key must be followed by either
X.B f, p, c, n,
Xor
X.B l.
XThese indicate you wish to see the
X.I first, previous, current, next,
Xor
X.B last
Xlevels of the game.  The first time you enter the
X.B R
Xcommand, there will be a pause of several seconds while the whole log
Xfile is digested.  After this initialization, there should be no delay
Xwhen skipping around in the log file.  After you have skipped once, the
Xprogram won't terminate at the end of the file until you enter the
X.B Q
X.I (quit)
Xcommand.  This way you can replay the last level over (and over...).
X.IR
X.PP
XWhen the game ends, either by your death, when you quit, or when 
X.I Rog-O-Matic
Xdies horribly of some bug, you will not get a list of the top-ten scorers.
XThe scoring is based entirely upon useless criteria anyway.
X.I Rog-O-Matic
Xdoes keep a list of its games. To see the best 
X.I Rog-O-Matic
Xgames, use "rogomatic -s" which dumps the current scores in reverse order.
X.PP
XFor more detailed directions, read the source.
X.SH OPTIONS
X.TP
X.B -c
XTurns on cheat mode. See also the
X.B c
Xcommand in transparent mode.
X.TP
X.B -e
XTurns on logging. See also the
X.B e
Xcommand in transparent mode.
X.TP
X.B -f
XFile command. The next argument is the file name of the 
X.I Rogue
Xexecutable to use.
X.I Rog-O-Matic
Xwill play versions 3.6, 5.2, and 5.3;
X.I rogomatic -f /usr/games/rogue
XWould run 
X.I Rog-O-Matic
Xagainst the standard system 
X.I Rogue
Xgame.  You can run Rog-O-Matic on modified rogues using this option,
Xbut be warned that the interface must be completely compatible with
Xone of the standard versions of Rogue listed, and the version number
Xprinted must be either "3.6," "5.2," or "5.3."
X.TP
X.B -p
XReplay option. Typing 
X.I rogomatic -p
Xwill replay log file 
X.I roguelog.
XOr use
X.I rogomatic -p <file>
Xto replay a specific file.
X.TP
X.B -r
XRestore option. Plays the game saved in the default 
X.I Rogue
Xsave file.
X.TP
X.B -s
XScores. Lists the 
X.I Rog-O-Matic 
Xscoreboard.
X.TP
X.B -t
XTerse mode. In terse mode,
X.I Rog-O-Matic 
Xwill only print a summary after each level explored.
X.TP
X.B -u
XUser mode. Tells 
X.I Rog-O-Matic 
Xto start up in transparent mode, so the user can type commands before
X.I Rog-O-Matic
Xstarts exploring level 1.
X.SH FILES
XThere are two executable files: rogomatic and player.  Rogomatic
Xis a small program which forks and execs the Rogue process and then execs the
Xplayer process.  Thus you must have access to all of these files.  These are
Xavailable as
X.PP
X	/usr/mlm/bin/rogomatic on the GP-Vax
X.br
X	/usr/mlm/bin/player on the GP-Vax
X.PP
XIf you are moving these files to another machine, you must either edit the 
Xrogomatic module to change the name of the player process, or run rogomatic 
Xfrom a directory containing the player module.
X.PP
XThe score file is kept in /usr/mlm/games/rlog/rgmscore<version>.
XIf this file does not exist, it is created.
X.SH SEE ALSO
Xrogue(6)
X.SH BUGS
XOccasionally 
X.I Rog-O-Matic
Xwill dead-lock waiting for input from 
X.I Rogue.
XWhen this happens, type an interrupt and enter the
X.I t
Xcommand again. This usually wakes it up enough to re-start the game.
XIn completely unusual cases, try interrupting and then entering the
X.I S
Xcommand to save the game, and then re-start with "rogomatic -r". Sometimes
Xyou will have to use transparent mode to get it down to the next level
Xbefore turning it loose again.
X.SH HISTORY
X.TP
X01-Feb-85  Michael Mauldin (mlm) at CMU
XAdded genetic learning, UTexas mods, new titlepage, new version XIV.
X.TP
X01-Nov-83  Michael Mauldin (mlm) at CMU
XModified to include long term memory, and to play Rogue 5.3.
X.TP
X31-Aug-83  Michael Mauldin (mlm) at CMU
XModified the replay command to allow skipping around and replaying
Xindividual levels over and over.
X.TP
X16-Jun-83  Michael Mauldin (mlm) at CMU
XAdded error logging, single-step mode, fixed several small bug fixes,
Xmodified title animation to display correct version number.
X.TP
X23-Apr-83  Hamey and Mauldin at CMU
XVersion XII, replaced
X.I replay
Xcommand with an option which causes input to come from a log file, and
Xnot from the Rogue process.  This removes the necessity of a standalone
Xreplay command.
X.TP
X16-Apr-83  Leonard Hamey (lgh) at CMU
XAdded ability to infer unseen halls and use them in searchto without
Xhaving trodden on them first.  Modified exploration algorithm.
X.TP
X07-Nov-82  Michael Mauldin (mlm) at CMU
XAdded archery, homogenous ring handling, removed the keyact kluge.
X.TP
X27-Oct-82  Appel, Hamey, Jacobson, and Mauldin at CMU
XAdded support for Rogue 5.2, and various other improvements and fixes.
X.TP
X30-Sep-82  Michael Mauldin (mlm) at CMU
XAdded improved Invisible Stalker code, modified strength management,
XAmulet handling, improved cheating. Was a total winner on Level 26 with a
Xscore of 14,655.
X.TP
X18-May-82  Appel, Jacobson, and Mauldin at CMU
XAdded running away, level searching, wand and staff usage.
X.TP
X26-Apr-82  Michael Mauldin (mlm) at CMU 
XAdded replay ability.
X.TP
X22-Apr-82  Michael Mauldin (mlm) at CMU 
XAdded cheating mode and enhanced magic handling abilities.
X.TP
X11-Apr-82  Michael Mauldin (mlm) at CMU 
XAdded searching for secret doors.
XModified breadth first search to avoid traps and prefer known safe squares.
XAdded detection of potions of blindness.
X.TP
X21-Mar-82  Michael Mauldin (mlm) at CMU 
XAdded termcap support.
X.TP
X12-Jan-82  Andrew Appel (awa) and Guy Jacobson (guy) at CMU
XAdded breadth first search.
X.TP
X14-Oct-81  Andrew Appel (awa) and Guy Jacobson (guy) at CMU
XCreated.
/
echo 'x - rooms.c'
sed 's/^X//' > rooms.c << '/'
X/*
X * rooms.c: Rog-O-Matic XIV (CMU) Thu Jan 31 20:22:14 1985 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * Contains functions which deal with the geometry of
X * the dungeon levels, rooms, and passages.
X */
X
X# include <curses.h>
X# include <ctype.h>
X# include "types.h"
X# include "globals.h"
X
X# define sign(x) ((x)?(x)>0?1:-1:0)
X# define EXPLORED 01
X# define HASROOM  02
X
Xint levelmap[9];
X
X/*
X * newlevel: Clear old data structures and set up for a new level.
X */
X
Xnewlevel ()
X{ int   i, j;
X
X  initstufflist ();			/* Delete the list of items */
X  droppedscare = 0;			/* Old stuff gone */
X  maxobj = 22;				/* Reset maximum # of objs */
X  newmonsterlevel ();			/* Do new monster stuff */
X  exploredlevel = 0;			/* New level */
X  aggravated = 0;			/* Old monsters gone */
X  beingstalked = 0;			/* Old monsters gone */
X  darkdir = NONE; darkturns = 0;	/* Not arching old monster */
X  stairrow = NONE; staircol = 0;	/* Get rid of old stairs */
X  missedstairs = 0;
X  newdoors = doorlist;			/* Clear door list */
X  goalr = goalc = NONE;			/* Old goal invalid */
X  trapr = trapc = NONE;			/* Old traps are gone */
X  foundarrowtrap = foundtrapdoor = 0;   /* Old traps are gone */
X  teleported = 0;			/* Not teleported yet */
X  attempt = 0;				/* Haven't search for doors yet */
X  usesynch = 0;				/* Force a new inventory */
X  compression = Level < 13;		/* Set move compression */
X  newarmor = newweapon = newring = 1;	/* Reevaluate our items */
X  foundnew ();				/* Reactivate all rules */
X
X  /*
X   * Clear the highlevel map
X   */
X
X  for (i = 0; i < 9; i++) levelmap[i] = 0;
X  for (i = 0; i < 9; i ++) for (j = 0; j < 9; j ++) zonemap[i][j] = (i == j);
X  zone = NONE;
X
X  /*
X   * Clear the lowlevel map
X   */
X
X  for (i = 1; i < 23; i++)
X    for (j = 0; j < 80; j++)    /* Forall screen positions */
X    { scrmap[i][j] = 0;
X      timessearched[i][j] = 0;
X      updatepos (screen[i][j], i, j);
X    }
X
X  atrow0 = atrow;
X  atcol0 = atcol;
X  set (ROOM);
X  setnewgoal ();
X  timestosearch = k_door / 5;
X}
X
X/* routine to find the rooms:
X * room[i] =     0 -- nothing in sector
X *            ROOM -- room found already
X *	     CANGO -- halls, but no room in sector
X */
X
Xstatic struct {int top,bot,left,right;} bounds[9]=
X
X       /* top bot left right */
X/*0*/	{{ 1,  6,   0,  25},
X/*1*/	 { 1,  6,  27,  51},
X/*2*/	 { 1,  6,  53,  79},
X/*3*/	 { 8, 14,   0,  25},
X/*4*/	 { 8, 14,  27,  51},
X/*5*/	 { 8, 14,  53,  79},
X/*6*/	 {16, 22,   0,  25},
X/*7*/	 {16, 22,  27,  51},
X/*8*/	 {16, 22,  53,  79}};
X
Xmarkmissingrooms ()
X{ register rm,i,j;
X  for (rm=0; rm<9; ++rm)
X  { room[rm]=0;
X    for (i=bounds[rm].top; i<=bounds[rm].bot; ++i)
X      for (j=bounds[rm].left; j<=bounds[rm].right; ++j)
X	if (onrc(ROOM,i,j)) { room[rm]=ROOM; goto nextroom; }
X	else if (onrc(BEEN,i,j)) { room[rm]=BEEN; goto nextroom; }
X    nextroom: ;
X  }
X}
X
X/*
X * whichroom: Return the zone number of a square (0..8) or -1, as follows:
X *
X *		room 0 | room 1 | room 2
X *              -------+--------+-------
X *		room 3 | room 4 | room 5
X *              -------+--------+-------
X *		room 6 | room 7 | room 8
X */
X
Xint whichroom (r,c)
Xregister int r,c;
X{ register int rm;
X
X  for (rm=0; rm<9; ++rm)
X    if (r >= bounds[rm].top  && r <= bounds[rm].bot &&
X        c >= bounds[rm].left && c <= bounds[rm].right)
X      return(rm);
X
X    return (-1);
X}
X
X/*
X * nametrap: look around for a trap and set its type.
X */
X
Xnametrap (ttype, standingonit)
Xint ttype, standingonit;
X{ register int i, r, c, tdir = NONE, monsteradj = 0;
X
X  if (standingonit)
X  { r=atrow; c=atcol; }
X
X  else if (blinded)		/* Cant see, dont bother */
X    return;
X
X  else
X  { /* Look all around and see what there is next to us */
X    for (i = 0; i < 8; i++)
X    { r = atdrow(i); c = atdcol(i);
X
X      if (seerc ('^', r, c))		/* Aha, a trap! */
X      { if (tdir != NONE) return;        /* Second trap, ambigous case */
X        else tdir = i;                    /* First trap,  record direction */
X      }
X      else if (isupper(screen[r][c]))   /* Trap could be under monster */
X        monsteradj++;
X    }
X
X    /* See one trap, set (r,c) to the trap location */
X    if (tdir != NONE)
X    { r = atdrow(tdir); c =  atdcol(tdir); }
X
X    /* See no traps, if there is a monster adjacent, he could be on it */
X    else if (monsteradj)
X      return;
X
X    /* Cant ever sit on a trap door or a teleport trap */
X    else if (ttype == TRAPDOR || ttype == TELTRAP)
X      return;
X
X    /* Cant see trap anywhere else, we must be sitting on it */
X    else
X    { r = atrow; c = atcol; }
X  }
X
X  /* Record last arror trap found (for cheating against 3.6) */
X  if (ttype == ARROW) { foundarrowtrap = 1; trapr = r; trapc = c; }
X  else if (ttype == TRAPDOR) { foundtrapdoor = 1; }
X
X  /* If a trapdor, reactivate rules */
X  if (ttype == TRAPDOR) foundnew ();
X
X  /* Set the trap type */
X  unsetrc (TELTRAP|TRAPDOR|BEARTRP|GASTRAP|ARROW|DARTRAP, r, c);
X  setrc (TRAP | ttype, r, c);
X}
X
X/*
X * findstairs: Look for STAIRS somewhere and set the stairs to that square.
X */
X
Xfindstairs (notr, notc)
Xint notr, notc;
X{ register int r, c;
X
X  stairrow = staircol = NONE;
X
X  for (r = 2; r < 22; r++)
X    for (c = 1; c < 79; c++)
X      if ((seerc ('%', r, c) || onrc (STAIRS, r, c)) &&
X	  r != notr && c != notc)
X      { setrc (STAIRS, r, c); stairrow = r; staircol = c; }
X}
X
X/*
X * downright: Find a square from which we cannot go down or right.
X */
X
Xdownright (drow, dcol)
Xint *drow, *dcol;
X{ register int i=atrow, j=atcol;
X
X  while (i < 23 && j < 79)
X  { if (onrc (CANGO, i, j+1)) j++;
X    else if (onrc (CANGO, i+1, j)) i++;
X    else { *drow = i; *dcol = j; return (1); }
X  }
X
X  return (0);
X}
X
X/*
X * Try to light up the situation
X */
X
Xlightroom ()
X{ int obj;
X
X  /* not in a room nor on door or room lit?? */
X  if (blinded || !darkroom ())
X    return (0);
X
X  if ((obj = havenamed (scroll, "light")) >=0 && reads (obj))
X    return (1);
X
X  if ((obj = havewand ("light")) >=0 && point (obj, 0))
X    return (1);
X
X  return (0);
X}
X
X/*
X * darkroom: Are we in a dark room?
X */
X
Xdarkroom ()
X{ register int dir, dir2, drow, dcol;
X
X  if (!on (DOOR | ROOM))
X    return (0);
X
X  for (dir=0; dir<8; dir++)
X    if (seerc ('.', (drow = atdrow(dir)), (dcol = atdcol(dir))))
X      for (dir2=0; dir2<8; dir2++)
X	if (seerc (' ', drow+deltr[dir2], dcol+deltc[dir2]))
X	  return (1);
X
X  return (0);
X}
X
X/*
X * currentrectangle: infer room extent based on clues from walls
X * NOTE: When a door appears on the screen, currentrectangle
X * should be re-initialised.				LGCH
X */
X
X# define fT 1
X# define fB 2
X# define fL 4
X# define fR 8
X
Xstatic int curt, curb, curl, curr;
X
Xcurrentrectangle ()
X{ int   flags = fT + fB + fL + fR, r, c, any = 1;
X
X  /*
X   * DEFINITION: curt is the current top of the room.  This is the
X   * topmost row which is known to be a room square.  The wall location
X   * is therefore curt-1.  curb: bottom.  curl: left. curr: right
X   * Since we discover new info when we step on a square on the
X   * extremity of the known room area, the following statement was
X   * modified by LGCH to use >=, <= instead of >, <
X   */
X
X  if ((atrow >= curb || atrow <= curt || atcol <= curl || atcol >= curr)
X      && on (ROOM))
X  { curt = curb = atrow;
X    curl = curr = atcol;
X    while (any)
X    { any = 0;
X
X      if (flags & fT)
X        for (r = curt - 1, c = curl - 1; c <= curr + 1; c++)
X          if (onrc (ROOM, r, c))      { curt--; any = 1; break; }
X          else if (seerc ('-', r, c)) { flags &= ~fT; break; }
X
X      if (flags & fB)
X        for (r = curb + 1, c = curl - 1; c <= curr + 1; c++)
X          if (onrc (ROOM, r, c))      { curb++; any = 1; break; }
X          else if (seerc ('-', r, c)) { flags &= ~fB; break; }
X
X      if (flags & fL)
X        for (r = curt, c = curl - 1; r <= curb; r++)
X          if (onrc (ROOM, r, c))      { curl--; any = 1; break; }
X          else if (seerc ('|', r, c)) { flags &= ~fL; break; }
X
X      if (flags & fR)
X        for (r = curt, c = curr + 1; r <= curb; r++)
X          if (onrc (ROOM, r, c))      { curr++; any = 1; break; }
X          else if (seerc ('|', r, c)) { flags &= ~fR; break; }
X
X    }
X    for (r = curt; r <= curb; r++)
X      for (c = curl; c <= curr; c++)
X      { setrc (ROOM + CANGO, r, c);
X        unsetrc	 (HALL, r, c);
X      }
X
X# define ckdoor(FLAG, NODOOR, STATIC, INC, S1, S2, I1, I2) \
X    if (0 == (flags & FLAG)) \
X    { any = 0; \
X      if (NODOOR) any = 1; \
X      else \
X	for (STATIC = S2, INC = I1; INC <= I2; INC++) \
X	  if (onrc (DOOR, r, c)) { any = 1; break; } \
X      if (any) \
X      { for (STATIC = S2, INC = I1; INC <= I2; INC++) \
X	  setrc (SEEN+WALL, r, c); \
X	for (STATIC = S1, INC = I1; INC <= I2; INC++) \
X	  setrc (BOUNDARY, r, c);   /* Room boundary   LGCH */ \
X      } \
X      else \
X      { for (STATIC = S2, INC = I1; INC <= I2; INC++) \
X	  setrc (BOUNDARY, r, c);  /* Unseen wall or door LGCH */ \
X      } \
X    }
X
X    if (curt <= 2) flags &= ~fT;    /* Wall must be on screen edge */
X    if (curb >= 21) flags &= ~fB;
X    if (curl <= 1) flags &= ~fL;
X    if (curr >= 78) flags &= ~fR;
X
X    ckdoor (fT, curt<6,  r, c, curt, curt-1, curl-1, curr+1)
X    ckdoor (fB, curb>17, r, c, curb, curb+1, curl-1, curr+1)
X    ckdoor (fL, curl<24, c, r, curl, curl-1, curt-1, curb+1)
X    ckdoor (fR, curr>56, c, r, curr, curr+1, curt-1, curb+1)
X
X    /* Fill in the corners of the room without seeing them */
X    /* Prevents looking at corners to find missing doors */
X    if ((flags & fT+fR) == 0)  setrc (SEEN + WALL, curt-1, curr+1);
X    if ((flags & fT+fL) == 0)  setrc (SEEN + WALL, curt-1, curl-1);
X    if ((flags & fB+fR) == 0)  setrc (SEEN + WALL, curb+1, curr+1);
X    if ((flags & fB+fL) == 0)  setrc (SEEN + WALL, curb+1, curl-1);
X  }
X}
X
Xclearcurrect()
X{ curl = curr = curt = curb = 0;
X}
X
X/*
X * updateat: We have moved, record results of our passge...
X *
X * Bug if monster is chasing us:  +######A@
X * Bug if teleported horiz or vert. Infers cango
X */
X
Xupdateat ()
X{ register int dr = atrow - atrow0, dc = atcol - atcol0;
X  register int i, r, c;
X  int   dist, newzone, sum;
X
X  /*
X   * Record passage from one zone to the next
X   */
X
X  newzone = whichroom (atrow, atcol);
X
X  if (newzone != NONE && zone != NONE && newzone != zone)
X  { new_arch = 1;
X    zonemap[zone][newzone] = zonemap[newzone][zone] = 1;
X    if ((levelmap[zone] & (EXPLORED | HASROOM)) == 0)
X    { for (i = 0, sum = 0; i < 9; i++) sum += zonemap[zone][i];
X      if (sum >= 3) markexplored (atrow0, atcol0);
X    }
X  }
X
X  if (newzone != NONE)
X    zone = newzone;
X
X
X  /*
X   * Check for teleport, else if we moved multiple squares, mark them as BEEN
X   */
X
X  if (direc (dr, dc) != movedir || dr && dc && abs(dr) != abs(dc))
X    teleport ();
X  else
X  { dist = (abs(dr)>abs(dc)) ? abs(dr) : abs(dc);
X    dr = (dr > 0) ? 1 : (dr < 0) ? -1 : 0;
X    dc = (dc > 0) ? 1 : (dc < 0) ? -1 : 0;
X    for (r = atrow0, c = atcol0;
X         dist >= 0 && (onrc(DOOR,r,c) || !onrc(WALL,r,c));
X         r += dr, c += dc, dist--)
X    { setrc (BEEN | SEEN | CANGO, r, c);
X      if (!onrc (TRAP, r, c)) setrc (SAFE, r, c);
X    }
X  }
X
X  /* Mark surrounding area according to what we see */
X
X  if (!on (HALL | DOOR | ROOM) && !blinded)
X  { int i, rr, cc;
X    int halls = 0, rooms = 0, rm;
X    char *terrain = "nothing";
X
X    for (i=0; i<8; i += 2)
X    { rr = atdrow(i); cc = atdcol(i);
X      if (onrc (HALL, rr, cc))
X        halls++;
X      else if (onrc (ROOM, rr, cc))
X        rooms++;
X    }
X
X    if (seerc ('|', atrow-1, atcol) && seerc ('|', atrow+1, atcol) ||
X        seerc ('-', atrow, atcol-1) && seerc ('-', atrow, atcol+1))
X    { set (DOOR | SAFE); unset (HALL | ROOM); terrain = "door";
X      if ((rm = whichroom (atrow, atcol)) != NONE) levelmap[rm] |= HASROOM;
X    }
X    else if (halls > 0)
X    { set (HALL | SAFE); unset (DOOR | ROOM); terrain = "hall"; }
X    else if (rooms > 0)
X    { set (ROOM); unset (HALL | DOOR); terrain = "room"; }
X    else
X      return;
X
X    dwait (D_INFORM, "Inferring %s at %d,%d.", terrain, atrow, atcol);
X  }
X  else if (on (DOOR | ROOM) && !isexplored (atrow, atcol) && !darkroom ())
X  { markexplored (atrow, atcol);
X  }
X}
X
X/*
X * updatepos: Something changed on the screen, update the screen map
X */
X
Xupdatepos (ch, row, col)
Xregister char  ch;
Xregister int row, col;
X{ char  oldch = screen[row][col], *monster, functionchar();
X  int   seenbefore = onrc (EVERCLR, row, col);
X  int   couldgo = onrc (CANGO, row, col);
X  int   unseen = !onrc (SEEN, row, col);
X  int   rm = whichroom (row, col);
X
X  if (mlistlen && ch != oldch) deletemonster (row, col);
X  if (unseen) { foundnew (); }
X
X  switch (ch)
X  { case '@':
X      setrc (SEEN | CANGO | BEEN | EVERCLR, row, col);
X      unsetrc (MONSTER | SLEEPER, row, col);
X      atrow = row;
X      atcol = col;
X      break;
X
X    case '#':
X      if (!onrc (HALL, row, col))
X      { foundnew ();
X        timestosearch = k_door / 5;
X      }
X      if (onrc (STUFF, row, col)) deletestuff (row, col);
X      setrc (SEEN | CANGO | SAFE | HALL | EVERCLR, row, col);
X      unsetrc (DOOR | ROOM | TRAP | ARROW | TRAPDOR | TELTRAP | GASTRAP |
X	       BEARTRP | DARTRAP | MONSTER | SCAREM | WALL | SLEEPER | STAIRS,
X	       row, col);
X      break;
X
X    case '+':
X      if (!onrc (DOOR, row, col))
X      { foundnew ();
X        timestosearch = k_door / 5;
X	teleported = 0; /* Dont give up on this level yet */
X	*newdoors++ = row;  *newdoors++ = col;
X      }
X      if (onrc (STUFF, row, col)) deletestuff (row, col);
X      setrc (SEEN | CANGO | SAFE | DOOR | WALL | EVERCLR, row, col);
X      unsetrc (ROOM | TRAP | ARROW | TRAPDOR | TELTRAP | GASTRAP | BEARTRP |
X               DARTRAP | MONSTER | SCAREM | SLEEPER, row, col);
X      clearcurrect();  /* LGCH: redo currentrectangle */
X      break;
X
X    /*
X     * Room floor:  there are many cases of what a room floor means,
X     * depending on the version of Rogue, whether the room is lit, whether
X     * we are in the room or not, and whether or not we were shooting
X     * missiles last turn.
X     */
X
X    case '.':
X      /* The square cant be any of these */
X      unsetrc (HALL | DOOR | MONSTER | SCAREM | WALL | TRAP | ARROW |
X               TRAPDOR | TELTRAP | GASTRAP | BEARTRP | DARTRAP, row, col);
X
X      if (!onrc (ROOM, row, col))		/* New room? */
X        unmarkexplored (row, col);
X      if (rm != NONE) levelmap[rm] |= HASROOM;	/* Room here */
X
X      /* If older Rogue, or our last position or a moving missile or */
X      /* in the same room, then a floor '.' means no stuff there     */
X      if ((version < RV52A ||
X           oldch == '@' ||
X           oldch == ')' && functionchar (lastcmd) == 't' ||
X           (on (ROOM) && whichroom (row, col) == whichroom (atrow, atcol))) &&
X          onrc (STUFF, row, col))
X      { deletestuff (row, col); }
X
X      /* If the stairs moved, look for them */
X      if (oldch == '@' && onrc (STAIRS, row, col)) findstairs (row, col);
X
X      /* Record whether this square has been clear of monsters */
X      if (!isupper (oldch)) setrc (EVERCLR, row, col);
X
X      /* Safe if we have been there, but not if the stuff was an arrow */
X      if (onrc (BEEN, row, col)) setrc (SAFE, row, col);
X      else if (oldch == ')' && functionchar (lastcmd) == 't')
X        unsetrc (SAFE, row, col);
X
X      setrc (SEEN | CANGO | ROOM, row, col);	/* Square must be these */
X      break;
X
X    case '-':
X    case '|':
X      setrc (SEEN | WALL | EVERCLR, row, col);
X      unsetrc (CANGO | HALL | DOOR | ROOM | SLEEPER, row, col);
X      break;
X
X    case ':':
X    case '?':
X    case '!':
X    case ')':
X    case ']':
X    case '/':
X    case '=':
X    case ',':           /* HAH! *//* HAH HAH! *//* HAH HAH HAH! */
X    case '*':
X      setrc (SEEN | CANGO | SAFE | EVERCLR, row, col);
X      unsetrc (DOOR | TRAP | ARROW | TRAPDOR | TELTRAP | GASTRAP | BEARTRP |
X               DARTRAP | MONSTER | WALL | SLEEPER, row, col);
X      if (ch != '?') unsetrc (SCAREM, row, col);
X      if (!onrc (BEEN, row, col) || !onrc(STAIRS, row, col) || !cosmic)
X      { addstuff (ch, row, col); unsetrc (STAIRS, row, col); }
X      setnewgoal ();
X      break;
X
X    case '%':
X      if (!onrc (STAIRS, row, col)) foundnew ();
X      if ((!cosmic || onrc (BEEN, row, col)) && onrc (STUFF, row, col))
X        deletestuff (row, col);
X      setrc (SEEN | CANGO | SAFE | ROOM | STAIRS | EVERCLR, row, col);
X      unsetrc (DOOR | HALL | TRAP | ARROW | TRAPDOR | TELTRAP | GASTRAP | 
X	       BEARTRP | DARTRAP | MONSTER | SCAREM | SLEEPER,
X               row, col);
X      stairrow = row;
X      staircol = col;
X      setnewgoal ();
X      break;
X
X    case '^':
X      setrc (SEEN | CANGO | ROOM | TRAP | EVERCLR, row, col);
X      if (onrc (STUFF, row, col)) deletestuff (row, col);
X      unsetrc (SAFE | HALL | DOOR | MONSTER | SCAREM | WALL | SLEEPER,
X               row, col);
X      break;
X
X    case ' ':
X      unsetrc (MONSTER | WALL, row, col);
X      break;
X
X    default:
X      if (isupper (ch))
X      { monster = monname (ch);
X        setrc (SEEN | CANGO | MONSTER, row, col);
X        unsetrc (SCAREM, row, col);
X	if (onrc (WALL, row, col))	/* Infer DOOR here */
X	{ if (!onrc (DOOR, row, col))
X          { foundnew ();
X            timestosearch = k_door / 5;
X            setrc (DOOR, row, col); /* MLM */
X            unsetrc (WALL, row, col); /* MLM */
X          }
X        }
X        if (!revvideo && ch != oldch) /* R5.2 MLM */
X        { blinded = 0;
X          if (seenbefore)
X            addmonster (ch, row, col, AWAKE);
X          else if (!onrc (HALL | DOOR, row, col) && !aggravated &&
X                   (streq (monster, "floating eye") ||
X                    streq (monster, "ice monster") ||
X                    streq (monster, "leprechaun") ||
X                    streq (monster, "nymph") ||
X                    (version < RV52A && (ch == 'T' || ch == 'P'))))
X          { addmonster (ch, row, col, ASLEEP);
X            setrc (SLEEPER, row, col);
X          }
X          else if (onrc (HALL | DOOR, row, col) || aggravated)
X          { addmonster (ch, row, col, AWAKE);
X	    setrc (EVERCLR, row, col);
X	  }
X          else
X            addmonster (ch, row, col, 0);
X        }
X      }
X      break;
X  }
X
X  /* If the stairs moved, look for the real stairs */
X  if ((!onrc (STAIRS, row, col) && (row==stairrow && col==staircol)) ||
X      (stairrow != NONE && !onrc (STAIRS, stairrow, staircol)))
X    findstairs (row, col);
X
X  if (!couldgo && onrc (CANGO, row, col))
X    setnewgoal ();
X}
X
X/*
X * teleport: We have just been teleported. Reset whatever is necessary to
X * avoid doing silly things.
X */
X
Xteleport ()
X{ register int r = atrow0, c = atcol0;
X
X  goalr = goalc = NONE; setnewgoal ();
X
X  hitstokill = 0; darkdir = NONE; darkturns = 0;
X
X  if (movedir >= 0 && movedir < 8 && !confused)
X  { teleported++;
X
X    while (r > 1 && r < 23 && c > 0 && c < 79)
X    { if (onrc (WALL | DOOR | HALL, r, c)) break;
X      if (onrc (TRAP, r, c))
X      { if (!onrc (ARROW|DARTRAP|GASTRAP|BEARTRP|TRAPDOR|TELTRAP, r, c))
X          saynow ("Assuming teleport trap at %d, %d", r, c);
X	break;
X      }
X      r += deltr[movedir]; c += deltc[movedir];
X    }
X  }
X}
X
X/*
X * mapinfer: Rewritten by Michael Mauldin.  August 19, 1983.
X * Infer bit settings after reading a scroll of magic mapping.
X * Because the mapping scroll gives extra information (in particular
X * we now know all the room squares so we can plan run-away paths
X * properly) it is best to process the entire map making extra
X * inferences.
X */
X
Xmapinfer()
X{ register r, c, inroom;
X
X  dwait (D_CONTROL, "Map read: inferring rooms.");
X  for (r=1; r<23; r++)
X  { inroom = 0;
X    for (c=0; c<80; c++)
X    { if (seerc ('|', r, c) || (seerc ('+', r, c) && !seerc('-', r, c-1)))
X      { inroom = !inroom; }
X      else if (inroom)
X      { setrc (ROOM | CANGO, r, c); }
X      else
X      { setrc (SEEN, r, c); }
X    }
X  }
X}
X
X/*
X * markexplored: If we are in a room, mark the location as explored.
X */
X
Xmarkexplored (row, col)
Xint row, col;
X{ register int rm = whichroom (row, col);
X
X  if (rm != NONE && !(levelmap[rm] & EXPLORED))
X  { levelmap[rm] |= EXPLORED;
X    if (!(levelmap[rm] & HASROOM))
X      saynow ("Assuming room %d is gone.", zone);
X  }
X}
X
X/*
X * unmarkexplored: If we are in a room, unmark the location as explored.
X */
X
Xunmarkexplored (row, col)
Xint row, col;
X{ register int rm = whichroom (row, col);
X
X  if (rm != NONE) levelmap[rm] &= ~EXPLORED;
X}
X
X/*
X * isexplored: If we are in a room, return true if it has been explored.
X */
X
Xisexplored (row, col)
Xint row, col;
X{ register int rm = whichroom (row, col);
X
X  return (rm != NONE ? levelmap[rm] & EXPLORED : 0);
X}
X
X/*
X * haveexplored: Have we explored n rooms?
X */
X
Xhaveexplored (n)
Xint n;
X{ register int rm, count = 0;
X
X  for (rm = 0; rm < 9; rm++)
X    if (levelmap[rm] & EXPLORED)
X      count++;
X
X  return (count >= n);
X}
X
X/*
X * printexplored: List the explored rooms
X */
X
Xprintexplored ()
X{ register int rm;
X
X  at (0,0);
X  printw ("Rooms explored: ");
X  for (rm = 0; rm < 9; rm++)
X  { if (levelmap[rm] & EXPLORED)
X    { printw (" %d", rm);
X    }
X  }
X  clrtoeol ();
X  at (row, col);
X  refresh ();
X}
X
X/*
X * inferhall: When a door appears on the screen where no door was before,
X * check whether we can infer a hall between it an a neighbouring room.
X * The technique is simple: We first determine whether the hall is already
X * known, and if it is not, we scan away from the room looking for another
X * wall. If we find one, then we look for a door and if we find THAT then
X * we infer a hall between the matching doors. Of course, this means that
X * we must set CANGO bits so that exploration can use the guessed hall. So
X * we set CANGO for the complete rectangle joining the two doors and then
X * rely on the CANGO bits being unset again where we actually see blank
X * space.
X */
X
Xinferhall (r, c)
Xregister int r, c;
X{ register int i, j, k;
X
X  int inc, rm, end1, end2, end, dropout = 0, dir= NONE;
X  for (k = 0; k < 8; k += 2)
X  { if (onrc (HALL, r + deltr[k], c + deltc[k]))      /* Hall has been seen */
X      return;
X    else if (onrc (ROOM, r + deltr[k], c + deltc[k])) /* Room is over here */
X      dir = k;
X  }
X
X  dwait (D_SEARCH, "Room direction %d", dir);
X
X  if (dir < 0) return;
X
X  if (dir % 4 == 0) 			     /* If horizontal dir */
X  { inc = -deltc[dir]; rm = whichroom (r, c);
X    end1 = bounds[rm].top; end2 = bounds[rm].bot;
X    if (inc < 0) end = bounds[rm-1].left;
X    else         end = bounds[rm+1].right;
X    end = end * inc;
X
X    for (j = c+inc; j*inc < end; j += inc)
X    { for (i = end1; i <= end2; i++)
X      { if (debug (D_SCREEN | D_SEARCH | D_INFORM)) mvaddch (i, j, 'h');
X	if (onrc (DOOR | WALL | ROOM | HALL, i, j))
X	{ /* Modified only to find doors on vertical walls */
X          if (onrc (DOOR,i,j) && (onrc (WALL,i-1,j) || onrc (WALL,i+1,j)))
X	    connectdoors (r, c+inc, i, j-inc);
X	  dropout = 1;
X	}
X      }
X      if (dropout)
X	break;
X    }
X  }
X
X  else
X  { inc = -deltr[dir]; rm = whichroom (r, c);
X    end1 = bounds[rm].left; end2 = bounds[rm].right;
X    if (inc < 0) end = bounds[rm-3].top;
X    else         end = bounds[rm+3].bot;
X    end = end * inc;
X
X    for (i = r+inc; i*inc < end; i += inc)
X    { for (j = end1; j <= end2; j++)
X      { if (debug (D_SCREEN | D_SEARCH | D_INFORM)) mvaddch (i, j, 'v');
X	if (onrc (DOOR | WALL | ROOM | HALL, i, j))
X	{ /* Modified only to find doors on horizontal walls */
X          if (onrc (DOOR,i,j) && (onrc (WALL,i,j-1) || onrc (WALL,i,j+1)))
X	    connectdoors (r+inc, c, i-inc, j);
X	  dropout = 1;
X	}
X      }
X      if (dropout) break;
X    }
X  }
X
X  /* NOTE: If we set SEEN here on the three squares beyond the door, then
X   * we can prevent Rogomatic's persistence in searching out every
X   * corridor that leads to a secret door at the other end. Or, we could set
X   * a bit on the door to make it a preferred exploration target so that
X   * Rogomatic would ALWAYS search out every corridor leading to a secret
X   * door at the other end. The latter alternative is probably better
X   * unless we implement the inferred corridors so that we can infer a
X   * corridor which has a secret door and therefore we can traverse it
X   * more easily one way than the other. NOTE that we must have a flag to
X   * indicate why the search for a corridor failed: if it found a wall
X   * then we know there is a secret door; if it stopped for another reason
X   * then we don't know what we may find - maybe a room, maybe a path to a
X   * corridor.
X   */
X
X  dwait (D_SEARCH | D_CONTROL, "Hall search done.");
X}
X
Xconnectdoors (r1, c1, r2, c2)
Xregister int r1, c1, r2, c2;
X{ register int r, c;
X  int endr = max (r1, r2), endc = max (c1, c2);
X
X  dwait (D_INFORM, "Inferring hall (%d,%d) to (%d,%d)", r1, c1, r2, c2);
X
X  for (r = min (r1, r2); r <= endr; r++)
X    for (c = min (c1, c2); c <= endc; c++)
X      setrc (CANGO|SAFE, r, c);              /* Can go (somewhere) here */
X
X  for (r = min (r1, r2) - 1; r <= endr + 1; r++)
X    for (c = min (c1, c2) - 1; c <= endc + 1; c++)
X      setrc (SEEN, r, c); 		     /* Nothing to see here */
X}
X
X/*
X * canbedoor: Called from setpsd() to check that a dead end could in fact
X * lead to a room.  Only checks that there is enough empty space next to a
X * square.  Does NOT check that this square is in fact a dead end.
X *
X * September 25, 1983	Michael L. Mauldin
X */
X
Xcanbedoor (deadr, deadc)
Xint deadr, deadc;
X{ register int r, c, dr, dc, k, count;
X
X  /* Check all orthogonal directions around the square */
X  for (k=0; k < 8; k+=2)
X  { dr = deltr[k]; dc = deltc[k];
X    r = deadr+dr; c = deadc+dc;
X
X    /* If there are four blank squares, then it could be a door */
X    for (count=0; count < 4 && seerc (' ',r,c); count++)
X    { r+=dr; c+=dc; }
X
X    if (count >= 4) return (1);
X  }
X
X  /* Not enough room in any direction */
X  return (0);
X}
X
X/*
X * mazedoor: Return true if this could be a door to a maze
X */
X
Xmazedoor (row, col)
Xint row, col;
X{ register int r=row, c=col, dr, dc, k=0, dir = NONE;
X
X  if (onrc (HALL,r,c+1)) {dir=0; k++; dr=0;   dc=1;}
X  if (onrc (HALL,r-1,c)) {dir=2; k++; dr= -1; dc=0;}
X  if (onrc (HALL,r+1,c)) {dir=6; k++; dr=1;   dc=0;}
X  if (onrc (HALL,r,c-1)) {dir=4; k++; dr=0,   dc= -1;}
X  if (k != 1) return (0);
X
X  /* Fail if no adjacent hall, or not double corridor */
X  if ((onrc (HALL, r+dr+dr, c+dc+dc) == 0))
X    return (0);
X
X  /* Must have two sets of double corridor */
X  if (! (((onrc (HALL, r+dr+deltr[(dir+1)&7], c+dc+deltc[(dir+1)&7])) &&
X          (onrc (HALL, r+dr+deltr[(dir+2)&7], c+dc+deltc[(dir+2)&7]))) ||
X         ((onrc (HALL, r+dr+deltr[(dir-1)&7], c+dc+deltc[(dir-1)&7])) &&
X          (onrc (HALL, r+dr+deltr[(dir-2)&7], c+dc+deltc[(dir-2)&7])))))
X    return (0);
X
X  /* If there are four blank squares, then it could be a door */
X  for (r = row-dr, c = col-dc, k=0;  k < 4 && seerc (' ',r,c);  k++)
X  { r-=dr; c-=dc; }
X
X  if (k >= 4) return (1);
X
X  /* Not enough room for room */
X  return (0);
X}
X
X/*
X * nextto:  Is there a square type orthogonally adjacent?
X */
X
Xnextto (type,r,c)
Xregister int type, r, c;
X{ register int result;
X  if (result = onrc (type, r-1, c)) return (result);
X  if (result = onrc (type, r+1, c)) return (result);
X  if (result = onrc (type, r, c-1)) return (result);
X  if (result = onrc (type, r, c+1)) return (result);
X  return (0);
X}
X
X/*
X * nexttowall:  Is there a wall adjacent wall?
X *			|
X *  e.g.	########|   <----   there should be a door here.
X *			|
X * Fuzzy:	Replaces knowisdoor (), October 17, 1983.
X */
X
Xnexttowall (r,c)
Xregister int r, c;
X{ return (onrc (DOOR | WALL, r-1, c) == WALL ||
X          onrc (DOOR | WALL, r+1, c) == WALL ||
X          onrc (DOOR | WALL, r, c-1) == WALL ||
X          onrc (DOOR | WALL, r, c+1) == WALL);
X}
X
X/*
X * dumpmazedoor: Show all squares for which mazedoor(r,c) is true.
X */
X
Xdumpmazedoor ()
X{ register int r, c;
X
X  for (r=2; r<22; r++)
X  { for (c=1; c<79; c++)
X    { if (((scrmap[r][c] & (BEEN|DOOR|HALL|ROOM|WALL|STAIRS)) == 0) &&
X          mazedoor (r, c))
X        mvaddch (r, c, 'M');
X    }
X  }
X
X  at (row, col);
X}
X
X/* 
X * foundnew: Reactivate rules which new new squares to work
X */
X
Xfoundnew ()
X{ new_mark = new_findroom = new_search = new_stairs = 1;
X  reusepsd = teleported = 0;
X  cancelmove (SECRETDOOR);
X  unrest ();
X}
/
echo 'x - setup.c'
sed 's/^X//' > setup.c << '/'
X/*
X * setup.c: Rog-O-Matic XIV (CMU) Wed Jan 30 17:38:07 1985 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * This is the program which forks and execs the Rogue & the Player
X */
X
X# include <stdio.h>
X# include <signal.h>
X# include "install.h"
X
X# define READ    0
X# define WRITE   1
X
X/* Define the Rog-O-Matic pseudo-terminal (Concept Based) */
X
X# define ROGUETERM "rg|rterm:am:bs:ce=^[^S:cl=^L:cm=^[a%+ %+ :co#80:li#24:so=^[D:se=^[d:pt:ta=^I:up=^[;:db:xn:"
X
Xint   frogue, trogue;
X
Xmain (argc, argv)
Xint   argc;
Xchar *argv[];
X
X{ int   ptc[2], ctp[2];
X  int   child, score = 0, oldgame = 0;
X  int   cheat = 0, noterm = 1, echo = 0, nohalf = 0, replay = 0;
X  int   emacs = 0, rf = 0, terse = 0, user = 0, quitat = 2147483647;
X  char  *rfile = "", *rfilearg = "", options[32];
X  char  ropts[128], roguename[128];
X
X  while (--argc > 0 && (*++argv)[0] == '-')
X  { while (*++(*argv))
X    { switch (**argv)
X      { case 'c': cheat++;        break; /* Will use trap arrows! */
X        case 'e': echo++;         break; /* Echo file to roguelog */
X        case 'f': rf++;           break; /* Next arg is the rogue file */
X        case 'h': nohalf++;       break; /* No halftime show */
X        case 'p': replay++;       break; /* Play back roguelog */
X        case 'r': oldgame++;      break; /* Use saved game */
X        case 's': score++;        break; /* Give scores only */
X        case 't': terse++;        break; /* Give status lines only */
X        case 'u': user++;         break; /* Start up in user mode */
X        case 'w': noterm = 0;     break; /* Watched mode */
X        case 'E': emacs++;        break; /* Emacs mode */
X        default:  printf 
X                  ("Usage: rogomatic [-cefhprstuwE] or rogomatic [file]\n");
X                  exit (1);
X      }
X    }
X
X    if (rf) 
X    { if (--argc) rfilearg = *++argv;
X      rf = 0;
X    }
X  }
X
X  if (argc > 1)
X  { printf ("Usage: rogomatic [-cefhprstuwE] or rogomatic <file>\n");
X    exit (1);
X  }
X
X  /* Find which rogue to use */
X  if (*rfilearg)
X  { if (access (rfilearg, 1) == 0)	rfile = rfilearg;
X    else				{ perror (rfilearg); exit (1); }
X  }
X  else if (access ("rogue", 1) == 0)	rfile = "rogue";
X# ifdef NEWROGUE
X  else if (access (NEWROGUE, 1) == 0)	rfile = NEWROGUE;
X# endif
X# ifdef ROGUE
X  else if (access (ROGUE, 1) == 0)	rfile = ROGUE;
X# endif
X  else
X  { perror ("rogue");
X    exit (1);
X  }
X
X  if (!replay && !score) quitat = findscore (rfile, "Rog-O-Matic");
X
X  sprintf (options, "%d,%d,%d,%d,%d,%d,%d,%d",
X           cheat, noterm, echo, nohalf, emacs, terse, user,quitat);
X  sprintf (roguename, "Rog-O-Matic %s for %s", RGMVER, getname ());
X  sprintf (ropts, "name=%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
X           roguename, "fruit=apricot", "terse", "noflush", "noask",
X           "jump", "step", "nopassgo", "inven=slow", "seefloor");
X
X  if (score)  { dumpscore (argc==1 ? argv[0] : DEFVER); exit (0); }
X  if (replay) { replaylog (argc==1 ? argv[0] : ROGUELOG, options); exit (0); }
X
X  if ((pipe (ptc) < 0) || (pipe (ctp) < 0))
X  { fprintf (stderr, "Cannot get pipes!\n");
X    exit (1);
X  }
X
X  trogue = ptc[WRITE];
X  frogue = ctp[READ];
X
X  if ((child = fork ()) == 0)
X  { close (0);
X    dup (ptc[READ]);
X    close (1);
X    dup (ctp[WRITE]);
X
X    putenv ("TERMCAP", ROGUETERM);
X    putenv ("ROGUEOPTS", ropts);
X
X    if (oldgame)  execl (rfile, rfile, "-r", 0);
X    if (argc)     execl (rfile, rfile, argv[0], 0);
X    execl (rfile, rfile, 0);
X    _exit (1);
X  }
X
X  else
X  { /* Encode the open files into a two character string */
X
X    char *ft = "aa", rp[32]; ft[0] += frogue; ft[1] += trogue;
X
X    /* Pass the process ID of the Rogue process as an ASCII string */
X    sprintf (rp, "%d", child);
X
X    if (!author ()) nice (4);
X
X    execl ("player", "player", ft, rp, options, roguename, 0);
X# ifdef PLAYER
X    execl (PLAYER, "player", ft, rp, options, roguename, 0);
X# endif
X    printf ("Rogomatic not available, 'player' binary missing.\n");
X    kill (child, SIGKILL);
X  }
X}
X
X/* 
X * replaylog: Given a log file name and an options string, exec the player
X * process to replay the game.  No Rogue process is needed (since we are
X * replaying an old game), so the frogue and trogue file descrptiors are
X * given the fake value 'Z'.
X */
X
Xreplaylog (fname, options)
Xchar *fname, *options;
X{ execl ("player", "player", "ZZ", "0", options, fname, 0);
X# ifdef PLAYER
X  execl (PLAYER, "player", "ZZ", "0", options, fname, 0);
X# endif
X  printf ("Replay not available, 'player' binary missing.\n");
X  exit (1);
X}
X
X/*
X * author:
X *	See if a user is an author of the program
X */
X
Xauthor()
X{
X  switch (getuid())
X  { case 1337:	/* Fuzzy */
X    case 1313:	/* Guy */
X    case 1241:	/* Andrew */
X    case 345:	/* Leonard */
X    case 342:	/* Gordon */
X		return 1;
X    default:	return 0;
X  }
X}
/
echo 'Part 06 of Rog-O-Matic XIV complete.'
exit



More information about the Comp.sources.unix mailing list