DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T l

⟦539347dca⟧ TextFile

    Length: 21688 (0x54b8)
    Types: TextFile
    Names: »life.doc«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Life/life.doc« 

TextFile

			The Game of LIFE
			program by David I. Bell


If you do not know what the game of life is, see the appendix at the end.
Except in that appendix, the remainder of this document assumes that you
know the rules and terms of the game.

This program plays the game of life on a practically infinite board by using
sparse matrices.  Therefore there is no hard limit on the size of a life
object except for its memory requirements.  The memory requirements depend
on the number of live cells of the object, and not on their locality.  The
time needed to compute one generation also depends on the number of live cells.
The speed is such that on a VAX 750, an object with 2000 live cells takes
about 1 second of run time per generation.  Typical objects run much faster.

Life programs are limited by the size of their display.  On special kinds of
terminals, very large objects can be seen directly.  However, this program
is designed to run on the vast majority of terminals, most of which have
displays which are limited to showing 24 by 80 characters.  The program gets
around this limitation by doing two things.  Firstly, the standard display
can show any portion of an object.  As the cursor is moved around the object,
the view scrolls as necessary in any direction so that the location of the
cursor remains visible.  Thus you can move to any point in the object and
see what is nearby.  Secondly, the display can be scaled by any amount up
to 1000.  This means that each position on the screen can represent an area
which is up to 1000 by 1000 cells of the object.  Obviously, information must
be lost when this is done.  So the program displays the number of live cells
in each region, from 1 to 9 (or * for 10 or more).  In practice this display
is perfectly adequate for seeing what is happening.  Once you have moved the
cursor to an interesting location, you can reduce the scale to see what is
actually there in detail.  The 's' command sets the viewing scale as desired,
and 'S' sets auto-scale mode, which keeps an object visible as it grows.
Both commands recenter the view around the current cursor position.  When
you are trying to count the number of cells between two parts of an object,
the ';grid' command is useful.  It changes the display of dead cells from
blanks to another character (typically periods).

This program can simulaneously handle more than one object.  Each object is
distinct and has its own name, and you can move between objects to select the
one currently being edited.  The ';create name' command creates a new object,
and the ';edit name' switches between objects (defaulting to the previously
edited object if no name is given).  Cells can be copied or moved between
objects.  This allows you to make backups of an object, compare two objects,
or split up and edit the parts of a single object.  The ';copy' command
copies the current object to another object.  The ';insert' command inserts
another object into the current object.  This is done in such as way that the
two object's cursor locations match.  The ';list' command will display data
about all objects whose names do not begin with a period (adding '-a' to the
command will show even those).  Objects with names beginning with '..' are
reserved, and have special uses like temporary object manipulation, the saving
of deleted objects, and for implementing undo.

Most commands (and the viewpoint), are based on the current cursor location.
To change the viewpoint, or to point at a location in the object that you
wish to modify, you must move the cursor around in the object.  To do this,
you can use some single character commands.  The directions for movement
are like in rogue, so that for example, 'h' moves left, 'j' moves down, 'y'
moves to the upper left, and so on.  The commands are multiplied by the scale
factor, so that you can move about in large objects easily.  In addition,
they accept an optional preceeding numeric argument, which multiplies their
movement by the given amount.  Also, space (or period) moves to the right,
while return moves down to the next line and back to the column of the pointer.
The pointer is simply a location that is remembered in an object, and only a
few commands use it.  The '@' command sets the pointer to the cursor location.
The movement commands when capitalized perform a shift of both the cursor
and the viewing region together by 1/4 of the screen size.  This is useful
to shift the view slightly to see an object on the edge better.

The simplest commands for changing an object are 'o', 'x', 't', and 'i'.
The 'o' command creates a live cell and moves the cursor to the right.
The 'x' command creates a dead cell and moves the cursor to the right.
Both of these commands can accept a numeric argument which replicates their
action by the given amount (as an example, the command string '25o' creates
a row of 25 live cells).  The 't' command toggles the current cell from
dead to alive, or from alive to dead, without moving the cursor.  The 'i'
command sets a mode in which some of the movement commands described in
the previous paragraph automatically insert or delete cells.  This makes it
easy to create lines of cells in any direction.

