Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/17/84 chuqui version 1.7 9/23/84; site nsc.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!whuxl!whuxlm!akgua!gatech!nsc!chongo From: chongo@nsc.UUCP (Landon Noll) Newsgroups: net.sources.games Subject: Reporting for DBELL - LIFE (1 of 4) Message-ID: <2591@nsc.UUCP> Date: Fri, 12-Apr-85 05:11:41 EST Article-I.D.: nsc.2591 Posted: Fri Apr 12 05:11:41 1985 Date-Received: Sat, 13-Apr-85 06:38:56 EST Distribution: net Organization: Rational Swamiconductor, Sanivale Lines: 668 In net.sources: I am reposting DBell's DPY sources in responce to all the folks who needed them for his LIFE and WAR progs. DBell is no longer on the net (in fact in a few days he will no longer be in this hemisphere) otherwise he would have done this himself. In net.sources.games: I am reposting DBell's LIFE sources complete with the changes for the new DPY. Both LIFE and WAR (which was posted by DBell not long ago) require the use of DPY so be sure and GRAB IT FROM net.sources NOW!!! ---------------------begin DBell's comments------------------------------- This article (and the next 2) contain sources to my version of a program which plays the mathematical game of life. Its features include: * An 'infinite' sized board * Display routines capable of showing large objects * Editing of multiple life objects at once * Provides macros, loops, and variables * Allows rule changing to create alternate life universes * Supports libraries of life objects * Friendly storage format for objects This program requires my 'dpy' module for screen handling. That module was posted very recently by me. If necessary, I can mail copies to you. Part 4 of this posting contains a library of life objects which I have seen or created, along with comments for each one. I am very interested in receiving other interesting life objects to add to the library. Thanks!! - nsc!daisy!dbell - #---Cut here and place in it's own directory, then feed to Bourne shell--- # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # This archive contains: # README (1117 chars) # life.doc (21688 chars) # makefile (357 chars) # life.h (7899 chars) # echo x - README sed -e 's/^X//' > "README" << '//E*O*F README//' XThis is a version of life which was written to run under 4.2 BSD UNIX Xrunning on a VAX 750. If you are not running this configuration, you Xwill probably have to make modifications. The only Berkeley specific Xfeature used (that I can recall) is the use of the FIONREAD ioctl. But Xthere are many int/long mismatches (some of us on VAXes are rather lax). X XThis program requires the use of my "dpy" library module for its screen Xupdating. This module was recently posted to net.sources. If you did Xnot receive that module, I can send it to you privately if necessary. XChanging the life program to use curses would be possible, but painful. X XA program like this can have almost an infinite number of features. XThere are still things I would like to include in it, but enough major Xthings are implemented to make it very useful. Suggestions for new Xfeatures or changes are welcome, as are the (to be expected) bug fixes. X XOnce again, sorry about the the documentation. Life.doc should be formatted, Xbut the life program would probably have waited forever until I did that. XEnjoy! X David I. Bell X nsc!daisy!dbell //E*O*F README// echo x - life.doc sed -e 's/^X//' > "life.doc" << '//E*O*F life.doc//' X The Game of LIFE X program by David I. Bell X X XIf you do not know what the game of life is, see the appendix at the end. XExcept in that appendix, the remainder of this document assumes that you Xknow the rules and terms of the game. X XThis program plays the game of life on a practically infinite board by using Xsparse matrices. Therefore there is no hard limit on the size of a life Xobject except for its memory requirements. The memory requirements depend Xon the number of live cells of the object, and not on their locality. The Xtime needed to compute one generation also depends on the number of live cells. XThe speed is such that on a VAX 750, an object with 2000 live cells takes Xabout 1 second of run time per generation. Typical objects run much faster. X XLife programs are limited by the size of their display. On special kinds of Xterminals, very large objects can be seen directly. However, this program Xis designed to run on the vast majority of terminals, most of which have Xdisplays which are limited to showing 24 by 80 characters. The program gets Xaround this limitation by doing two things. Firstly, the standard display Xcan show any portion of an object. As the cursor is moved around the object, Xthe view scrolls as necessary in any direction so that the location of the Xcursor remains visible. Thus you can move to any point in the object and Xsee what is nearby. Secondly, the display can be scaled by any amount up Xto 1000. This means that each position on the screen can represent an area Xwhich is up to 1000 by 1000 cells of the object. Obviously, information must Xbe lost when this is done. So the program displays the number of live cells Xin each region, from 1 to 9 (or * for 10 or more). In practice this display Xis perfectly adequate for seeing what is happening. Once you have moved the Xcursor to an interesting location, you can reduce the scale to see what is Xactually there in detail. The 's' command sets the viewing scale as desired, Xand 'S' sets auto-scale mode, which keeps an object visible as it grows. XBoth commands recenter the view around the current cursor position. When Xyou are trying to count the number of cells between two parts of an object, Xthe ';grid' command is useful. It changes the display of dead cells from Xblanks to another character (typically periods). X XThis program can simulaneously handle more than one object. Each object is Xdistinct and has its own name, and you can move between objects to select the Xone currently being edited. The ';create name' command creates a new object, Xand the ';edit name' switches between objects (defaulting to the previously Xedited object if no name is given). Cells can be copied or moved between Xobjects. This allows you to make backups of an object, compare two objects, Xor split up and edit the parts of a single object. The ';copy' command Xcopies the current object to another object. The ';insert' command inserts Xanother object into the current object. This is done in such as way that the Xtwo object's cursor locations match. The ';list' command will display data Xabout all objects whose names do not begin with a period (adding '-a' to the Xcommand will show even those). Objects with names beginning with '..' are Xreserved, and have special uses like temporary object manipulation, the saving Xof deleted objects, and for implementing undo. X XMost commands (and the viewpoint), are based on the current cursor location. XTo change the viewpoint, or to point at a location in the object that you Xwish to modify, you must move the cursor around in the object. To do this, Xyou can use some single character commands. The directions for movement Xare like in rogue, so that for example, 'h' moves left, 'j' moves down, 'y' Xmoves to the upper left, and so on. The commands are multiplied by the scale Xfactor, so that you can move about in large objects easily. In addition, Xthey accept an optional preceeding numeric argument, which multiplies their Xmovement by the given amount. Also, space (or period) moves to the right, Xwhile return moves down to the next line and back to the column of the pointer. XThe pointer is simply a location that is remembered in an object, and only a Xfew commands use it. The '@' command sets the pointer to the cursor location. XThe movement commands when capitalized perform a shift of both the cursor Xand the viewing region together by 1/4 of the screen size. This is useful Xto shift the view slightly to see an object on the edge better. X XThe simplest commands for changing an object are 'o', 'x', 't', and 'i'. XThe 'o' command creates a live cell and moves the cursor to the right. XThe 'x' command creates a dead cell and moves the cursor to the right. XBoth of these commands can accept a numeric argument which replicates their Xaction by the given amount (as an example, the command string '25o' creates Xa row of 25 live cells). The 't' command toggles the current cell from Xdead to alive, or from alive to dead, without moving the cursor. The 'i' Xcommand sets a mode in which some of the movement commands described in Xthe previous paragraph automatically insert or delete cells. This makes it Xeasy to create lines of cells in any direction. X XA very useful feature is the use of 'selections'. You can select any group Xof cells of an object, and handle them specially, leaving the rest of the Xcells unchanged. For example, you can save the selected cells as a different Xobject, or can move them around, or can delete them. Selected cells appear Xdifferently in the display (as hash marks), so that you can recognize which Xcells are selected. Selections are set based on where the cursor is. You Xcan select all the cells in any quadrant or half-plane around the cursor. XYou can also select all the cells which are king-wise connected to your cursor Xlocation. Each selection command adds to the set of selected cells. The 'M' Xcommand removes all current selections so you can start a new set. There are Xseveral commands which act on a selection in interesting ways. For example, Xif the cursor is on a glider, the command 'dd' will delete just the glider. XThe commands which flip or rotate selections do so with respect to the current Xcursor location. X XTo compute generations, you use the 'g' or 'G' commands. The 'g' command Xcomputes a single generation of the current object, or as many generations Xas you specified in its preceeding argument. The 'G' command simply means Xrun for an infinite number of generations. If the object dies or becomes Xstable, computations automatically stop. However, loops of period 2 or Xgreater are not detected. While generations are being computed, you can use Xthe movement or scaling commands to wander around the object. But attempts Xto change the object while it is running will be rejected. If you wish to Xwait until the indicated computations are complete before the next command is Xexecuted, use the ';wait' command (this is often used inside of a command Xmacro or loop). To stop the computations for an object, use the 'g' command Xagain to reset the count to zero. Normally each generation will be displayed. XTo speed up the computations when you don't want to see every generation, use Xthe ';frequency n' command to set how often the screen is updated. X XThis program can read commands from a file. It can also save objects out to Xa file. When writing an object to a file, what is actually written is a Xsequence of commands which regenerates the object. The choice of commands is Xsuch that for small objects, the commands look like a picture of the object. XThus, the object is written using the commands '.' (to move right), 'o' (to Xinsert cells), and '\n' (to move to the next line). (Periods are used instead Xof spaces so that you can count the spaces between live cells easily. However, Xspaces or tabs could also be used and will act reasonably.) Thus for small Xobjects, you can create a picture of an object in an editor, and then the Xobject can be read in by the life program. Lines beginning with '!' or '#' Xare ignored, so you can comment your objects. When writing out an object, if Xit is too large to be typed to your screen or edited easily, the output will Xcontain numeric arguments as necessary in order to compress the resulting file. XThe command ';write filename' is used to save an object. X XWhen reading an input file, the program looks for six different file names in Xsequence. It starts by looking for the file name as given. Then it looks for Xthe name with an '.l' extension appended. Then, if the environment variable XLIFELIB is defined, it looks in that directory for the file, and then for the Xfile with the '.l' extension. Finally, it looks in /usr/games/lib/life for Xthe file, and then for the file with the '.l' extension. Thus there is a Xstandard library of interesting life objects, and you can create your own Xlife library. The ';read filename' command reads back a command file. In Xaddition, when the life program is started, you can specify a filename on the Xcommand line which will be read before any commands are read from the terminal. XThis is useful when you want to immediately read a life object from a library. X XCommand loops and macros can be defined using the '<' and '>' commands. If Xa numeric argument is specified, a loop is being defined. If no argument is Xgiven, a macro is being defined. While defining a macro or loop, the commands Xyou type are executed normally, so that you can see how the definition will Xexecute. This is useful when you define a macro to create an object, since Xyou can easily see how to create the object. Loops and macros can contain Xboth line mode and character mode style commands. While you are defining a Xloop or macro, the status line will indicate this and give the current depth Xof loop or macro nesting. X XWhen defining a macro, the next letter after the '<' is the macro name being Xdefined (the name must be a lower case letter). All of the commands between Xthe '<' and the '>' (except for the macro name character) are saved. Once a Xmacro has been defined, it is used by typing the ESCAPE character followed by Xthe macro letter. As an example, the command string '' defines Xa macro named 'g' which causes a glider to be inserted at the current cursor Xposition every time you type 'g'. The ';dumpmacros file' command writes Xout the definitions of all macros so that you can read them back in later. X XIf a loop is being defined, the loop is executed the number of times specifed Xby the argument to '<'. If two arguments are specifed, the loop runs from Xthe first to the second argument (backwards if the second argument is less Xthan the first argument). The value of the loop counter is available in the Xloop itself by using '%' as you would a number. As an example of a loop, Xthe command string '3,7<%o >' inserts five strings of cells spaced apart by Xone cell, where the first string contains three cells, and the last string Xcontains seven cells. When nesting loops, supplying an argument to '%' can Xobtain the loop counter values for the outside loops while in the inner loop. XThus, '2%' obtains the loop value for the next-to-innermost loop level. X XWhile defining a loop or macro, you can request user intervention by using Xthe ';ttyinput' command. This will suspend the execution of the loop or macro Xand notify the user that input is desired by displaying 'tty-input' in the Xstatus line. The user can then execute any commands of his choice. When he Xis ready to proceed, he uses the ';endinput' (or a control-D) command to Xcontinue execution where it had paused. Different commands can be given by Xthe user each time the loop or macro asks for terminal input. If the command X';ttyinput -c' is used, terminal commands will only be asked for if there Xis any terminal input available to be read. X XWhile a macro or loop is executing, there is no screen updating. Thus a Xcomplicated command sequence can be executed without letting the user see Xwhat is occuring until it is finished. However, if you wish to update the Xscreen in the middle of execution, the ';updateview' command will do this. XCommands from the terminal automatically do an update whenever no more Xinput is available. X XThere is a set of variables which you can use to influence your commands. XThey come in two kinds. The first kind is the single-character variable. XThere are 52 of these variables (the lower and upper case letters). These Xvariables are used with a leading dollar sign. Any command which accepts an Xargument can accept '$c' to mean the value of variable 'c'. These variables Xcan be set using the ';set' command, which takes a variable name followed by Xan expression. (As a shortcut, the '+c' command increments variable c.) XThe initial values of all variables are zero. These variables are useful Xinside a macro in order to execute a command string over and over again with Xonly small differences each time (such as to vary the placement of two objects Xwith respect to each other). As an example of the use of a single-character Xvariable, the command string '$al' moves the cursor to the right by the number Xof cells given by the value of variable 'a'. X XThe other kind of variables are the multi-character variables. These are Xa fixed set of names, and their values are specific things, and cannot be Xchanged. For example, the 'cx' variable returns the x coordinate of the Xcurrent cursor position. You can see the complete set of variables using Xthe ';variables' command. Since the parser must be able to distinguish Xvariable names from command letters, you cannot use them without surrounding Xthem with a pair of parenthesis. The parenthesis can actually contain any Xexpression, including single-character variables. When inside parenthesis Xor as part of a line mode command, variables do not need the leading '$'. XAs an example of multi-character variables used with an expression, the Xcommand string '((vmaxx-vminx)/2)l' shifts the cursor to the right by an Xamount equal to half of the screen width. X XThe rules of life can be changed to some degree. This allows you to explore Xalternative life universes. You can specify how many live cells are required Xfor a cell to be born, or to stay alive. However, you cannot change the Xneighborhood used for counting live cells (the program always counts all of Xthe eight neighboring cells). To change the cells needed for birth or death, Xuse the ';rules ' line mode command. The string lists Xthose counts of neighbors which are required for a new cell to be born. The X string lists those counts of neighbors which are required for an Xexisting cell to stay alive. The standard rules are thus described by the Xcommand ';rules 3 23'. X XThere are two kinds of commands to life. Line mode commands begin with a Xcolon or semi-colon character, and are terminated by an end of line character. XMany of these have already been described above. Use the ';help' command to Xlist all of the line mode commands. They are reasonably self-documenting. XHere are some of the remaining useful line mode commands. The ';quit' command Xexits the program. The ';zero' command clears all cells of an object and Xresets the scaling factor and cursor position. The ';copyselection name' and X';moveselection name' commands copy or move selected cells to another object. XFinally, the ';undo' command will undo the most recent change to the current Xobject. This can undo deletions, insertions, and running of generations, Xamong other things. But you get only one level of backup (A related backup Xfeature is the 'p' command, which will reinsert the last deleted object to Xthe current cursor location.) X XCharacter mode commands are executed immediately when complete. Until it is Xcomplete, it can be edited using the normal erase and kill characters. The Xcharacter mode commands can be preceeded by zero, one, or two arguments. XThese arguments are generally used as a count of how many times the command Xis to be executed. Missing arguments are defaulted to 1 (with the exceptions Xnoted in the tables below). If two arguments are specified, they are separated Xby a comma. So a character mode command can take one of the following forms: X X Both arguments defaulted. X First argument given, second is defaulted. X , Both arguments given. X XThe following table specifies the character mode commands, arranged in Xuseful catagories. Many of these have been described in detail above. X X X --- MOVEMENT COMMANDS --- X XSPACE move right cells X. move right cells Xh move left cells Xl move right cells Xk move up cells Xj move down cells Xy move upper left cells Xu move upper right cells Xb move lower left cells Xn move lower right cells XLF move to next "line" XTAB move to next "tab stop" X@ remember current location as the pointer Xc return to location of the pointer X/ move cursor to next object X X X --- SCREEN COMMANDS --- X Xs set viewing scale to and center view (default current scale) XS turn on auto-scaling and center view XH shift view left by width/4 XL shift view right by width/4 XK shift view up by height/4 XJ shift view down by height/4 XY shift view left and up XU shift view right and up XB shift view left and down XN shift view right and down X^L refresh the screen X X X --- SINGLE CELL COMMANDS -- X Xo insert cells and move cursor right XO insert cells and move cursor right Xx kill cells and move cursor right Xt toggle cell at current location Xi toggle movement mode to move, insert, or delete X X X --- MULTIPLE CELL COMMANDS --- X Xd delete cells described by Xp place last deleted object at current location Xf flip cells left-to-right as described by Xr rotate cells 90 degrees clockwise as described by Xm mark (select) cells as described by XM remove all marks (selections) X X X --- LOOP, VARIABLE, AND MACRO COMMANDS --- X X< begin loop which executes from to times (if given) X< begin definition of macro named (if not given) X> end loop or macro definition XESC execute a macro command named X+ increment the value of the single-character variable by arg1 X X X --- MISCELLANEOUS COMMANDS --- X Xg compute generations (or stop if running) XG compute infinite generations Xz set generation number to (default zero) X! ignore characters until end of line X# ignore character until end of line X: execute a line mode command X; execute a line mode command X X XArguments specified above as and can be any of the following: X$ value of variable , where is a lower or upper case letter X(expr) an arithmetic expression containing constants, variables, or operators X% current loop counter value X explicit numeric value X X XThose commands above referencing take one of the following letters. XThe command affects only those cells selected. As a special case, repeating Xthe command letter is equivilant to selecting 'o' (the connected object). XExample: 'dd' deletes the connected object the cursor is on. Xa all cells Xc cell at current location Xo cells in the king-wise connected object at current location Xh cells to left of cursor Xl cells to right of cursor Xk cells above cursor Xj cells below cursor Xb cells below and left of cursor Xn cells below and right of cursor Xu cells above and right of cursor Xy cells above and left of cursor Xp cells in rectangle determined by pointer and cursor Xm cells which are marked Xv cells visible in window X X X APPENDIX X XThis is a short introduction to life. Life is played on an infinitely large Xboard divided into squares. Each square is called a cell. Each cell can be Xeither dead or alive. Dead cells are seen as blanks, whereas live cells are Xseen as non-blanks. You begin to play by choosing some arbitrary set of Xlive and dead cells. This configuration is called generation 0. There is Xa set of rules which transforms this set of cells into another set of cells, Xcalled generation 1. These same rules are then reapplied to generation 1 to Xproduce generation 2. This process continues indefinitely. The 'purpose' of Xthe game is to find starting patterns such that 'interesting things' result. X XThe rules which are applied are as follows. Take any cell of a generation, Xand call it the current cell. Consider the eight cells immediately adjacent Xto the current cell. Count the number of these eight cells which are alive. XIf the current cell is dead and the count is 3, then the current cell changes Xto a live cell in the next generation. If the current cell is alive and the Xcount is NOT 2 or 3, then the current cell changes to a dead cell in the next Xgeneration. Otherwise the cell remains unchanged in the next generation. XThis rule is applied to every cell of a generation SIMULTANEOUSLY. Thus to Xrephrase, 3 live neighbors causes a new cell to be born, whereas 2 or 3 live Xneighbors keeps a cell alive. X XTo see how these rules work in practice, run the program and start with some Xnumber of live cells in some arrangement, and watch the generations change. XIf you can predict what the changes will be, then you understand the rules. XThe following are some objects to try, along with some descriptive names. XWarning: the last example gets complicated!! X X O O O O O OO X O O OO OO OO O OO X O O O O O OOO O X Xdoomed blinker beehive block traffic lights glider r-pentomino //E*O*F life.doc// echo x - makefile sed -e 's/^X//' > "makefile" << '//E*O*F makefile//' X# @(#)makefile 1.3 1/31/85 X# @(#) X XCFLAGS = -O XCC = cc X XCFILES = alloc.c cell.c cmd.c cmdl.c debug.c gen.c io.c main.c mark.c\ X object.c scan.c vars.c view.c X XOFILES = alloc.o cell.o cmd.o cmdl.o debug.o gen.o io.o main.o mark.o\ X object.o scan.o vars.o view.o X Xlife: ${OFILES} makefile X ${CC} ${CFLAGS} -o life ${OFILES} -ldpy -ltermlib X X${OFILES}: life.h //E*O*F makefile// echo x - life.h sed -e 's/^X//' > "life.h" << '//E*O*F life.h//' X/* X * @(#)life.h 1.9 1/31/85 X * @(#)Copyright (C) 1985 by D Bell X */ X X#include X#include X#include X X#define LIFELIB "/usr/games/lib/life" /* directory for general life library */ X#define LIFEVAR "LIFELIB" /* environment name for user's lib */ X#define ALLOCOBJ 10 /* how many new objects to allocate */ X#define ALLOCROW 50 /* how many new rows to allocate */ X#define ALLOCCELL 500 /* how many new cells to allocate */ X#define FILESIZE (1024*4) /* file buffer size */ X#define LOOPSIZE 5000 /* characters in command loops */ X#define SCAN_SIZE 100 /* maximum command length */ X#define MAXINPUT 20 /* maximum nesting of command inputs */ X#define MAXNAME 32 /* maximum object name size */ X#define MAXSCALE 1000 /* maximum scale factor */ X#define WRITEROWS 100 /* default maximum rows for writing */ X#define WRITECOLS 79 /* default maximum cols for writing */ X#define ESC '\033' /* escape character */ X#define INFINITY 0x7fffffff /* infinite value */ X#define LIFE 9 /* live cell value in neighbor count */ X#define STDIN 0 /* standard input */ X#define STDOUT 1 /* standard output */ X#define STDERR 2 /* standard error */ X#define RELATIVE 0 /* do object additions relatively */ X#define ABSOLUTE 1 /* do object additions absolutely */ X#define M_MOVE 0 /* movement mode */ X#define M_INSERT 1 /* insertion mode */ X#define M_DELETE 2 /* deletion mode */ X#define MARK_ANY 0x1 /* mark always set */ X#define MARK_USR 0x2 /* marked due to user specification */ X#define MARK_CMD 0x4 /* marked only for current command */ X#define MARK_SRC 0x8 /* marked by searching */ X#define MARK_SEE (MARK_USR) /* marks seen by user */ X#define MARK_ALL (MARK_ANY|MARK_USR|MARK_CMD|MARK_SRC) /* all non-null marks */ X#define INP_TTY 0 /* input is terminal */ X#define INP_FILE 1 /* input is file */ X#define INP_LOOP 2 /* input is command loop */ X#define INP_MACRO 3 /* input is command macro */ X#define SCAN_ABORT 1 /* setjmp value for aborted command */ X#define SCAN_EDIT 2 /* setjmp value for edited command */ X#define SCAN_EOF 3 /* setjmp value for no command data */ X#define crow curobj->o_currow /* current row of current object */ X#define ccol curobj->o_curcol /* current column of current object */ X#define cmark curobj->o_mark /* current mark being applied */ X#define cscale curobj->o_scale /* current scale of current object */ X#define prow curobj->o_prow /* current pointer row */ X#define pcol curobj->o_pcol /* current pointer column */ X X/* macro to detect reserved names */ X#define BADNAME(s) ((s[0] == '.') && ((s[1] == '\0') || (s[1] == '.'))) X X Xstruct object { /* structure for each object */ X struct row *o_firstrow; /* first row */ X struct row *o_lastrow; /* last row */ X struct object *o_next; /* next object */ X long o_count; /* number of live cells */ X long o_born; /* number of cells born */ X long o_died; /* number of cells died */ X long o_currow; /* current row */ X long o_curcol; /* current column */ X long o_minrow; /* minimum row seen in window */ X long o_maxrow; /* maximum row seen in window */ X long o_mincol; /* minimum column seen in window */ X long o_maxcol; /* maximum column seen in window */ X long o_prow; /* currently pointed at row */ X long o_pcol; /* currently pointed at column */ X long o_gen; /* current generation */ X short o_scale; /* current scaling factor for view */ X char o_autoscale; /* doing autoscaling */ X char o_mark; /* mark value for new cells */ X char o_reserved; /* reserved object */ X char o_lock; /* locked against computing gens */ X char o_name[MAXNAME+1]; /* name of object */ X}; X Xstruct row { /* structure for each row of cells */ X struct row *r_next; /* link to next row */ X struct cell *r_firstcell; /* link to first cell */ X struct cell *r_lastcell; /* link to last real cell */ X long r_row; /* row number */ X long r_count; /* number of cells in this row */ X}; X Xstruct cell { /* structure for each cell */ X struct cell *c_next; /* link to next cell */ X long c_col; /* column number */ X int c_marks; /* marking values for cell */ X}; X X X/* X * The following structure holds all data necessary for processing X * characters from some source. X */ Xstruct input { X int (*i_getchar)(); /* routine to read next character */ X int (*i_term)(); /* routine to terminate reading */ X char *i_begptr; /* beginning of command data */ X char *i_endptr; /* end of command data */ X char *i_curptr; /* current character */ X char i_type; /* type of input */ X /* following data for file reading only */ X short i_file; /* file descriptor */ X struct object *i_obj; /* object to restore on reentry */ X long i_row; /* row to restore */ X long i_col; /* column to restore */ X long i_prow; /* pointer row to restore */ X long i_pcol; /* pointer column to restore */ X /* following data for loop or macro reading only */ X long i_curval; /* current iteration value */ X long i_endval; /* ending iteration value */ X int i_first; /* processing new chars */ X char i_macro; /* macro being defined */ X}; X X Xstruct macro { /* structure for command macros */ X char *m_begptr; /* beginning of data (NULL if none) */ X char *m_endptr; /* end of data */ X}; X X Xstruct object *objects; /* list of active objects */ Xstruct object *curobj; /* currently selected object */ Xstruct object *prevobj; /* previously selected object */ Xstruct object *mainobject; /* the main object */ Xstruct object *deleteobject; /* object last deleted */ Xstruct object *backupobject; /* backup object */ Xstruct object *tempobject; /* temporary object */ Xstruct object *freeobjects; /* list of free objects */ Xstruct object *newobjects; /* top of new object allocation */ Xstruct object *endobjects; /* end of new objects */ X Xstruct row *freerows; /* list of free row structures */ Xstruct row *newrows; /* top of new row allocation */ Xstruct row *endrows; /* end of new rows */ Xstruct row *termrow; /* terminus row */ Xstruct row initrow; /* row to initialize list */ X Xstruct cell *freecells; /* list of free cell structures */ Xstruct cell *newcells; /* top of new cell allocation */ Xstruct cell *endcells; /* end of new cells */ Xstruct cell *termcell; /* terminus cell */ Xstruct cell initcell; /* cell to initialize list */ X Xstruct input *curinput; /* current input being read from */ X Xint seecount; /* number of cells we can see */ Xint frequency; /* typeout frequency */ Xint freqcount; /* current count */ Xint genleft; /* generations left before stopping */ Xshort rowradius; /* half of length of screen */ Xshort colradius; /* half of width of screen */ Xchar reserve; /* reserved object names allowed */ Xchar dowait; /* must wait for input */ Xchar update; /* status or position needs updating */ Xchar redraw; /* whole screen needs updating */ Xchar interact; /* still being interactive */ Xchar stop; /* user wants to stop current action */ Xchar mode; /* mode of movement */ Xchar gridchar; /* character to use for grid */ Xchar *errorstring; /* error string to type */ Xchar *userlib; /* user's life library if any */ Xjmp_buf ttyjmp; /* jump buffer */ Xstruct input inputs[MAXINPUT]; /* list of input environments */ Xstruct macro macros[26]; /* list of macros */ Xchar stringbuf[FILESIZE]; /* characters for string value */ Xchar rulestring[20]; /* string describing rules */ X Xextern char rules[]; /* life rules */ X Xstruct object *allocobject(); /* allocate new object */ Xstruct object *findobject(); /* find object with certain name */ Xstruct object *getobject(); /* get new object with certain name */ Xstruct row *allocrow(); /* allocate new row */ Xstruct row *findrow(); /* find a row */ Xstruct row *getrow(); /* get a new row */ Xstruct row *computerow(); /* compute a new row */ Xstruct cell *alloccell(); /* allocate new cell */ Xstruct cell *findcell(); /* find a cell */ X Xchar *readstring(); /* read input */ //E*O*F life.h// echo done -- no comment is a comment.