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

Michael Mauldin mlm at cmu-cs-cad.ARPA
Sat Feb 2 02:32:08 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 08 of 10:'
echo 'x - arms.c'
sed 's/^X//' > arms.c << '/'
X/*
X * arms.c: Rog-O-Matic XIV (CMU) Thu Jan 31 15:46:02 1985 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X * 
X * This file contains all utility functions which exist for armor, 
X * weapons and rings.
X */
X
X# include <curses.h>
X# include "types.h"
X# include "globals.h"
X
X/*
X * havearmor: Return Kth best armor. K should be in the range 1 to invcount.
X *            If K is greater than the number of pieces of armor we have,
X *            then NONE is returned.  Will not return cursed armor or
X *	      armor worse than wearing nothing.
X */
X
X# define swap(x,y) {t=(x); (x)=(y); (y)=t;}
X
Xint havearmor (k, print, rustproof)
X{ register int i, j, w, t, n=0;
X  int armind[MAXINV], armval[MAXINV];
X
X  /* Sort armor by armor class (best first) */
X  for (i=0; i<invcount; ++i)
X  { if (inven[i].count && inven[i].type == armor &&
X        ! (rustproof && willrust (i)))
X    { n++;
X      w = armorclass (i);
X      for (j = n-1; j > 0 && w <= armval[j-1]; j--)
X      { swap (armind[j], armind[j-1]);
X        swap (armval[j], armval[j-1]);
X      }
X      armind[j] = i;
X      armval[j] = w;
X    }
X  }
X
X  /* Put protected sets of armor with equal ACs first.  DR UTexas 19 Jan 84 */
X  for (j = n-1; j > 0; j--)
X  { if (armval[j] == armval[j-1])
X    { i = armind[j];
X      w = armind[j-1];
X      if (!itemis (w, PROTECTED) && itemis (i, PROTECTED))
X        swap (armind[j], armind[j-1]);
X    }
X  }
X
X  if (print)
X  { mvaddstr (1, 0, "Current Armor Rankings");
X    for (i = 0; i<n; i++)
X      mvprintw (i+3, 8, "%2d: %3d %s", i+1, armval[i], itemstr (armind[i]));
X  }
X
X  /* Any uncursed, useful armor at or beyond position k? */
X  for (i=k; i <= n; i++)
X    if (!itemis ((j = armind[i-1]), CURSED) && armval[j] < 10) return (j);
X  
X  /* Return the kth best, even though it is cursed or useless */
X  return ((k <= n) ? armind[k-1] : NONE);
X}
X
X/*
X * armorclass: Given the index of a piece of armor, return the armor
X * class. Assume modifiers of +2 for unknown armor when we have scrolls
X * of remove curse and -2 for when we don't have a remove curse.
X */
X
Xarmorclass (i)
Xint i;
X{ int class;
X
X  if (inven[i].type != armor)
X    return (1000);
X    
X  if (stlmatch (inven[i].str, "leather"))        class = 8;
X  else if (stlmatch (inven[i].str, "ring"))      class = 7;
X  else if (stlmatch (inven[i].str, "studded"))   class = 7;
X  else if (stlmatch (inven[i].str, "scale"))     class = 6;
X  else if (stlmatch (inven[i].str, "chain"))     class = 5;
X  else if (stlmatch (inven[i].str, "splint"))    class = 4;
X  else if (stlmatch (inven[i].str, "banded"))    class = 4;
X  else if (stlmatch (inven[i].str, "plate"))     class = 3;
X  else                                           class = 1000;
X
X  /* Know the modifier exactly */
X  if (inven[i].phit != UNKNOWN)
X    class -= inven[i].phit;
X
X  /* Can remove curse, so assume it is +2 armor */
X  else if (havenamed (scroll, "remove curse") != NONE)
X    class -= 2;
X
X  /* Can't remove curse, assume it is -2 armor */
X  else
X    class += 2;
X
X  return (class);
X}
X
X/*
X * haveweapon: Return Kth best weapon. K should be in the range 1 to invcount.
X *             If K is greater than the number of weapons we have,
X *             then NONE is returned.
X */
X
Xint haveweapon (k, print)
X{ register int i, j, w, t, n=0;
X  int weapind[MAXINV], weapval[MAXINV];
X  for (i=0; i<invcount; ++i)
X    if (inven[i].count && (w = weaponclass (i)) > 0)
X    { n++;
X      for (j = n-1; j > 0 && w >= weapval[j-1]; j--)
X      { swap (weapind[j], weapind[j-1]);
X        swap (weapval[j], weapval[j-1]);
X      }
X      weapind[j] = i;
X      weapval[j] = w;
X    }
X
X    /*
X     * Put enchanted weapons above unenchanted ones if the weapon
X     * ratings are equal.  DR UTexas 25 Jan 84 
X     */
X
X    for (j = n-1; j > 0; j--)
X    { if (weapval[j] == weapval[j-1])
X      { i = weapind[j];
X        w = weapind[j-1];
X        if (!itemis (w, ENCHANTED) && itemis (i, ENCHANTED) &&
X            !itemis (w, KNOWN) && !itemis (i, KNOWN))
X        { swap (weapind[j], weapind[j-1]); }
X      }
X    }
X
X  if (print)
X  { mvaddstr (1, 0, "Current Weapon Rankings");
X    for (i = 0; i<n; i++)
X      mvprintw (i+3, 8, "%2d: %5d %s", i+1, weapval[i], itemstr (weapind[i]));
X  }
X
X  return ((k <= n) ? weapind[k-1] : NONE);
X}
X
X/*
X * weaponclass: Given the index of a weapon, return the weapon class. 
X *              This is the average damage done + 3/2 the plus to
X *              hit, multiplied by 10. Magic arrows are given very
X *              high numbers.
X */
X
Xweaponclass (i)
Xint i;
X{ int class, hitplus = 0, damplus = 0;
X
X  /* Swords and maces are always valid weapons */   
X  if (inven[i].type == hitter)
X    ;
X  /* Under special circumstances, arrows are valid weapons (Hee hee) */
X  else if (cheat && inven[i].type == missile &&
X           stlmatch (inven[i].str, "arrow"))
X    ;
X  /* Not a valid weapon */
X  else
X    return (0);
X
X  /* 
X   * Set the basic expected damage done by the weapon. 
X   */
X    
X  if (stlmatch (inven[i].str, "mace"))
X    class =  50;
X  else if (stlmatch (inven[i].str, "two handed sword"))
X    class = (version < RV52A) ? 105 : 100;
X  else if (stlmatch (inven[i].str, "long sword"))
X    class =  (version < RV52A) ? 55 : 75;
X  else if (stlmatch (inven[i].str, "arrow"))
X    class =  10;
X  else
X    class =   0;
X
X  /* Know the modifier exactly */
X  if (inven[i].phit != UNKNOWN)
X  { hitplus += inven[i].phit;
X
X    if (inven[i].pdam != UNKNOWN)
X      damplus = inven[i].pdam; 
X  }
X
X  /* 
X   * Strategy for "Magic Arrows". These are single arrows when
X   * we are cheating. Since arrows normally come in clumps, and
X   * since we have never (in cheat mode) thrown any, then a
X   * single arrow must have come from a trap, and until it fails
X   * to kill something, we assume it is a valuable arrow.
X   */
X
X  else if (cheat && version <= RV36B && usingarrow && goodarrow > 20 &&
X           i == currentweapon)
X    return (1800);
X
X  else if (cheat && version <= RV36B && stlmatch (inven[i].str, "arrow") &&
X           inven[i].count == 1 && !itemis (i, WORTHLESS) && 
X           (!badarrow || i != currentweapon))
X  { hitplus = 50;  damplus = 50; }
X
X  hitplus = (hitplus < 100) ? hitplus : 100;
X  damplus = (damplus < 200) ? damplus : 200;
X
X  return (class + 12*hitplus + 10*damplus);
X}
X
X/*
X * havering: Return Kth best ring. K should be in the range 1 to invcount.
X *           If K is greater than the number of rings we have,
X *           then NONE is returned.
X */
X
Xint havering (k, print)
X{ register int i, j, r, t, n=0;
X  int ringind[MAXINV], ringval[MAXINV];
X  for (i=0; i<invcount; ++i)
X    if (inven[i].count && (r = ringclass (i)) > 0)
X    { n++;
X      for (j = n-1; j > 0 && r >= ringval[j-1]; j--)
X      { swap (ringind[j], ringind[j-1]);
X        swap (ringval[j], ringval[j-1]);
X      }
X      ringind[j] = i;
X      ringval[j] = r;
X    }
X
X  if (print)
X  { mvaddstr (1, 0, "Current Ring Rankings");
X    for (i = 0; i<n; i++)
X      mvprintw (i+3, 8, "%2d: %5d  %s", i+1, ringval[i], itemstr (ringind[i]));
X  }
X
X  /* 
X   * Since rings are class [1-1000] if we don't want to wear them,
X   * return the ring index only if its value is greater than 1000.
X   */
X
X  return ((k <= n && ringval[k-1] > 1000) ? ringind[k-1] : NONE);
X}
X
X/*
X * ringclass: Given the index of a ring, return the ring class. 
X *            This is a subjective measure of how much good it
X *            would do us to wear this ring. Values of [1-1000] indicates
X *            that we should not wear this ring at all. A value of 0
X *            indicates a worthless ring. This routine uses the amount
X *            of food available to decide how valuable rings are.
X *            Worth evaluates the value of a ring by subtracting 1000 if
X *            the ringclass is over 1000 to decide how valuable the ring
X *            is, so we add 1000 to indicate that the ring should be worn
X *            and try to assign values from 0 to 999 to determine the
X *            value of the ring.
X */
X
Xringclass (i)
Xint i;
X{ int class = 0, magicplus = 0;
X
X  if (inven[i].type != ring)
X    return (0);
X
X  /* Get the magic plus */
X  if (inven[i].phit != UNKNOWN)
X  { magicplus = inven[i].phit;
X  }
X
X  /* A ring of protection */
X  if (stlmatch (inven[i].str, "protection"))
X  { if (magicplus > 0) class = (havefood (1) ? 1000 : 0) + 450; }
X
X  /* A ring of add strength */
X  else if (stlmatch (inven[i].str, "add strength"))
X  { if (itemis (i, INUSE) && magicplus > 0)
X    { if (hitbonus (Str) == hitbonus (Str - magicplus * 100) &&
X          damagebonus (Str) == damagebonus (Str - magicplus * 100))
X        class = 400;
X      else
X        class = (havefood (1) ? 1000 : 0) + 400;
X    }
X    else if (magicplus > 0)
X    { if (hitbonus (Str) == hitbonus (Str + magicplus * 100) &&
X          damagebonus (Str) == damagebonus (Str + magicplus * 100))
X        class = 400;
X      else
X        class = (havefood (1) ? 1000 : 0) + 400;
X    }
X  }
X
X  /* A ring of sustain strength */
X  else if (stlmatch (inven[i].str, "sustain strength"))
X  { 
X    /* A second ring of sustain strength is useless */
X    if (!itemis (i, INUSE) && wearing ("sustain strength") != NONE)
X      class = 0;
X
X    else
X      class = (havefood (3) ? 1000 : 0) + 
X              (Level > 12 ? 150 : 
X               Str > 2000 ? 700 :
X               Str > 1600 ? Str - 1200 :
X                            100);
X  }
X
X  /* A ring of searching */
X  else if (stlmatch (inven[i].str, "searching"))
X  { class = (havefood (0) ? 1000 : 0) + 250; }
X
X  /* A ring of see invisible */
X  else if (stlmatch (inven[i].str, "see invisible"))
X  { 
X    /* A second ring of see invisible is useless */
X    if (!itemis (i, INUSE) && wearing ("see invisible") != NONE)
X      class = 0;
X
X    /* 
X     * If we are beingstalked and we are wearing this ring, then
X     * we should take it off and put it on to set the Rogue CANSEE
X     * bit, which can be unset by a second ring of see invisible or
X     * by a see invisible potion wearing off.				MLM
X     */
X
X    else if (itemis (i, INUSE) && beingstalked)
X      class = 800;
X
X    /*
X     * When we put the ring on, keep its importance high for 20
X     * turns, just in case the beast comes back to haunt us.		MLM
X     */
X
X    else
X      class = (beingstalked || turns - putonseeinv < 20) ? 1999 :
X              ((havefood (0) && Level > 15 && Level < 26) ? 1000 : 0) + 300;  }
X
X  /* A ring of adornment */
X  else if (stlmatch (inven[i].str, "adornment"))
X  { class = 0; }
X
X  /* A ring of aggravate monster */
X  else if (stlmatch (inven[i].str, "aggravate monster"))
X  { class = 0; }
X
X  /* A ring of dexterity */
X  else if (stlmatch (inven[i].str, "dexterity"))
X  { if (magicplus > 0) class = (havefood (0) ? 1000 : 0) + 475; }
X
X  /* A ring of increase damage */
X  else if (stlmatch (inven[i].str, "increase damage"))
X  { if (magicplus > 0) class = (havefood (0) ? 1000 : 0) + 500; }
X
X  /* A ring of regeneration */
X  else if (stlmatch (inven[i].str, "regeneration"))
X  {
X    /* Analysis indicates that rings of regenerate DO NOT hold back   */
X    /* the character after any level. They each add one hit point per */
X    /* turn of rest regardless of your level!			MLM   */
X
X    class = 50*(Hpmax-Hp-Explev) + 500; }
X
X  /* A ring of slow digestion */
X  else if (stlmatch (inven[i].str, "slow digestion"))
X  { 
X    /* A second ring of slow digestion is not too useful */
X    if (havefood (0) && !itemis (i, INUSE) &&
X	wearing ("slow digestion") != NONE)
X      class = 1001;
X
X    else
X    { class =	havefood (3) ?	1100 :
X		havefood (2) ?	1300 :
X		havefood (1) ?	1500 :
X		havefood (0) ?	1900 :
X				1999 ;
X    }
X  }
X
X  /* A ring of teleportation */
X  else if (stlmatch (inven[i].str, "telportation") || 
X           stlmatch (inven[i].str, "teleportation"))
X  { class = 0; }
X
X  /* A ring of stealth */
X  else if (stlmatch (inven[i].str, "stealth"))
X  {
X    /* A second ring of stealth is useless */
X    if (!itemis (i, INUSE) && wearing ("stealth") != NONE)
X      class = 0;
X
X    else
X    { class = (havefood (1) ? 1000 : 0) + 
X             (Level > 17 ? 850 : Level > 12 ? 700 : 300);
X    }
X  }
X
X  /* A ring of maintain armor */
X  else if (stlmatch (inven[i].str, "maintain armor"))
X  { int bestarm, nextarm, armdiff;
X
X    /* No rust monsters yet or cursed armor */
X    if (Level < 9 || cursedarmor) return (900);
X    
X    /* Past the rust monsters */
X    else if (Level > 18) return (300);
X
X    /* A second ring of maintain armor is useless */
X    else if (!itemis (i, INUSE) && wearing ("maintain armor") != NONE)
X      class = 0;
X
X    else
X    { bestarm = havearmor (1, NOPRINT, ANY);
X      nextarm = havearmor (1, NOPRINT, RUSTPROOF);
X
X      if (bestarm < 0)                       /* No armor to protect */
X        return (700);
X
X      else if (!willrust (bestarm))	     /* Armor wont rust anyway */
X        return (0);
X
X      else if (nextarm < 0)	             /* Naked is AC 10 */
X        armdiff = 10 - armorclass (bestarm);
X
X      else			             /* Get difference in classes */
X        armdiff = armorclass (nextarm) -
X		  armorclass (bestarm);
X
X      class = (havefood (1) ? 1000 : 0) +
X              200 * armdiff;
X    }
X  }
X
X  /* Not a known ring, forget it */
X  else
X    return (0);
X
X  /* A magical plus is worth 100 */
X  return (class + 100*magicplus);
X}
X
X/*
X * havebow: Return Kth best thrower. K should be in the range 1 to invcount.
X *          If K is greater than the number of weapons we have,
X *          then NONE is returned.
X */
X
Xint havebow (k, print)
X{ register int i, j, w, t, n=0;
X  int bowind[MAXINV], bowval[MAXINV];
X  for (i=0; i<invcount; ++i)
X    if (inven[i].count && (w = bowclass (i)) > 0)
X    { n++;
X      for (j = n-1; j > 0 && w >= bowval[j-1]; j--)
X      { swap (bowind[j], bowind[j-1]);
X        swap (bowval[j], bowval[j-1]);
X      }
X      bowind[j] = i;
X      bowval[j] = w;
X    }
X
X  if (print)
X  { mvaddstr (1, 0, "Current Bow Rankings");
X    for (i = 0; i<n; i++)
X      mvprintw (i+3, 8, "%2d: %5d %s", i+1, bowval[i], itemstr (bowind[i]));
X  }
X
X  return ((k <= n) ? bowind[k-1] : NONE);
X}
X
X/*
X * bowclass: Given the index of a bow, return the bow class. 
X *           This is the average damage done + 6/5 the plus to
X *           hit, multiplied by 10.
X */
X
Xbowclass (i)
Xint i;
X{ int class, hitplus = 0, damplus = 0;
X
X  if (inven[i].type == thrower &&
X      stlmatch (inven[i].str, "short bow") &&
X      havemult (missile, "arrow", 5) != NONE)
X    class =  35;
X  else
X    return (0);
X
X  /* Find the modifiers */
X  if (inven[i].phit != UNKNOWN)
X  { hitplus += inven[i].phit;
X
X    if (inven[i].pdam != UNKNOWN)
X      damplus = inven[i].pdam; 
X  }
X
X  return (class + 12*hitplus + 10*damplus);
X}
X
X/*
X * havemissile: Return best missile. Dont consider arrows if we
X * are cheating.  Consider arrows first if we are wielding our bow.
X */
X
Xint havemissile ()
X{ register int i, fewest = 9999, obj = NONE;
X
X  if (wielding (thrower))	/* Wielding bow, use arrows */
X  { for (i=0; i<invcount; ++i)
X      if (inven[i].count > 0 && inven[i].count < fewest &&
X          inven[i].type == missile && stlmatch(inven[i].str,"arrow"))
X      { obj = i; fewest = inven[i].count; }
X  }
X
X  if (obj < 0)			/* Not wielding bow or no arrows */
X  { for (i=0; i<invcount; ++i)
X      if (inven[i].count > 0 &&
X	  inven[i].count < fewest &&
X	  !itemis (i, INUSE) &&
X          (inven[i].type == missile ||
X           stlmatch(inven[i].str,"spear") || 
X           stlmatch(inven[i].str,"dagger") || 
X           stlmatch(inven[i].str,"mace") && inven[i].phit <= 0 || 
X           stlmatch(inven[i].str,"long sword") && inven[i].phit < 0))
X      { obj = i; fewest = inven[i].count; }
X  }
X
X  if (obj != NONE)
X    dwait (D_BATTLE, "Havemissile returns (%s", itemstr (obj));
X  else
X    dwait (D_BATTLE, "Havemissile fails");
X
X  return (obj);
X}
X
X/*
X * havearrow: return the index of any arrow which has count 1.
X */
X
Xhavearrow ()
X{ int arr;
X
X  for (arr = 0; arr<invcount; arr++)
X    if (inven[arr].type == missile &&
X        inven[arr].count == 1 &&
X        stlmatch(inven[arr].str,"arrow"))
X      return (arr);
X
X  return (NONE);
X}
X
X/*
X * plusweapon: we just enchanted our current weapon.
X *             Do a picky identify to try to find its plusses.
X */
X
Xplusweapon ()
X{
X  cursedweapon = 0;
X  newweapon = 1;
X  forget (currentweapon, CURSED);
X  usesynch = 0;
X}
X
X/* 
X * hitbonus: Return the bonus to hit.
X */
X
Xhitbonus (strength)
Xint strength;
X{ int bonus = 0;
X  
X  if (strength < 700) bonus = strength/100 - 7;
X
X  else if (version > RV36B)
X  { if (strength < 1700) bonus = 0;
X    else if (strength < 2100) bonus = 1;
X    else if (strength < 3100) bonus = 2;
X    else bonus = 3;    
X  }
X
X  else 
X  { if (strength < 1700) bonus = 0;
X    else if (strength < 1851) bonus = 1;
X    else if (strength < 1900) bonus = 2;
X    else bonus = 3;    
X  }
X
X  return (bonus);
X}
X
X/* 
X * damagebonus: bonus = the damage bonus.
X */
X
Xdamagebonus (strength)
Xint strength;
X{ int bonus = 0;
X
X  if (strength < 700) bonus = strength/100 - 7;
X
X  else  if (version > RV36B)
X  { if (strength < 1600) bonus = 0;
X    else if (strength < 1800) bonus = 1;
X    else if (strength < 1900) bonus = 2;
X    else if (strength < 2100) bonus = 3;
X    else if (strength < 2200) bonus = 4;
X    else if (strength < 1600) bonus = 5;
X    else bonus = 6;
X  }
X
X  else 
X  { if (strength < 1600) bonus = 0;
X    else if (strength < 1800) bonus = 1;
X    else if (strength < 1801) bonus = 2;
X    else if (strength < 1876) bonus = 3;
X    else if (strength < 1891) bonus = 4;
X    else if (strength < 1900) bonus = 5;
X    else bonus = 6;    
X  }
X
X  return (bonus);
X}
X
X/* 
X * setbonuses: Set global hit and damage pluses.
X */
X
Xsetbonuses ()
X{
X  /* Set global Hit bonus */
X  gplushit = hitbonus (Str);
X
X  if (leftring != NONE && stlmatch (inven[leftring].str, "dexterity") &&
X      inven[leftring].phit != UNKNOWN)
X   gplushit += inven[leftring].phit;
X
X  if (rightring != NONE && stlmatch (inven[rightring].str, "dexterity") &&
X      inven[rightring].phit != UNKNOWN)
X   gplushit += inven[rightring].phit;
X
X  /* Set global Damage Bonus */
X  gplusdam = damagebonus (Str);
X
X  if (leftring != NONE && stlmatch (inven[leftring].str, "add damage") &&
X      inven[leftring].pdam != UNKNOWN)
X   gplusdam += inven[leftring].pdam;
X
X  if (rightring != NONE && stlmatch (inven[rightring].str, "add damage") &&
X      inven[rightring].pdam != UNKNOWN)
X   gplusdam += inven[rightring].pdam;
X
X  /* Set bonuses for weapons */
X  wplushit = gplushit;
X  wplusdam = gplusdam;
X
X  if (currentweapon != NONE)
X  { if (inven[currentweapon].phit != UNKNOWN)
X      wplushit += inven[currentweapon].phit;
X
X    if (inven[currentweapon].pdam != UNKNOWN)
X      wplusdam += inven[currentweapon].pdam;
X  }
X}
/
echo 'x - globals.h'
sed 's/^X//' > globals.h << '/'
X/*
X * globals.h: Rog-O-Matic XIV (CMU) Thu Jan 31 18:12:50 1985 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * Global variables
X */
X
X/* global files */
Xextern FILE *frogue,*trogue;	/* From Rogue, To Rogue */
Xextern FILE *fecho;		/* Rogomatic score file */
Xextern FILE *logfile;		/* Rogomatic score file */
Xextern FILE *realstdout;	/* Real stdout when in terse or emacs mode */
Xextern FILE *snapshot;		/* File for snapshot command */
XFILE *wopen();			/* Open a file for world access */
X
X/* global characters and strings */
Xextern char afterid;		/* Index of object after identify */
Xextern char *genocide;		/* List of monsters to genocide */
Xextern char genocided[];	/* List of monsters genocided */
Xextern char lastcmd[];		/* Copy of last command sent to Rogue */
Xextern char lastname[];		/* Name of last potion/scroll/wand */
Xextern char nextid;		/* Next object to identify */
Xextern char ourkiller[];	/* What was listed on the tombstone */
Xextern char *parmstr;		/* Pointer to argument space */
Xextern char queue[];		/* stuff to be sent to Rogue */
Xextern char *roguename;		/* Name we are playing under */
Xextern char screen[24][80];	/* characters drawn by Rogue */
Xextern char sumline[];		/* Summation line */
Xextern char *termination;	/* Latin verb for how we died */
Xextern char versionstr[];	/* Version of Rogue we are playing */
X
X/* character and string functions */
Xextern char getlogtoken(), *getname(), *itemstr();
Xextern char logchar(), *monname(), *realname();
X
X/* double precision floating point functions */
Xdouble prob(), mean(), stdev();	/* For stats.c */
X
X/* global integers */
Xextern int aggravated;		/* True if we aggravated this level */
Xextern int agoalr,agoalc;	/* where we killed a monster */
Xextern int ammo;		/* Number of missiles in pack */
Xextern int arglen;		/* Length of argument space */
Xextern int arrowshot;		/* True if trap fired at us this round */
Xextern int atrow,atcol;		/* where is the '@'? (us) */
Xextern int atrow0,atcol0;	/* where was the '@' last time */
Xextern int attempt;		/* # times have we explored this level */
Xextern int badarrow;		/* True if we missed with this arrow */
Xextern int beingheld;		/* True if being held by a fungus */
Xextern int beingstalked;	/* True if an Invisible Stalker is around */
Xextern int blinded;		/* True if blinded */
Xextern int blindir;		/* Last direction we moved when blind */
Xextern int cancelled;		/* Turns till use cancellation again */
Xextern int cecho;		/* Last message type to logfile */
Xextern int cheat;		/* True ==> cheat to win */
Xextern int checkrange;		/* True ==> check range */
Xextern int chicken;		/* True ==> test run away code */
Xextern int compression;		/* True ==> move multiple squares */
Xextern int confused;		/* True if confused */
Xextern int cosmic;		/* True if hallucinating */
Xextern int currentarmor;	/* Index of our armor */
Xextern int currentweapon;	/* Index of our weapon */
Xextern int cursedarmor;		/* True if armor is cursed */
Xextern int cursedweapon;	/* True if weapon if cursed */
Xextern int darkdir;		/* Direction of arrow in dark room */
Xextern int darkturns;		/* # arrows left to fire in dark room */
Xextern int debugging;		/* Debugging options in effect */
Xextern int didreadmap;		/* Last magically mapped level */
Xextern int doorlist[], *newdoors; /* Holds r,c of new doors found */
Xextern int doublehasted;	/* True if double hasted (3.6 only) */
Xextern int droppedscare;	/* Number of scare mon. on this level */
Xextern int emacs;		/* True if in emacs mode */
Xextern int exploredlevel;	/* We completely explored this level */
Xextern int floating;		/* True if we are levitating */
Xextern int foughtmonster;	/* True if we recently fought a monster */
Xextern int foundarrowtrap;	/* Well, did we? */
Xextern int foundtrapdoor;	/* Well, did we? */
Xextern int goalr,goalc;		/* where are we trying to go */
Xextern int goodarrow;		/* Number of times we killed in one blow */
Xextern int goodweapon;		/* Used for two-handed sword */
Xextern int gplusdam;		/* Global damage bonus */
Xextern int gplushit;		/* Global hit bonus */
Xextern int hasted;		/* True if hasted */
Xextern int head,tail;		/* endpoints of circular queue */
Xextern int hitstokill;		/* Number of hits to kill last monster */
Xextern int interrupted;		/* True if at commandtop from onintr() */
Xextern int knowident;		/* Found an identify scroll? */
Xextern int larder;		/* Number of foods left */
Xextern int lastate;		/* Time we last ate */
Xextern int lastdamage;		/* Amount of last hit by a monster */
Xextern int lastdrop;		/* What did we last try to drop */
Xextern int lastfoodlevel;	/* Last food found */
Xextern int lastmonster;		/* Last monster we tried to hit */
Xextern int lastobj;		/* What did we last try to use */
Xextern int lastwand;		/* Index of last wand */
Xextern int leftring;		/* Index of our left ring */
Xextern int logdigested;		/* True if game log has been read by replay */
Xextern int logging;		/* True if logging game */
Xextern int lyinginwait;		/* Did we lie in wait last turn? */
Xextern int maxobj;		/* How much can we carry */
Xextern int missedstairs;	/* True if we missed the stairs */
Xextern int morecount;		/* Number of messages since last command */
Xextern int msgonscreen;		/* There is a rogomatic msg on the screen */
Xextern int newarmor;		/* True if our armor status has changed */
Xextern int newring;		/* True if our ring status has changed */
Xextern int newweapon;		/* True if our weapon status has changed */
Xextern int nohalf;		/* True if no halftime show */
Xextern int noterm;		/* True if no human watching */
Xextern int objcount;		/* Number of objects */
Xextern int ourscore;		/* Our score when we died/quit */
Xextern int playing;		/* True if still playing the game */
Xextern int poorarrow;		/* # Times we failed to kill in one blow */
Xextern int protected;		/* True if we protected our armor */
Xextern int putonseeinv;		/* Time when last put on see invisible ring */
Xextern int quitat;		/* Score we are trying to beat */
Xextern int redhands;		/* True if our hands are red */
Xextern int replaying;		/* True if replaying old game */
Xextern int revvideo;		/* True if in rev. video mode */
Xextern int rightring;		/* Index of our right ring */
Xextern int rogpid;		/* Process id of Rogue process */
Xextern int room[];		/* Flags for each room */
Xextern int row,col;		/* where is the cursor? */
Xextern int scrmap[24][80];	/* attribute flags for squares */
Xextern int slowed;		/* True if we recently slowed a monster */
Xextern int stairrow,staircol;	/* Where is the staircase */
Xextern int teleported;		/* times teleported on this level */
Xextern int terse;		/* True if in terse mode */
Xextern int transparent;		/* True ==> user mode */
Xextern int trapc;		/* Col of last trap */
Xextern int trapr;		/* Row of last trap */
Xextern int urocnt;		/* Un-identified Rogue Object count */
Xextern int usesynch;		/* Have we finished using something? */
Xextern int usingarrow;		/* True if wielding an arrow from a trap */
Xextern int version;		/* From types.h, set by getrougeversion */
Xextern int wplusdam;		/* Weapon damage bonus */
Xextern int wplushit;		/* Weapon hit bonus */
Xextern int zone;		/* Current zone (0 to 8) */
Xextern int zonemap[9][9];	/* Connectivity map */
X
X/* Status line variables */
Xextern int Level,MaxLevel,Gold,Hp,Hpmax,Str,Strmax,Ac,Exp,Explev;
Xextern char Ms[];		/* Msg 'X', 'Hungry', 'Weak', 'Fainting' */
Xextern int turns;		/* Est time in Rogue turns since start */
X
X/* Geometry data */
Xextern int deltc[], deltr[];	/* Displacements for directions */
Xextern int deltrc[];		/* ditto */
Xextern char keydir[];		/* Directions for motion keys */
Xextern int movedir;		/* Which direction did we last move */
Xextern stuff translate[];	/* what Rogue characters represent */
X
X/* Time history */
Xextern timerec timespent[];
X
X/* Objects in pack */
Xextern invrec inven[];	extern int invcount;
X
X/* Stuff on this level */
Xextern stuffrec slist[]; extern int slistlen;
X
X/* Monster on this level */
Xextern monrec mlist[];	extern int mlistlen;
X
Xextern char	killedmonster, targetmonster;
X
X/* Door search variables */
Xextern int	new_mark, new_findroom, new_search, new_stairs, new_arch;
Xextern char	timessearched[24][80], timestosearch;
Xextern int	searchstartr, searchstartc;
Xextern int	reusepsd;
X
X/* Results of last makemove */
Xextern int	ontarget, targetrow, targetcol;
X
X/* Monster attribute and Long term memory arrays */
Xextern attrec monatt[];		/* Monster attributes */
Xextern lrnrec ltm;		/* Long term memory -- general */
Xextern ltmrec monhist[]; 	/* Long term memory -- creatures */
Xextern ltmrec delhist[]; 	/* Long term memory -- changes this game */
Xextern int nextmon;		/* Length of LTM */
Xextern int monindex[];		/* Index into monhist array */
X
X/* Genetic learning arrays */
Xextern int knob[];		/* Knobs */
Xextern int k_srch;		/* Propensity for searching squares */
Xextern int k_door;		/* Propensity for searching doors */
Xextern int k_rest;		/* Propensity for resting */
Xextern int k_arch;		/* Propensity for firing arrows */
Xextern int k_exper;		/* Level on which to experiment with items */
Xextern int k_run;		/* Propensity for retreating */
Xextern int k_wake;		/* Propensity for waking things up */
Xextern int k_food;		/* Propensity for hoarding food (rings) */
/
echo 'x - survival.c'
sed 's/^X//' > survival.c << '/'
X/*
X * survival.c: Rog-O-Matic XIV (CMU) Mon Jan  7 15:22:23 1985 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * This file contains all of the "Run Away" code.
X * Well, almost all of the run away code.
X * At least I think it has something to do with running away.
X */
X
X# include <stdio.h>
X# include <ctype.h>
X# include <curses.h>
X# include "types.h"
X# include "globals.h"
X
X# define SO	  1
X# define SE	  0
X
X# define highlight(rowcol,stand)		\
X  if (print || debug (D_SCREEN))		\
X  { at((rowcol)/80,(rowcol)%80);		\
X    if (stand) standout ();			\
X    printw("%c",screen[0][rowcol]);		\
X    if (stand) standend ();			\
X    refresh (); }
X
X/*
X * markcycles: evokes fond memories of an earlier time, when Andrew
X * was a hacker who just patched things together until they worked,
X * and used the SHIFT-STOP key to compile things, rather than thinking.
X *
X * markcycles does a depth-first-search of the squares to find loops in
X * the rooms.  All doors on loops are marked RUNOK, and are used by the
X * runaway code.
X */
X
Xmarkcycles (print)
X{ short mark[1920];
X  struct {short where,door,dirs;} st[1000];
X  register int sp,newsquare; int *Scr; int whichdir; int D;
X
X  if (!new_mark) return (0);
X
X  Scr=scrmap[0];
X
X  { register int count=1920; register short *m=mark; while(count--) *m++=0;}
X  sp=1; st[1].where=atrow*80+atcol; st[1].dirs=1; st[1].door=0;
X
X  for (D = 0; D < 8; D += 2)
X  { if ((Scr[newsquare = (st[1].where+deltrc[D^4])]) & CANGO)
X    { if (mark[newsquare])
X      { int stop, i;
X        if (mark[newsquare] < sp)
X          for (stop = st[mark[newsquare]].door,
X                 i = (Scr[st[sp].where] & DOOR) ? sp : st[sp].door;
X               i !=  stop;
X               i =st[i].door)
X          { Scr[st[i].where] |= RUNOK; 
X            highlight (st[i].where, SO) 
X          }
X       }
X       else
X       { sp++; mark[newsquare] = sp;
X         highlight (newsquare, SO)
X         st[sp].where=newsquare;
X         st[sp].dirs=1; st[1].dirs= -1;
X         st[sp].door = (Scr[st[sp-1].where]&DOOR) ? sp-1 : st[sp-1].door;
X       }
X     }
X
X     while (sp > 1)
X     { if ((whichdir=(st[sp].dirs++)<<1)<8)
X       { /* whichdir is 6,2, or 4. */
X         if ((Scr[newsquare= (st[sp].where+deltrc[(whichdir+D)&7])])&CANGO)
X         { if (mark[newsquare])
X           { register int stop,i;
X             if (mark[newsquare]<sp)
X                 for (stop=st[mark[newsquare]].door,
X                 i=(Scr[st[sp].where]&DOOR)?sp:st[sp].door;
X                 i!=stop;
X                 i=st[i].door)
X             { Scr[st[i].where] |= RUNOK;
X               highlight (st[i].where, SO)
X             }
X           }
X           else
X           { sp++; mark[newsquare]=sp;
X             highlight (newsquare, SO)
X             st[sp].where=newsquare;
X             st[sp].dirs=1; D += whichdir+4;
X             st[sp].door = (Scr[st[sp-1].where]&DOOR) ? sp-1 : st[sp-1].door;
X           }
X         }
X       }
X       else
X       { if (! (Scr[st[sp].where] & RUNOK)) highlight (st[sp].where, SE) 
X         sp--;
X         D -= 4+((st[sp].dirs-1)<<1);
X       }
X     }
X  }
X  highlight (st[1].where, SE)
X
X  new_mark = 0;
X  return (1);
X}
X
X/* 
X * Runaway: Panic!
X */
X
Xint runaway ()
X{
X  if (on (SCAREM)) 
X  { dwait (D_BATTLE, "Not running, on scare monster scroll!");
X    return (0);
X  }
X
X  dwait (D_BATTLE | D_SEARCH, "Run away!!!!");
X
X  if (on (STAIRS) && !floating)		/* Go up or down */
X  { if (!goupstairs (RUNNING)) godownstairs (RUNNING); 
X    return (1);
X  }
X
X  if (canrun ())		/* If canrun finds a move, use it */
X    return (followmap (RUNAWAY));
X
X  return (0);			/* Cant run away */  
X}
X
X/*
X * Canrun: set up a move which will get us away from danger.
X */
X
Xint canrun ()
X{ int result, oldcomp = compression;
X  int runinit(), runvalue(), expruninit(), exprunvalue();
X  
X  if (on (STAIRS)) return (1);		/* Can run down stairs */
X
X  compression = 0;			/* Be tense when fleeing */
X  result = (findmove (RUNAWAY, runinit, runvalue, REEVAL) ||
X            findmove (EXPLORERUN, expruninit, exprunvalue, REEVAL));
X
X  compression = oldcomp;
X  return (result);
X}
X
X/*
X * unpin:
X *
X *	"When you're stuck and wriggling on a pin,
X *	 When you're pinned and wriggling on a wall..."
X *
X *		"The Love Song of J. Alfred Prufrock", T.S. Eliot
X */
X
Xint unpin ()
X{ int result, oldcomp = compression;
X  int unpininit (), runvalue (), expunpininit (),
X      exprunvalue (), expunpinvalue ();
X
X  if (on (SCAREM)) 
X  { dwait (D_BATTLE, "Not unpinning, on scare monster scroll!");
X    return (0);
X  }
X
X  if (on (STAIRS) && !floating)
X  { if (!goupstairs (RUNNING)) godownstairs (RUNNING); 
X    return (1);
X  }
X
X  dwait (D_BATTLE, "Pinned!!!!");
X
X  /* currentrectangle ();   // always done after each move of the rogue // */
X
X  compression = 0;	/* Be tense when fleeing */
X  result = (makemove (UNPIN, unpininit, runvalue, REEVAL) ||
X            makemove (UNPINEXP, expunpininit, expunpinvalue, REEVAL));
X
X  compression = oldcomp;
X  return (result);
X}
X
X/*
X * backtodoor: Useful when being ganged up on. Back into the nearest
X *             door.
X */
X
Xint backtodoor (dist)
Xint dist;
X{ int rundoorinit(), rundoorvalue();
X  static int lastcall= -10, stillcount=0, notmoving=0, closest=99;
X  
X  /* 
X   * Keep track of the opponents distance.  If they stop advancing on us,
X   * disable the rule for 10 turns.
X   */
X
X  if (turns-lastcall > 20)
X  { notmoving=0; closest=99; stillcount=0; }
X  else if (dist < closest)
X  { closest=dist; stillcount=0; }
X  else if (++stillcount > 5)
X  { notmoving++; }
X
X  lastcall = turns;
X
X  /* 
X   * Now check whether we try to move back to the door
X   */
X
X  if (notmoving)
X    dwait (D_BATTLE, "backtodoor: monsters not moving");
X  
X  else if (on (SCAREM)) 
X    dwait (D_BATTLE, "Not backing up, on scare monster scroll!");
X
X  else if (dist > 0 && (on (DOOR) || nextto (DOOR, atrow, atcol)))
X    dwait (D_BATTLE, "backtodoor: next to door, have time");
X
X  else if (makemove (RUNTODOOR, rundoorinit, rundoorvalue, REEVAL))
X  { dwait (D_BATTLE, "Back to the door..."); return (1); }
X
X  return (0);
X}
/
echo 'x - types.h'
sed 's/^X//' > types.h << '/'
X/*
X * types.h: Rog-O-Matic XIV (CMU) Wed Jan 30 14:57:17 1985 - mlm
X * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
X *
X * Miscellaneous Macros and Constants 
X */
X
X/* The unctrl macro for systems where curses doesn't define it */
X
X# ifndef unctrl
Xextern char	*_unctrl[];
X
X# define	unctrl(ch)	(_unctrl[ch & 0177])
X# endif
X
X/* Global Preprocessor constants */
X
X# define ill		";'"
X# define status		"Str:"
X# define MAXATTEMPTS	(10)
X# define ROGQUIT	(-2)
X# define DIED		(1)
X# define FINISHED	(0)
X# define SAVED		(2)
X# define MAXINV		(26)
X# define NONE		(-1)
X# define MAXSTUFF	(30)
X# define MAXMONST	(40)
X# define SAVEARROWS	(30)
X# define NAMSIZ		(64)
X# define MAXLEV		(30)
X# define MAXMON		(128)
X# define SUCCESS	(1)
X# define FAILURE	(0)
X
X# define ISPRT(c)	((c) >= ' ' && (c) <= '~')
X# define GETROGUECHAR	fgetc(frogue)
X# define GETLOGCHAR	fgetc(logfile)
X
X/*
X * Magic numbers for Invisible stalker strategies
X */
X
X# define INVHIT		(1000)
X
X/*
X * Attribute bits for the screen map: If you change this list, be sure
X * to change the flag names at the end of debug.c.   MLM
X */
X
X# define BEEN		(0000000001)
X# define CANGO		(0000000002)
X# define DOOR		(0000000004)
X# define HALL		(0000000010)
X# define PSD		(0000000020)
X# define ROOM		(0000000040)
X# define SAFE		(0000000100)
X# define SEEN		(0000000200)
X# define SEENPOS	(7)
X# define DEADEND	(0000000400)
X# define STUFF		(0000001000)
X# define TRAP		(0000002000)
X# define ARROW		(0000004000)
X# define TRAPDOR	(0000010000)
X# define TELTRAP	(0000020000)
X# define GASTRAP	(0000040000)
X# define BEARTRP	(0000100000)
X# define DARTRAP	(0000200000)
X# define WATERAP	(0000400000)
X# define MONSTER	(0001000000)
X# define WALL		(0002000000)
X# define USELESS	(0004000000)
X# define SCAREM		(0010000000)
X# define STAIRS		(0020000000)
X# define RUNOK		(0040000000)
X# define BOUNDARY	(0100000000)
X# define SLEEPER	(0200000000)
X# define EVERCLR	(0400000000)
X
X# define TOPW		(0)
X# define BOTW		(1)
X# define LEFTW		(2)
X# define RIGHTW		(3)
X# define NOTW		(-1)
X# define DOORW		(-2)
X# define CORNERW	(-3)
X
X# define INFINITY	(10000)
X
X# define NOTAMOVE	(-1)
X
X# define FORCE		(1)
X# define OPTIONAL	(0)
X
X# define NEAR		(0)
X# define HERE		(1)
X
X# define NOPRINT	(0)
X# define DOPRINT	(1)
X
X# define NOTRUNNING	(0)
X# define RUNNING	(1)
X
X# define ANY		(0)
X# define RUSTPROOF	(1)
X
X/* Types of moves planned by makemove */
X# define REUSE		(0)
X# define REEVAL		(1)
X
X# define EXPLORE	(1)
X# define EXPLORERUN	(2)
X# define RUNTODOOR	(3)
X# define RUNAWAY	(4)
X# define SECRETDOOR	(5)
X# define FINDSAFE	(6)
X# define GOTOMOVE	(7)
X# define ATTACKSLEEP	(8)
X# define ARCHERYMOVE	(9)
X# define UNPIN		(10)
X# define UNPINEXP	(11)
X# define EXPLOREROOM	(12)
X# define FINDROOM	(13)
X# define RESTMOVE	(14)
X# define DOWNMOVE	(15)
X# define RUNDOWN	(16)
X# define NUMMOVES	(17)
X
X/* Version numbers */
X# define RV36A		(361)	/* OLDROG: Rogue 3.6 w/o wands */
X# define RV36B		(362)	/* CURROG: Rogue 3.6 with wands */
X# define RV52A		(521)	/* NEWROG: Rogue 5.2 */
X# define RV52B		(522)	/* Rogue 5.2 with maze rooms */
X# define RV53A		(531)	/* Rogue 5.3 new monsters */
X
X/* Ways to spend time */
X
X# define T_OTHER	(0)
X# define T_HANDLING	(1)
X# define T_FIGHTING	(2)
X# define T_RESTING	(3)
X# define T_MOVING	(4)
X# define T_EXPLORING	(5)
X# define T_RUNNING	(6)
X# define T_GROPING	(7)
X# define T_SEARCHING	(8)
X# define T_DOORSRCH	(9)
X# define T_LISTLEN	(10)
X
X/* Bit value for debugging types (for debugging function dwait) */
X
X# define D_FATAL	(00001)
X# define D_ERROR	(00002)
X# define D_WARNING	(00004)
X# define D_INFORM	(00010)
X# define D_SEARCH	(00020)
X# define D_BATTLE	(00040)
X# define D_MESSAGE	(00100)
X# define D_PACK		(00200)
X# define D_CONTROL	(00400)
X# define D_SCREEN	(01000)
X# define D_MONSTER	(02000)
X# define D_SAY		(04000)
X# define D_ALL		(01777)
X# define D_NORMAL	(D_FATAL | D_ERROR)
X
X# define debugon(mask)	(debugging|=(mask))
X# define debugoff(mask)	(debugging&=(~(mask)))
X# define debug(mask)	(debugging&(mask))
X
X/* Parameters for genetic learning, knobs */
X# define K_SRCH		(0)
X# define K_DOOR		(1)
X# define K_REST		(2)
X# define K_ARCH		(3)
X# define K_EXPER	(4)
X# define K_RUN		(5)
X# define K_WAKE		(6)
X# define K_FOOD		(7)
X# define MAXKNOB	(8)
X
X/* Monster attributes */
X# define AWAKE		(1)
X# define ASLEEP		(2)
X# define ALL		(9)
X# define HELD		(10)
X
X/* Constants for handling inventory */
X# define UNKNOWN	-99999
X# define INVMAX		25
X
X/* Pack item attributes  DR UTexas 25 Jan 84 */
X# define KNOWN                 (0000000001)
X# define CURSED                (0000000002)
X# define ENCHANTED             (0000000004)
X# define PROTECTED             (0000000010)
X# define UNCURSED              (0000000020)
X# define INUSE                 (0000000040)
X# define WORTHLESS             (0000000100)
X
X/* Miscellaneous macros */
X
X# define LETTER(i)	((char)((i)+'a'))
X# define DIGIT(c)	((int)((c)-'a'))
X# define OBJECT(c)	DIGIT(c)
X# define ISDIGIT(c)	((c) >= '0' && (c) <= '9')
X# define plural(n)	((n)==1 ? "" : "s")
X# define ordinal(n)	((((n)/10)%10==1) ? "th": \
X			      ((n)%10==1) ? "st": \
X			      ((n)%10==2) ? "nd": \
X			      ((n)%10==3) ? "rd":"th")
X# define ctrl(c)	((c)&037)
X# define ESC		ctrl('[')
X# define NEWLINE	ctrl('J')
X# define abs(a)		((a) >= 0 ? (a) : -(a))
X# define max(a,b)	(((a) > (b)) ? (a) : (b))
X# define min(a,b)	(((a) < (b)) ? (a) : (b))
X# define between(v,a,b)	((v) < (a) ? (a) : (v) > (b) ? (b) : (v))
X# define percent(v,p)	(((v)*(p))/100)
X# define SKIPARG	while (*++(*argv)); --(*argv)
X# define when	        break; case
X# define orwhen	        case
X# define otherwise      break; default
X# define SKIPDIG(s)	while (ISDIGIT(*(s))) (s)++
X# define SKIPCHAR(c,s)	while (*(s)==(c)) (s)++
X# define SKIPTO(c,s)	\
X	{ while (*(s) && *(s)!=(c)) (s)++; if (*(s)==(c)) (s)++; }
X
X/* Utility Macros */
X
X/* onrc - tell if row and col have the proper attributes */
X# define onrc(type,r,c) ((type)&scrmap[r][c])
X
X/* on - tell if current position has correct attributes */
X# define on(type) onrc(type,atrow,atcol)
X
X/* seerc - is this character at row,col */
X# define seerc(ch,r,c) ((ch)==screen[r][c])
X
X/* see - is this character at current position */
X# define see(ch) seerc(atrow,atcol)
X
X/* setrc - set attribute at <r,c> */
X# define setrc(type,r,c) scrmap[r][c]|=(type)
X
X/* set - set attribute at current position */
X# define set(type) setrc(type,atrow,atcol)
X
X/* unsetrc - unset attribute at <r,c> */
X# define unsetrc(type,r,c) scrmap[r][c]&= ~(type)
X
X/* unset - unset attribute at current position */
X# define unset(type) unsetrc(type,atrow,atcol)
X
X/* Direc - give the vector from an xy difference */
X# define direc(r,c) (r>0?(c>0?7:(c<0?5:6)):(r<0?(c>0?1:(c<0?3:2)):(c>0?0:4)))
X
X/* atdrow - gives row of adjacent square given direction */
X# define atdrow(dir) (atrow+deltr[(dir)])
X
X/* atdcol - gives col of adjacent square given direction */
X# define atdcol(dir) (atcol+deltc[(dir)])
X
X/* Define a more mnemonic string comparison */
X# define streq(s1,s2) (strcmp ((s1),(s2)) == 0)
X
X/* Monster value macros */
X# define maxhitchar(m) (cosmic ? Level*3/2+6 : monatt[(m)-'A'].maxdam)
X# define avghitchar(m) (cosmic ? Level*2/3+4 : monatt[(m)-'A'].expdam)
X# define maxhit(m) maxhitchar(mlist[m].chr)
X# define avghit(m) avghitchar(mlist[m].chr)     /* times 10 */
X
X/* Item knowledge macros   DR UTexas 25 Jan 84 */
X
X/* itemis - test pack item for traits */
X# define itemis(obj,trait) ((obj>=0) ? ((trait)&inven[obj].traits) : 0)
X
X/* remember - set traits for pack item */
X# define remember(obj,trait) ((obj>=0) ? (inven[obj].traits|=(trait)) : 0)
X
X/* forget - clear traits for pack item */
X# define forget(obj,trait) ((obj>=0) ? (inven[obj].traits&= ~(trait)) : 0)
X
X/* The types of objects */
Xtypedef enum { strange, food, potion, scroll, wand, ring, hitter,
X               thrower, missile, armor, amulet, gold, none} stuff;
X
Xtypedef struct { int   fail, win; } probability;
X
Xtypedef struct { int   count;
X		 double sum, sumsq, low, high; } statistic;
X
Xtypedef struct { int   scol, srow;
X                 stuff what; } stuffrec;
X
Xtypedef struct { int   mcol, mrow;
X                 char  chr;
X                 int   q; } monrec;
X
Xtypedef struct { int   expdam, maxdam, mtokill; } attrec;
X
Xtypedef struct { int gamecnt, gamesum, inittime, timeswritten; } lrnrec;
X
Xtypedef struct { char m_name[NAMSIZ];
X		 probability wehit, theyhit, arrowhit;
X		 statistic htokill, damage, atokill; } ltmrec;
X
Xtypedef struct { stuff type; 
X                 int   count, phit, pdam, charges, traits;
X		 char  *str;  } invrec;
X
Xtypedef struct { int activity[T_LISTLEN];
X		 int timestamp; } timerec;
/
echo 'Part 08 of Rog-O-Matic XIV complete.'
exit



More information about the Comp.sources.unix mailing list