A very useful feature is the use of 'selections'.  You can select any group
of cells of an object, and handle them specially, leaving the rest of the
cells unchanged.  For example, you can save the selected cells as a different
object, or can move them around, or can delete them.  Selected cells appear
differently in the display (as hash marks), so that you can recognize which
cells are selected.  Selections are set based on where the cursor is.  You
can select all the cells in any quadrant or half-plane around the cursor.
You can also select all the cells which are king-wise connected to your cursor
location.  Each selection command adds to the set of selected cells.  The 'M'
command removes all current selections so you can start a new set.  There are
several commands which act on a selection in interesting ways.  For example,
if the cursor is on a glider, the command 'dd' will delete just the glider.
The commands which flip or rotate selections do so with respect to the current
cursor location.

To compute generations, you use the 'g' or 'G' commands.   The 'g' command
computes a single generation of the current object, or as many generations
as you specified in its preceeding argument.  The 'G' command simply means
run for an infinite number of generations.  If the object dies or becomes
stable, computations automatically stop.  However, loops of period 2 or
greater are not detected.  While generations are being computed, you can use
the movement or scaling commands to wander around the object.  But attempts
to change the object while it is running will be rejected.  If you wish to
wait until the indicated computations are complete before the next command is
executed, use the ';wait' command (this is often used inside of a command
macro or loop).  To stop the computations for an object, use the 'g' command
again to reset the count to zero.  Normally each generation will be displayed.
To speed up the computations when you don't want to see every generation, use
the ';frequency n' command to set how often the screen is updated.

This program can read commands from a file.  It can also save objects out to
a file.  When writing an object to a file, what is actually written is a
sequence of commands which regenerates the object.  The choice of commands is
such that for small objects, the commands look like a picture of the object.
Thus, the object is written using the commands '.' (to move right), 'o' (to
insert cells), and '\n' (to move to the next line).  (Periods are used instead
of spaces so that you can count the spaces between live cells easily.  However,
spaces or tabs could also be used and will act reasonably.)  Thus for small
objects, you can create a picture of an object in an editor, and then the
object can be read in by the life program.  Lines beginning with '!' or '#'
are ignored, so you can comment your objects.  When writing out an object, if
it is too large to be typed to your screen or edited easily, the output will
contain numeric arguments as necessary in order to compress the resulting file.
The command ';write filename' is used to save an object.

When reading an input file, the program looks for six different file names in
sequence.  It starts by looking for the file name as given.  Then it looks for
the name with an '.l' extension appended.  Then, if the environment variable
LIFELIB is defined, it looks in that directory for the file, and then for the
file with the '.l' extension.  Finally, it looks in /usr/games/lib/life for
the file, and then for the file with the '.l' extension.  Thus there is a
standard library of interesting life objects, and you can create your own
life library.  The ';read filename' command reads back a command file.  In
addition, when the life program is started, you can specify a filename on the
command line which will be read before any commands are read from the terminal.
This is useful when you want to immediately read a life object from a library.

Command loops and macros can be defined using the '<' and '>' commands.  If
a numeric argument is specified, a loop is being defined.  If no argument is
given, a macro is being defined.  While defining a macro or loop, the commands
you type are executed normally, so that you can see how the definition will
execute.  This is useful when you define a macro to create an object, since
you can easily see how to create the object.  Loops and macros can contain
both line mode and character mode style commands.  While you are defining a
loop or macro, the status line will indicate this and give the current depth
of loop or macro nesting.

When defining a macro, the next letter after the '<' is the macro name being
defined (the name must be a lower case letter).  All of the commands between
the '<' and the '>' (except for the macro name character) are saved.  Once a
macro has been defined, it is used by typing the ESCAPE character followed by
the macro letter.  As an example, the command string '<gththtuktntj>' defines
a macro named 'g' which causes a glider to be inserted at the current cursor
position every time you type '<ESC>g'.  The ';dumpmacros file' command writes
out the definitions of all macros so that you can read them back in later.

If a loop is being defined, the loop is executed the number of times specifed
by the argument to '<'.  If two arguments are specifed, the loop runs from
the first to the second argument (backwards if the second argument is less
than the first argument).  The value of the loop counter is available in the
loop itself by using '%' as you would a number.  As an example of a loop,
the command string '3,7<%o >' inserts five strings of cells spaced apart by
one cell, where the first string contains three cells, and the last string
contains seven cells.  When nesting loops, supplying an argument to '%' can
obtain the loop counter values for the outside loops while in the inner loop.
Thus, '2%' obtains the loop value for the next-to-innermost loop level.

