|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 29320 (0x7288) Types: TextFile Names: »main.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Rog-O-Matic/main.c«
/* * main.c: Rog-O-Matic XIV (CMU) Thu Jan 31 18:12:14 1985 - mlm */ /*========================================================================= * Rog-O-Matic XIV * Automatically exploring the dungeons of doom * Copyright (C) 1985 by Appel, Jacobson, Hamey, and Mauldin * * The right is granted to any person, university, or company * to copy, modify, or distribute (for free) these files, * provided that any person receiving a copy notifies Michael Mauldin * * (1) by electronic mail to Mauldin@CMU-CS-A.ARPA or * * (2) by US Mail to Michael Mauldin * Dept. of Computer Science * Carnegie-Mellon University * Pittsburgh, PA 15213 * * All other rights, including those of publication and sale, are reserved. *========================================================================/ /***************************************************************** * History: I. Andrew Appel & Guy Jacobson, 10/81 [created] * II. Andrew Appel & Guy Jacobson, 1/82 [added search] * III. Michael Mauldin, 3/82 [added termcap] * IV. Michael Mauldin, 3/82 [searching] * V. Michael Mauldin, 4/82 [cheat mode] * VI. Michael Mauldin, 4/82 [object database] * VII. All three, 5/82 [running away] * VIII. Michael Mauldin, 9/82 [improved cheating] * IX. Michael Mauldin, 10/82 [replaced termcap] * X. Mauldin, Hamey, 11/82 [Fixes, Rogue 5.2] * XI. Mauldin, 11/82 [Fixes, Score lock] * XII. Hamey, Mauldin, 06/83 [Fixes, New Replay] * XIII. Mauldin, Hamey, 11/83 [Fixes, Rogue 5.3] * XIV. Mauldin 01/85 [Fixes, UT mods] * * General: * * This is the main routine for the player process, which decodes the * Rogue output and sends commands back. This process is execl'd by the * rogomatic process (cf. setup.c) which also execl's the Rogue process, * conveniently connecting the two via two pipes. * * Source Files: * * arms.c Armor, Weapon, and Ring handling functions * command.c Effector interface, sends cmds to Rogue * database.c Memory for objects "discovered" * debug.c Contains the debugging functions * explore.c Path searching functions, exploration * findscore.c Reads Rogue scoreboard * io.c I/O functions, Sensory interface * main.c Main Program for 'player' (this file) * mess.c Handles messages from Rogue * monsters.c Monster handling utilities * mover.c Creates command strings to accomplish moves * rooms.c Room specific functions, new levels * scorefile.c Score file handling utilities * search.c Does shortest path * setup.c Main program for 'rogomatic' * strategy.c Makes high level decisions * survival.c Find cycles and places to run to * tactics.c Medium level intelligence * things.c Builds commands, part of Effector interface * titlepage.c Prints the animated copyright notice * utility.c Miscellaneous Unix (tm) functions * worth.c Evaluates the items in the pack * * Include files: * * globals.h External defs for all global variables * install.h Machine dependent DEFINES * termtokens.h Defines various tokens to/from Rogue * types.h Global DEFINES, macros, and typedefs. * * Other files which may be included with your distribution include * * rplot A shell script, prints a scatter plot of Rog's scores. * rgmplot.c A program used by rplot. * datesub.l A program used by rplot. * histplot.c A program which plots a histogram of Rgm's scores. * * Acknowledgments * * The UTexas modifications included in this distribution * came from Dan Reynolds, and are included by permission. * Rog-O-Matics first total winner against version 5.3 was * on a UTexas computer. *****************************************************************/ # include <curses.h> # include <ctype.h> # include <signal.h> # include <setjmp.h> # include "types.h" # include "termtokens.h" # include "install.h" /* global data - see globals.h for current definitions */ /* Files */ FILE *fecho=NULL; /* Game record file 'echo' option */ FILE *frogue=NULL; /* Pipe from Rogue process */ FILE *logfile=NULL; /* File for score log */ FILE *realstdout=NULL; /* Real stdout for Emacs, terse mode */ FILE *snapshot=NULL; /* File for snapshot command */ FILE *trogue=NULL; /* Pipe to Rogue process */ /* Characters */ char *logfilename = ""; /* Name of log file */ char afterid = '\0'; /* Letter of obj after identify */ char genelock[100]; /* Gene pool lock file */ char genelog[100]; /* Genetic learning log file */ char genepool[100]; /* Gene pool */ char *genocide; /* List of monsters to be genocided */ char genocided[100]; /* List of monsters genocided */ char lastcmd[64]; /* Copy of last command sent to Rogue */ char lastname[64]; /* Name of last potion/scroll/wand */ char nextid = '\0'; /* Next object to identify */ char screen[24][80]; /* Map of current Rogue screen */ char sumline[128]; /* Termination message for Rogomatic */ char ourkiller[64]; /* How we died */ char versionstr[32]; /* Version of Rogue being used */ char *parmstr; /* Pointer to process arguments */ /* Integers */ int aggravated = 0; /* True if we have aggravated this level */ int agoalc = NONE; /* Goal square to arch from (col) */ int agoalr = NONE; /* Goal square to arch from (row) */ int arglen = 0; /* Length in bytes of argument space */ int ammo = 0; /* How many missiles? */ int arrowshot = 0; /* True if an arrow shot us last turn */ int atrow, atcol; /* Current position of the Rogue (@) */ int atrow0, atcol0; /* Position at start of turn */ int attempt = 0; /* Number times we searched whole level */ int badarrow = 0; /* True if cursed/lousy arrow in hand */ int beingheld = 0; /* True if a fungus has ahold of us */ int beingstalked = 0; /* True if recently hit by inv. stalker */ int blinded = 0; /* True if blinded */ int blindir = 0; /* Last direction we moved when blind */ int cancelled = 0; /* True ==> recently zapped w/cancel */ int cecho = 0; /* Last kind of message to echo file */ int cheat = 0; /* True ==> cheat, use bugs, etc. */ int checkrange = 0; /* True ==> check range */ int chicken = 0; /* True ==> check run away code */ int compression = 1; /* True ==> move more than one square/turn */ int confused = 0; /* True if we are confused */ int cosmic = 0; /* True if we are hallucinating */ int currentarmor = NONE; /* Index of our armor */ int currentweapon = NONE; /* Index of our weapon */ int cursedarmor = 0; /* True if our armor is cursed */ int cursedweapon = 0; /* True if we are wielding cursed weapon */ int darkdir = NONE; /* Direction of monster being arched */ int darkturns = 0; /* Distance to monster being arched */ int debugging = D_NORMAL; /* Debugging options in effect */ int didreadmap = 0; /* Last level we read a map on */ int doorlist[40]; /* List of doors on this level */ int doublehasted = 0; /* True if double hasted (Rogue 3.6) */ int droppedscare = 0; /* True if we dropped 'scare' on this level */ int emacs = 0; /* True ==> format output for Emacs */ int exploredlevel = 0; /* We completely explored this level */ int floating = 0; /* True if we are levitating */ int foughtmonster = 0; /* True if recently fought a monster */ int foundarrowtrap = 0; /* Found arrow trap this level */ int foundtrapdoor = 0; /* Found trap door this level */ int goalc = NONE; /* Current goal square (col) */ int goalr = NONE; /* Current goal square (row) */ int goodarrow = 0; /* True if good (magic) arrow in hand */ int goodweapon = 0; /* True if weapon in hand worth >= 100 */ int gplusdam = 1; /* Our plus damage from strength */ int gplushit = 0; /* Our plus to hit from strength */ int hasted = 0; /* True if hasted */ int hitstokill = 0; /* # times we hit last monster killed */ int interrupted = 0; /* True if at commandtop from onintr() */ int knowident = 0; /* Found an identify scroll? */ int larder = 1; /* How much food? */ int lastate = 0; /* Time we last ate */ int lastdamage = 0; /* Amount of last hit by a monster */ int lastdrop = NONE; /* Last object we tried to drop */ int lastfoodlevel = 1; /* Last level we found food */ int lastmonster = NONE; /* Last monster we tried to hit */ int lastobj = NONE; /* What did we last use */ int lastwand = NONE; /* Index of last wand */ int leftring = NONE; /* Index of our left ring */ int logdigested = 0; /* True if log file has been read by replay */ int logging = 0; /* True if keeping record of game */ int lyinginwait = 0; /* True if we waited for a monster */ int maxobj = 22; /* How much can we carry */ int missedstairs = 0; /* True if we searched everywhere */ int morecount = 0; /* Number of messages since last command */ int msgonscreen = 0; /* Set implies message at top */ int newarmor = 1; /* Change in armor status? */ int *newdoors = NULL; /* New doors on screen */ int newring = 1; /* Change in ring status? */ int newweapon = 1; /* Change in weapon status? */ int nohalf = 0; /* True ==> no halftime show */ int noterm = 0; /* True ==> no user watching */ int objcount = 0; /* Number of objects */ int ourscore = 0; /* Final score when killed */ int playing = 1; /* True if still playing game */ int poorarrow = 0; /* True if arrow has missed */ int protected = 0; /* True if we protected our armor */ int putonseeinv = 0; /* Turn when last put on see inv ring */ int quitat = BOGUS; /* Score to beat, quit if within 10% more */ int redhands = 0; /* True if we have red hands */ int replaying = 0; /* True if replaying old game */ int revvideo = 0; /* True if in rev. video mode */ int rightring = NONE; /* Index of our right ring */ int rogpid = 0; /* Pid of rogue process */ int room[9]; /* Flags for each room */ int row, col; /* Current cursor position */ int scrmap[24][80]; /* Flags bits for level map */ int singlestep = 0; /* True ==> go one turn */ int slowed = 0; /* True ==> recently zapped w/slow monster */ int stairrow, staircol; /* Position of stairs on this level */ int startecho = 0; /* True ==> turn on echoing on startup */ int teleported = 0; /* # times teleported this level */ int terse = 0; /* True ==> terse mode */ int transparent = 0; /* True ==> user command mode */ int trapc = NONE; /* Location of arrow trap, this level (col) */ int trapr = NONE; /* Location of arrow trap, this level (row) */ int urocnt = 0; /* Un-identified Rogue Object count */ int usesynch = 0; /* Set when the inventory is correct */ int usingarrow = 0; /* True ==> wielding an arrow froma trap */ int version; /* Rogue version, integer */ int wplusdam = 2; /* Our plus damage from weapon bonus */ int wplushit = 1; /* Our plus hit from weapon bonus */ int zone = NONE; /* Current screen zone, 0..8 */ int zonemap[9][9]; /* Map of zones connections */ /* Functions */ int (*istat)(), onintr (); char getroguetoken (), *getname(); /* Stuff list, list of objects on this level */ stuffrec slist[MAXSTUFF]; int slistlen=0; /* Monster list, list of monsters on this level */ monrec mlist[MAXMONST]; int mlistlen=0; char targetmonster = '@'; /* Monster we are arching at */ /* Monster attribute and Long term memory arrays */ attrec monatt[26]; /* Monster attributes */ lrnrec ltm; /* Long term memory -- general */ ltmrec monhist[MAXMON]; /* Long term memory -- creatures */ int nextmon = 0; /* Length of LTM */ int monindex[27]; /* Index into monhist array */ /* Genetic learning parameters (and defaults) */ int geneid = 0; /* Id of genotype */ int genebest = 0; /* Best score of genotype */ int geneavg = 0; /* Average score of genotype */ int k_srch = 50; /* Propensity for searching for traps */ int k_door = 50; /* Propensity for searching for doors */ int k_rest = 50; /* Propensity for resting */ int k_arch = 50; /* Propensity for firing arrows */ int k_exper = 50; /* Level*10 on which to experiment with items */ int k_run = 50; /* Propensity for retreating */ int k_wake = 50; /* Propensity for waking things up */ int k_food = 50; /* Propensity for hoarding food (affects rings) */ int knob[MAXKNOB] = {50, 50, 50, 50, 50, 50, 50, 50}; /* Door search map */ char timessearched[24][80], timestosearch; int searchstartr = NONE, searchstartc = NONE, reusepsd=0; int new_mark=1, new_findroom=1, new_search=1, new_stairs=1, new_arch=1; /* Results of last call to makemove() */ int ontarget= 0, targetrow= NONE, targetcol= NONE; /* Rog-O-Matics model of his stats */ int Level = 0, MaxLevel = 0, Gold = 0, Hp = 12, Hpmax = 12; int Str = 16, Strmax = 16, Ac = 6, Exp = 0, Explev = 1, turns = 0; char Ms[30]; /* The message about his state of hunger */ /* Miscellaneous movement tables */ int deltrc[8] = { 1,-79,-80,-81,-1,79,80,81 }; int deltc[8] = { 1, 1, 0, -1, -1, -1, 0, 1 }; int deltr[8] = { 0, -1, -1, -1, 0, 1, 1, 1 }; char keydir[8] = { 'l', 'u', 'k', 'y', 'h', 'b', 'j', 'n' }; int movedir; /* Map characters on screen into object types */ stuff translate[128] = { /* \00x */ none, none, none, none, none, none, none, none, /* \01x */ none, none, none, none, none, none, none, none, /* \02x */ none, none, none, none, none, none, none, none, /* \03x */ none, none, none, none, none, none, none, none, /* \04x */ none, potion, none, none, none, none, none, none, /* \05x */ hitter, hitter, gold, none, amulet, none, none, wand, /* \06x */ none, none, none, none, none, none, none, none, /* \07x */ none, none, food, none, none, ring, none, scroll, /* \10x */ none, none, none, none, none, none, none, none, /* \11x */ none, none, none, none, none, none, none, none, /* \12x */ none, none, none, none, none, none, none, none, /* \13x */ none, none, none, armor, none, armor, none, none, /* \14x */ none, none, none, none, none, none, none, none, /* \15x */ none, none, none, none, none, none, none, none, /* \16x */ none, none, none, none, none, none, none, none, /* \17x */ none, none, none, none, none, none, none, none }; /* Inventory, contents of our pack */ invrec inven[MAXINV]; int invcount = 0; /* Time history */ timerec timespent[50]; /* End of the game messages */ char *termination = "perditus"; char *gamename = "Rog-O-Matic"; char *roguename = "Rog-O-Matic "; /* Used by onintr() to restart Rgm at top of command loop */ jmp_buf commandtop; /* * Main program */ main (argc, argv) int argc; char *argv[]; { char ch, *s, *getenv(), *statusline(), msg[128]; int startingup = 1; register int i; /* * Initialize some storage */ sprintf (genocided, ""); sprintf (lastcmd, "i"); sprintf (ourkiller, "unknown"); sprintf (sumline, ""); for (i = 80 * 24; i--; ) screen[0][i] = ' '; /* * The first argument to player is a two character string encoding * the file descriptors of the pipe ends. See setup.c for call. * * If we get 'ZZ', then we are replaying an old game, and there * are no pipes to read/write. */ if (argv[1][0] == 'Z') { replaying = 1; gamename = "Iteratum Rog-O-Maticus"; termination = "finis"; logfilename = argv[4]; startreplay (&logfile, logfilename); } else { frogue = fdopen (argv[1][0] - 'a', "r"); trogue = fdopen (argv[1][1] - 'a', "w"); setbuf (trogue, NULL); } /* The second argument to player is the process id of Rogue */ if (argc > 2) rogpid = atoi (argv[2]); /* The third argument is an option list */ if (argc > 3) sscanf (argv[3], "%d,%d,%d,%d,%d,%d,%d,%d", &cheat, ¬erm, &startecho, &nohalf, &emacs, &terse, &transparent, &quitat); /* The fourth argument is the Rogue name */ if (argc > 4) strcpy (roguename, argv[4]); else sprintf (roguename, "Rog-O-Matic %s", RGMVER); /* Now count argument space and assign a global pointer to it */ arglen = 0; for (i=0; i<argc; i++) { register int len = strlen (argv[i]); arglen += len + 1; while (len >= 0) argv[i][len--] = ' '; } parmstr = argv[0]; arglen--; /* If we are in one-line mode, then squirrel away stdout */ if (emacs || terse) { realstdout = fdopen (dup (fileno (stdout)), "w"); freopen ("/dev/null", "w", stdout); } initscr (); crmode (); noecho (); /* Initialize the Curses package */ if (startecho) toggleecho (); /* Start logging? */ clear (); /* Clear the screen */ getrogver (); /* Figure out Rogue version */ if (!replaying) { restoreltm (); /* Get long term memory of version */ startlesson (); /* Start genetic learning */ } /* * Give a hello message */ sprintf (msg, " %s: version %s, genotype %d, quit at %d.", roguename, versionstr, geneid, quitat); if (emacs) { fprintf (realstdout, "%s (%%b)", msg); fflush (realstdout); } else if (terse) { fprintf (realstdout, "%s\n", msg); fflush (realstdout); } else { saynow (msg); } /* * Now that we have the version figured out, we can properly * interpret the screen. Force a redraw by sending a redraw * screen command (^L for old, ^R for new). * * Also identify wands (/), so that we can differentiate * older Rogue 3.6 from Rogue 3.6 with extra magic... */ if (version < RV53A) sendnow ("%c//;", ctrl('l')); else sendnow ("%c;", ctrl('r')); /* * If we are not replaying an old game, we must position the * input after the next form feed, which signals the start of * the level drawing. */ if (!replaying) while ((int) (ch = GETROGUECHAR) != CL_TOK && (int) ch != EOF); /* * Note: If we are replaying, the logfile is now in synch */ getrogue (ill, 2); /* Read the input up to end of first command */ /* Identify all 26 monsters */ if (!replaying) for (ch = 'A'; ch <= 'Z'; ch++) send ("/%c", ch); /* * Signal handling. On an interrupt, Rogomatic goes into transparent * mode and clears what state information it can. This code is styled * after that in "UNIX Programming -- Second Edition" by Brian * Kernigan & Dennis Ritchie. I sure wouldn't have thought of it. */ istat = signal (SIGINT, SIG_IGN); /* save original status */ setjmp (commandtop); /* save stack position */ if (istat != SIG_IGN) signal (SIGINT, onintr); if (interrupted) { saynow ("Interrupt [enter command]:"); interrupted = 0; transparent = 1; } if (transparent) noterm = 0; while (playing) { refresh (); /* If we have any commands to send, send them */ while (resend ()) { if (startingup) showcommand (lastcmd); sendnow (";"); getrogue (ill, 2); } if (startingup) /* All monsters identified */ { versiondep (); /* Do version specific things */ startingup = 0; /* Clear starting flag */ } if (!playing) break; /* In case we died */ /* * No more stored commands, so either get a command from the * user (if we are in transparent mode or the user has typed * something), or let the strategize module try its luck. If * strategize fails we wait for the user to type something. If * there is no user (noterm mode) then use ROGQUIT to signal a * quit command. */ if ((transparent && !singlestep) || (!emacs && charsavail ()) || !strategize()) { ch = (noterm) ? ROGQUIT : getch (); switch (ch) { case '?': givehelp (); break; case '\n': if (terse) { printsnap (realstdout); fflush (realstdout); } else { singlestep = 1; transparent = 1; } break; /* Rogue Command Characters */ case 'H': case 'J': case 'K': case 'L': case 'Y': case 'U': case 'B': case 'N': case 'h': case 'j': case 'k': case 'l': case 'y': case 'u': case 'b': case 'n': case 's': command (T_OTHER, "%c", ch); transparent = 1; break; case 'f': ch = getch (); for (s = "hjklyubnHJKLYUBN"; *s; s++) { if (ch == *s) { if (version < RV53A) command (T_OTHER, "f%c", ch); else command (T_OTHER, "%c", ctrl (ch)); } } transparent = 1; break; case '\f': redrawscreen (); break; case 'm': dumpmonstertable (); break; case 'M': dumpmazedoor (); break; case '>': if (atrow == stairrow && atcol == staircol) command (T_OTHER, ">"); transparent = 1; break; case '<': if (atrow == stairrow && atcol == staircol && have (amulet) != NONE) command (T_OTHER, "<"); transparent = 1; break; case 't': transparent = !transparent; break; case ')': markcycles (DOPRINT); at (row, col); break; case '+': setpsd (DOPRINT); at (row, col); break; case 'A': attempt = (attempt+1) % 5; saynow ("Attempt %d", attempt); break; case 'G': mvprintw (0, 0, "%d: Sr %d Dr %d Re %d Ar %d Ex %d Rn %d Wk %d Fd %d, %d/%d", geneid, k_srch, k_door, k_rest, k_arch, k_exper, k_run, k_wake, k_food, genebest, geneavg); clrtoeol (); at (row, col); refresh (); break; case ':': chicken = !chicken; say (chicken ? "chicken" : "aggressive"); break; case '~': saynow ("Rogomatic version %s, Rogue version %s (%d), quit at %d", RGMVER, versionstr, version, quitat); break; case '[': at (0,0); printw ("%s = %d, %s = %d, %s = %d, %s = %d.", "hitstokill", hitstokill, "goodweapon", goodweapon, "usingarrow", usingarrow, "goodarrow", goodarrow); clrtoeol (); at (row, col); refresh (); break; case '-': saynow (statusline ()); break; case '`': clear (); summary (NULL, '\n'); pauserogue (); break; case '|': clear (); timehistory (NULL, '\n', 0); pauserogue (); break; case 'r': resetinv (); say ("Inventory reset."); break; case 'i': clear (); dumpinv (NULL); pauserogue (); break; case '/': dosnapshot (); break; case '(': clear (); dumpdatabase (); pauserogue (); break; case 'c': cheat = !cheat; say (cheat ? "cheating" : "righteous"); break; case 'd': toggledebug (); break; case 'e': toggleecho (); break; case '!': dumpstuff (); break; case '@': dumpmonster (); break; case '#': dumpwalls (); break; case '%': clear (); havearmor (1, DOPRINT, ANY); pauserogue (); break; case '=': clear (); havering (1, DOPRINT); pauserogue (); break; case '$': clear (); haveweapon (1, DOPRINT); pauserogue (); break; case '^': clear (); havebow (1, DOPRINT); pauserogue (); break; case '{': promptforflags (); break; case '&': saynow ("Object count is %d.", objcount); break; case '*': blinded = !blinded; saynow (blinded ? "blinded" : "sighted"); break; case 'C': cosmic = !cosmic; saynow (cosmic ? "cosmic" : "boring"); break; case 'E': dwait (D_ERROR, "Testing the ERROR trap..."); break; case 'F': dwait (D_FATAL, "Testing the FATAL trap..."); break; case 'R': if (replaying) { positionreplay (); getrogue (ill, 2); if (transparent) singlestep = 1; } else saynow ("Replay position only works in replay mode."); break; case 'S': quitrogue ("saved", Gold, SAVED); playing = 0; break; case 'Q': quitrogue ("user typing quit", Gold, FINISHED); playing = 0; break; case ROGQUIT: dwait (D_ERROR, "Strategize failed, gave up."); quitrogue ("gave up", Gold, SAVED); break; } } else { singlestep = 0; } } if (! replaying) { saveltm (Gold); /* Save new long term memory */ endlesson (); /* End genetic learning */ } /* Print termination messages */ at (23, 0); clrtoeol (); refresh (); endwin (); nocrmode (); noraw (); echo (); if (emacs) { if (*sumline) fprintf (realstdout, " %s", sumline); } else if (terse) { if (*sumline) fprintf (realstdout, "%s\n",sumline); fprintf (realstdout, "%s %s est.\n", gamename, termination); } else { if (*sumline) printf ("%s\n",sumline); printf ("%s %s est.\n", gamename, termination); } /* * Rename log file, if it is open */ if (logging) { char lognam[128]; /* Make up a new log file name */ sprintf (lognam, "%0.4s.%d.%d", ourkiller, MaxLevel, ourscore); /* Close the open file */ toggleecho (); /* Rename the log file */ if (link (ROGUELOG, lognam) == 0) { unlink (ROGUELOG); printf ("Log file left on %s\n", lognam); } else printf ("Log file left on %s\n", ROGUELOG); } exit (0); } /* * onintr: The SIGINT handler. Pass interrupts to main loop, setting * transparent mode. Also send some synchronization characters to Rogue, * and reset some goal variables. */ onintr () { sendnow ("n\033"); /* Tell Rogue we don't want to quit */ if (logging) fflush (fecho); /* Print out everything */ refresh (); /* Clear terminal output */ clearsendqueue (); /* Clear command queue */ setnewgoal (); /* Don't believe ex */ transparent = 1; /* Drop into transprent mode */ interrupted = 1; /* Mark as an interrupt */ noterm = 0; /* Allow commands */ longjmp (commandtop); /* Back to command Process */ } /* * startlesson: Genetic learning algorithm, pick a genotype to * test this game, and set the parameters (or "knobs") accordingly. */ startlesson () { sprintf (genelog, "%s/GeneLog%d", RGMDIR, version); sprintf (genepool, "%s/GenePool%d", RGMDIR, version); sprintf (genelock, "%s/GeneLock%d", RGMDIR, version); srand (0); /* Start random number generator */ critical (); /* Disable interrupts */ /* Serialize access to the gene pool */ if (lock_file (genelock, MAXLOCK)) /* Lock the gene pool */ { if (openlog (genelog) == NULL) /* Open the gene log file */ saynow ("Could not open file %s", genelog); if (! readgenes (genepool)) /* Read the gene pool */ initpool (MAXKNOB, 20); /* Random starting point */ setknobs (&geneid, knob, &genebest, &geneavg); /* Select a genotype */ writegenes (genepool); /* Write out the gene pool */ closelog (); /* Close the gene log file */ unlock_file (genelock); /* Unlock the gene pool */ } else fprintf (stderr, "Cannot lock gene pool to read '%s'\n", genepool); uncritical (); /* Reenable interrupts */ /* Cache the parameters for easier use */ k_srch = knob[K_SRCH]; k_door = knob[K_DOOR]; k_rest = knob[K_REST]; k_arch = knob[K_ARCH]; k_exper = knob[K_EXPER]; k_run = knob[K_RUN]; k_wake = knob[K_WAKE]; k_food = knob[K_FOOD]; } /* * endlesson: if killed, total winner, or quit for scoreboard, * evaluate the performance of this genotype and save in genepool. */ endlesson () { if (geneid > 0 && (stlmatch (termination, "perditus") || stlmatch (termination, "victorius") || stlmatch (termination, "callidus"))) { critical (); /* Disable interrupts */ if (lock_file (genelock, MAXLOCK)) /* Lock the score file */ { openlog (genelog); /* Open the gene log file */ if (readgenes (genepool)) /* Read the gene pool */ { evalknobs (geneid,Gold,Level); /* Add the trial to the pool */ writegenes (genepool); } /* Write out the gene pool */ closelog (); unlock_file (genelock); /* Disable interrupts */ } else fprintf (stderr, "Cannot lock gene pool to evaluate '%s'\n", genepool); uncritical (); /* Re-enable interrupts */ } }