LIFE - Fancy new version (part 1 of 4)

David I. Bell dbell at daisy.UUCP
Sun Feb 3 14:48:20 AEST 1985


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 '<gththtuktntj>' defines
Xa macro named 'g' which causes a glider to be inserted at the current cursor
Xposition every time you type '<ESC>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 <born> <live>' line mode command.  The <born> string lists
Xthose counts of neighbors which are required for a new cell to be born.  The
X<live> 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                <cmd>		Both arguments defaulted.
X         <arg1> <cmd>		First argument given, second is defaulted.
X<arg1> , <arg2> <cmd>		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 <arg1> cells
X.	move right <arg1> cells
Xh	move left <arg1> cells
Xl	move right <arg1> cells
Xk	move up <arg1> cells
Xj	move down <arg1> cells
Xy	move upper left <arg1> cells
Xu	move upper right <arg1> cells
Xb	move lower left <arg1> cells
Xn	move lower right <arg1> 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 <arg1> 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 <arg1> cells and move cursor right
XO	insert <arg1> cells and move cursor right
Xx	kill <arg1> 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<sel>	delete cells described by <sel>
Xp	place last deleted object at current location
Xf<sel>	flip cells left-to-right as described by <sel>
Xr<sel>	rotate cells 90 degrees clockwise as described by <sel>
Xm<sel>	mark (select) cells as described by <sel>
XM	remove all marks (selections)
X
X
X	--- LOOP, VARIABLE, AND MACRO COMMANDS ---
X
X<	begin loop which executes from <arg1> to <arg2> times (if <arg1> given)
X<<ch>	begin definition of macro named <ch> (if <arg1> not given)
X>	end loop or macro definition
XESC<ch>	execute a macro command named <ch>
X+<ch>	increment the value of the single-character variable <ch> by arg1
X
X
X	--- MISCELLANEOUS COMMANDS ---
X
Xg	compute <arg1> generations (or stop if running)
XG	compute infinite generations
Xz	set generation number to <arg1> (default zero)
X!	ignore characters until end of line
X#	ignore character until end of line
X:<line>	execute a line mode command
X;<line>	execute a line mode command
X
X
XArguments specified above as <arg1> and <arg2> can be any of the following:
X$<var>	value of variable <var>, where <var> is a lower or upper case letter
X(expr)	an arithmetic expression containing constants, variables, or operators
X%	current loop counter value
X<num>	explicit numeric value
X
X
XThose commands above referencing <sel> 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 <stdio.h>
X#include <signal.h>
X#include <setjmp.h>
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



More information about the Comp.sources.unix mailing list