While defining a loop or macro, you can request user intervention by using
the ';ttyinput' command.  This will suspend the execution of the loop or macro
and notify the user that input is desired by displaying 'tty-input' in the
status line.  The user can then execute any commands of his choice.  When he
is ready to proceed, he uses the ';endinput' (or a control-D) command to 
continue execution where it had paused.  Different commands can be given by
the user each time the loop or macro asks for terminal input.  If the command
';ttyinput -c' is used, terminal commands will only be asked for if there
is any terminal input available to be read.

While a macro or loop is executing, there is no screen updating.  Thus a
complicated command sequence can be executed without letting the user see
what is occuring until it is finished.  However, if you wish to update the
screen in the middle of execution, the ';updateview' command will do this.
Commands from the terminal automatically do an update whenever no more
input is available.

There is a set of variables which you can use to influence your commands.
They come in two kinds.  The first kind is the single-character variable.
There are 52 of these variables (the lower and upper case letters).  These
variables are used with a leading dollar sign.  Any command which accepts an
argument can accept '$c' to mean the value of variable 'c'.  These variables
can be set using the ';set' command, which takes a variable name followed by
an expression.  (As a shortcut, the '+c' command increments variable c.)
The initial values of all variables are zero.  These variables are useful
inside a macro in order to execute a command string over and over again with
only small differences each time (such as to vary the placement of two objects
with respect to each other).  As an example of the use of a single-character
variable, the command string '$al' moves the cursor to the right by the number
of cells given by the value of variable 'a'.

The other kind of variables are the multi-character variables.  These are
a fixed set of names, and their values are specific things, and cannot be
changed.  For example, the 'cx' variable returns the x coordinate of the
current cursor position.  You can see the complete set of variables using
the ';variables' command.  Since the parser must be able to distinguish
variable names from command letters, you cannot use them without surrounding
them with a pair of parenthesis.  The parenthesis can actually contain any
expression, including single-character variables.  When inside parenthesis
or as part of a line mode command, variables do not need the leading '$'.
As an example of multi-character variables used with an expression, the
command string '((vmaxx-vminx)/2)l' shifts the cursor to the right by an
amount equal to half of the screen width.

The rules of life can be changed to some degree.  This allows you to explore
alternative life universes.  You can specify how many live cells are required
for a cell to be born, or to stay alive.  However, you cannot change the
neighborhood used for counting live cells (the program always counts all of
the eight neighboring cells).  To change the cells needed for birth or death,
use the ';rules <born> <live>' line mode command.  The <born> string lists
those counts of neighbors which are required for a new cell to be born.  The
<live> string lists those counts of neighbors which are required for an
existing cell to stay alive.  The standard rules are thus described by the
command ';rules 3 23'.

There are two kinds of commands to life.  Line mode commands begin with a
colon or semi-colon character, and are terminated by an end of line character.
Many of these have already been described above.  Use the ';help' command to
list all of the line mode commands.  They are reasonably self-documenting.
Here are some of the remaining useful line mode commands.  The ';quit' command
exits the program.  The ';zero' command clears all cells of an object and
resets the scaling factor and cursor position.  The ';copyselection name' and
';moveselection name' commands copy or move selected cells to another object.
Finally, the ';undo' command will undo the most recent change to the current
object.  This can undo deletions, insertions, and running of generations,
among other things.  But you get only one level of backup  (A related backup
feature is the 'p' command, which will reinsert the last deleted object to
the current cursor location.)

Character mode commands are executed immediately when complete.  Until it is
complete, it can be edited using the normal erase and kill characters.  The
character mode commands can be preceeded by zero, one, or two arguments.
These arguments are generally used as a count of how many times the command
is to be executed.  Missing arguments are defaulted to 1 (with the exceptions
noted in the tables below).  If two arguments are specified, they are separated
by a comma.  So a character mode command can take one of the following forms:

                <cmd>		Both arguments defaulted.
         <arg1> <cmd>		First argument given, second is defaulted.
<arg1> , <arg2> <cmd>		Both arguments given.

The following table specifies the character mode commands, arranged in
useful catagories.  Many of these have been described in detail above.


	--- MOVEMENT COMMANDS ---

SPACE	move right <arg1> cells
.	move right <arg1> cells
h	move left <arg1> cells
l	move right <arg1> cells
k	move up <arg1> cells
j	move down <arg1> cells
y	move upper left <arg1> cells
u	move upper right <arg1> cells
b	move lower left <arg1> cells
n	move lower right <arg1> cells
LF	move to next "line"
TAB	move to next "tab stop"
@	remember current location as the pointer
c	return to location of the pointer
/	move cursor to next object


	--- SCREEN COMMANDS ---

s	set viewing scale to <arg1> and center view (default current scale)
S	turn on auto-scaling and center view
H	shift view left by width/4
L	shift view right by width/4
K	shift view up by height/4
J	shift view down by height/4
Y	shift view left and up
U	shift view right and up
B	shift view left and down
N	shift view right and down
^L	refresh the screen


	--- SINGLE CELL COMMANDS --

o	insert <arg1> cells and move cursor right
O	insert <arg1> cells and move cursor right
x	kill <arg1> cells and move cursor right
t	toggle cell at current location
i	toggle movement mode to move, insert, or delete


	--- MULTIPLE CELL COMMANDS ---

d<sel>	delete cells described by <sel>
p	place last deleted object at current location
f<sel>	flip cells left-to-right as described by <sel>
r<sel>	rotate cells 90 degrees clockwise as described by <sel>
m<sel>	mark (select) cells as described by <sel>
M	remove all marks (selections)


	--- LOOP, VARIABLE, AND MACRO COMMANDS ---

<	begin loop which executes from <arg1> to <arg2> times (if <arg1> given)
<<ch>	begin definition of macro named <ch> (if <arg1> not given)
>	end loop or macro definition
ESC<ch>	execute a macro command named <ch>
+<ch>	increment the value of the single-character variable <ch> by arg1


	--- MISCELLANEOUS COMMANDS ---

g	compute <arg1> generations (or stop if running)
G	compute infinite generations
z	set generation number to <arg1> (default zero)
!	ignore characters until end of line
#	ignore character until end of line
:<line>	execute a line mode command
;<line>	execute a line mode command


Arguments specified above as <arg1> and <arg2> can be any of the following:
$<var>	value of variable <var>, where <var> is a lower or upper case letter
(expr)	an arithmetic expression containing constants, variables, or operators
%	current loop counter value
<num>	explicit numeric value


Those commands above referencing <sel> take one of the following letters.
The command affects only those cells selected.  As a special case, repeating
the command letter is equivilant to selecting 'o' (the connected object).
Example: 'dd' deletes the connected object the cursor is on.
a	all cells
c	cell at current location
o	cells in the king-wise connected object at current location
h	cells to left of cursor
l	cells to right of cursor
k	cells above cursor
j	cells below cursor
b	cells below and left of cursor
n	cells below and right of cursor
u	cells above and right of cursor
y	cells above and left of cursor
p	cells in rectangle determined by pointer and cursor
m	cells which are marked
v	cells visible in window


				APPENDIX

This is a short introduction to life.  Life is played on an infinitely large
board divided into squares.  Each square is called a cell.  Each cell can be
either dead or alive.  Dead cells are seen as blanks, whereas live cells are
seen as non-blanks.  You begin to play by choosing some arbitrary set of
live and dead cells.  This configuration is called generation 0.  There is
a set of rules which transforms this set of cells into another set of cells,
called generation 1.  These same rules are then reapplied to generation 1 to
produce generation 2.  This process continues indefinitely.  The 'purpose' of
the game is to find starting patterns such that 'interesting things' result.

The rules which are applied are as follows.  Take any cell of a generation,
and call it the current cell.  Consider the eight cells immediately adjacent
to the current cell.  Count the number of these eight cells which are alive.
If the current cell is dead and the count is 3, then the current cell changes
to a live cell in the next generation.  If the current cell is alive and the
count is NOT 2 or 3, then the current cell changes to a dead cell in the next
generation.  Otherwise the cell remains unchanged in the next generation.
This rule is applied to every cell of a generation SIMULTANEOUSLY.  Thus to
rephrase, 3 live neighbors causes a new cell to be born, whereas 2 or 3 live
neighbors keeps a cell alive.

To see how these rules work in practice, run the program and start with some
number of live cells in some arrangement, and watch the generations change.
If you can predict what the changes will be, then you understand the rules.
The following are some objects to try, along with some descriptive names.
Warning: the last example gets complicated!!

  O         O          O                  O             O          OO
   O        O         OO       OO         OO             O          OO
  O         O         O        O          O            OOO          O

doomed   blinker   beehive   block   traffic lights   glider   r-pentomino