home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
vmsnet.sources.games
/
life
/
part01
next >
Wrap
Internet Message Format
|
1992-03-24
|
16KB
Path: uunet!mcsun!chsun!pegasus.ch!superuser
From: superuser@pegasus.ch
Newsgroups: vmsnet.sources.games
Subject: Game of Life 1/2
Message-ID: <1992Mar23.223316.32@pegasus.ch>
Date: 23 Mar 92 21:33:16 GMT
Organization: Pegasus BBS, Switzerland
Lines: 438
Game of Life -- Read the docs for more information
Feel free to call our BBS to get in touch with more 'funtastic'
VAX/VMS Games.
--
Internet: Superuser@pegasus.ch
FAX: ++41 [0]71 713837
PEGASUS: Sysop of PEGASUS BBS Call: ++41 [0]71 715577 > 27+ Lines
( PEGASUS.CH ) X.25: +228 4752 1 2574 > ChatSystem
VAX/VMS is like sex - if you've tried it, you can't get along without it,
if you haven't you really have no idea what the fuss is about.
$! ................... Cut between dotted lines and save. ...................
$!...........................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user SUPERUSER
$! on 23-MAR-1992 22:13:17.88.
$!
$! ATTENTION: To keep each article below 31 blocks (15872 bytes), this
$! program has been transmitted in 2 parts. You should
$! concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 7 files:
$! AAAREADME.LIS
$! FUTURE_FEATURES.LIS
$! GETCHA.C
$! LIFE.C
$! LIFE.WORK
$! PATTERNS.LIS
$! SPARE_LIFE.C
$!
$!============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
"VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher."
$ EXIT 44 ! SS$_ABORT
$VERSION_OK:
$ GOTO START
$!
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
VMS_SHARE_DUMMY.DUMMY
b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) )
; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE
, b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors
:= 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN
& "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION
( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail
& LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP
; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK
( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 )
; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip
<> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF
; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT )
; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip
:= MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip
<> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET )
; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part )
); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF
; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1
; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line
<> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF
; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors
:= i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT
( "The following line could not be unpacked properly:" ); SPLIT_LINE
; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL
( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH
( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1
); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP
; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION
( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO
( "The following !UL errors were detected while unpacking !AS", i_errors
, s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" )
; ENDIF; EXIT;
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." )
$ RETURN
$!
$START:
$ FILE_IS = "AAAREADME.LIS"
$ CHECKSUM_IS = 1999775588
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X`009`009`009`009LIFE
X`009`009`009 By Mark Randall
X
XAAAREADME.LIS`009`009This file
XFUTURE_FEATURES.LIS`009Features to be implemented in the (near?) future
XGETCHA.C`009`009Single character input without a CR
XLIFE.C`009`009`009Source code
XLIFE.EXE`009`009Executable
XLIFE.WORK`009`009Notes on functionality - see explanation below
XPATTERNS.LIS`009`009Suggested patterns to try
XSPARE_LIFE.C`009`009Attempt at different implemetation of life()
X
XABSTRACT
X--------
X`009The computer game of life has been famous ever since its introduction
Xin Scientific American and Byte. Its concept is simple enough so that anyone
Vcan use it, yet the patterns can get amazingly complex within very little tim
Xe.
XIt works like this: there is a large grid on which there are cells, either
Xalive or dead. Over time, the grid changes, bringing new cells to life or
Xkilling old cells. Each increment of time is called a generation. There are 3
Vbasic rules which determine whether any given cell will be alive or dead in t
Xhe
Xnext generation:
X
X`0091. Each living cell that has exactly 2 or 3 living neighbors will be
X`009 alive in the next generation.
X
V`0092. Each living cell that has other than 2 or 3 living neighbors will be`0
X32
X`009 dead in the next generation.
X
X`0093. If a cell that is currently not living (dead) has exactly 3 living
X`009 neighbors, it will be alive in the next generation.
X
X`009Different patterns will produce drastically different results -
Vsometimes one cell can make all the difference. Since the introduction of lif
Xe
Vin 1970, many different basic patterns have been discovered - see patterns.li
Xs
Vfor some patterns to try. Some patterns last forever, while some die out afte
Xr
Va few generations. Several will change for hundreds of generations, and final
Xly
Vreduce themseleves to small, basic patterns that either don't change or repea
Xt
Vevery 2 or 3 generations. See article list for articles in magazines that hav
Xe
Xdetails on various developments of life.
X
X`009Using the program is pretty simple. In the beginning, a grid is drawn
Von the screen using periods. You can manipulate the cursor around the grid wi
Xth
Vthe numeric keypad or VTxxx series arrow keys. A cell, 'o', is either produce
Xd
Xor erased by hitting the 5 key. The cursor manipulation and cell placement is
Xdone with escape sequences, so the output should work on any VTxxx or
Xcompatible.
X
X`009The program itself is written in C. Please feel free and encouraged to
Xmodify and improve it. If you do anything to drastically improve it, please
XEMAIL it to me, and I'll try to make the improvement public. The cell storage
Vis grossly memory-inefficient, but it was done for simplicity. Most all of th
Xe
Xcode is standard C, and should be portable to Unix with few modifications.
XAgain, I'd appreciate it if you passed along such versions to me. The last
Xitems of importance: the terminal width and hight can be changed within the
Xsource code by changing the constants HIGHT and WIDTH. The character for a
Xliving cell is currently hard-coded into the program, but it can be easily
Vchanged given the brevity of the program itself at this stage. This program i
Xs
Vpublic-domain, and may be copied anywhere. Please keep my name as the origina
Xl
Xauthor, though.
X
X`009`009`009Enjoy!
X`009`009`009Mark Randall
X`009`009`009CI$ user id: [70471,2760]
X
XKNOWN BUGS
X----------
X`009First and foremost - there's no good way to stop the processing of the
Xgenerations. If this were DOS (Ugh! Cough! YUK!), this would be easy - the
Xscanf function would WORK RIGHT! Unfortunatly, it doesn't, so the best way to
Vdate is a CTRL-Y. The processing for the corners of the grid doesn't work qui
Xte
Xright, either.
X
XARTICLES
X--------
X`009Several articles have been written on the game of life. Here's a list
Xof the ones I know about:
X
X`009Scientific American:
X`009`00910/70`009Original Article by John Horton Conway
X`009`00911/70
X`009`00901/71
X`009`00902/71
X`009`00903/71
X`009`00904/71
X`009`00911/71
X`009`00901/72
X`009Byte:
X`009`00909/75
X`009`00910/75
X`009`00912/75
X`009`00901/76
X`009`00912/78
X`009`00901/79
X
XLIFE.WORK
X---------
X`009This is just a text file that shows how to check the eight positions
Varound a given cell in the middle, on the borders, or in the corners. It may
X be
Xhelpful in changing/debugging the source code. Set your term to 132 cols to
Xdisplay.
X
XTO BUILD
X--------
X`009The building of Life is rediculously simple. Follow these commands:
X
X $ cc life
X $ cc getcha
X $ link life,getcha
X
X`009and finally:
X
X $ run life
X
XVARIATIONS
X----------
X`009I know there are variations of Life out there - I'm looking for them.
XOne-dimensional Life is pretty easy, and I may write some code for it one of
Vthese days. 3D Life is where a great deal of my interest lies, but I'm baffle
Xd
Xas to how to represent it on a screen, especially a character-based VTxxx.
XThere are also other rule sets, but I have yet to ever lay eyes on them. I'd
Xlove to create a DEC/X Windows interface for the game, but it'll be a while
Xbefore I get to that. See future_features.lis for my current ambitions.
X
$ GOSUB UNPACK_FILE
$ FILE_IS = "FUTURE_FEATURES.LIS"
$ CHECKSUM_IS = 878720711
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X3d life
Xdecwindows interface
Xget out of infinite loop
Xrandom cells/patterns
Xrecall original pattern and edit it`032
Xcheck for repetition n levels deep
Xdisk io
$ GOSUB UNPACK_FILE
$ FILE_IS = "GETCHA.C"
$ CHECKSUM_IS = 624702643
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*
X`009getcha.c
X`009get character from kb w/out echo (no CR)
X*/
X
X#include ssdef
X#include descrip
X#include iodef
Xint channel;
Xchar bufaddr;
X$DESCRIPTOR(DEVDSC,"TT:");
Xgetcha()
X`123
Xshort iosb[4];
Xint stat;
X`009bufaddr=0;
X`009stat = sys$assign(&DEVDSC,&channel,0,0);
X`009if (stat != SS$_NORMAL) lib$stop(stat);
X`009stat = sys$qiow(0,channel, IO$_READVBLK`124IO$M_NOECHO,&iosb,0,0,
X`009`009&bufaddr,1,0,0,0,0);
X`009stat = sys$dassgn(channel);
X`009return(bufaddr);
X`125
$ GOSUB UNPACK_FILE
$ FILE_IS = "LIFE.C"
$ CHECKSUM_IS = 847235763
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*`009`009`009GAME OF LIFE
X`009`009`009VAX C VERSION
X`009`009`009BY MARK RANDALL
X*/
X
X#include stdio
X#include ctype
X#define width 80
X#define hight 40
X#define esc '\33'
X
Xint `009screen[width+1][hight+1];
Xint `009memory[width+1][hight+1];
Xint `009cells_alive;
Xint `009x,y;
Xint`009charin;
V/* ------------------------------------------------------------------------ *
X/
X
Xmain()
X`123
X`009int generation;
X`009for ( ; ; ) `123
X`009 generation=0; cells_alive=1;
X`009 drawscreen();
X`009 input();
X`009 post_input();
X
X`009 while (cells_alive != 0) `123
X`009 `009printf("%c[%d;1fGeneration #%d", esc, hight+2, generation++);
X`009 `009life();
X
X`009`009if (cells_alive==0) `123
X`009`009 printf("%c[%d;1f Last generation. ",esc,hight+3);
X`009`009 printf("<<Enter>> to continue, E to end :");
X`009`009 charin=getcha();
X`009`009 if (charin>90) charin -= 32;
X`009`009 if (charin==69) `123 printf("%c[2J%c[;f",esc,esc); exit(); `125
X`009`009`125
X`009 `125
X`009`125
X`125
X
Xdrawscreen()
X`123
Xchar incstr[width];
X`009for (y=1; y<hight+1; y++) `123
X`009 for (x=1; x<width+1; x++)
X`009`009screen[x][y]=memory[x][y]=0;
X`009`125
X`009printf ("%c[2J%c[H",esc,esc);`009/* clear screen */
X`009for(x=0;x<width;x++) strcat(incstr,".");
X`009for(x=0;x<hight;x++) printf("%s\n",incstr);
X`009for(x=0;x<width;x++) incstr[x] = '\0';
X`009for(x=0;x<width;x++) strcat(incstr,"-");
X`009printf("%s\n",incstr);
X`125
X
Xinput()
X`123
X`009printf("%c[%d;f",esc,hight+2);
X`009printf("Use cursor keys or numeric keypad to move cursor.\n");
X`009printf("Use period or 5 key to place/remove cell,");
X`009printf(" zero or Enter to begin processing.");
X`009x=1; y=1;`009`009/* upper left position */
X`009printf("%c[1;1f",esc); /* put the cursor there */
X for ( ; ; ) `123`009`009/* infinite loop */
X`009charin=getcha();`009/* get ascii code from getcha */
X`009if (charin==27) `123`009/* if char=esc, */
X`009 charin=getcha();`009/* get the bracket */
X`009 charin=getcha();`009/* then get the wanted char */
X`009`125
X`009switch(charin) `123`009/* move cursor, change index, flip dot */
X`009 case 65:
X`009 case 56:`009if (y!=1) `123 printf("%c[A",esc); y--; `125 break;
X`009 case 66:
X`009 case 50:`009if (y!=hight) `123 printf("%c[B",esc); y++; `125 break;
X`009 case 67:
X`009 case 54:`009if (x!=width) `123 printf("%c[C",esc); x++; `125 break;
X`009 case 68:
X`009 case 52:`009if (x!=1) `123 printf("%c[D",esc); x--; `125 break;
X`009 case 55:`009if ((y!=1) & (x!=1)) `123
X`009`009`009 printf("%c[A%c[D",esc,esc); y--; x--; `125 break;
X`009 case 51:`009if ((y!=hight) & (x!=width)) `123
X`009`009`009 printf("%c[B%c[C",esc,esc); y++; x++; `125 break;
X`009 case 49:`009if ((x!=1) & (y!=hight)) `123
X`009`009`009 printf("%c[B%c[D",esc,esc); y++; x--; `125 break;
X`009 case 57:`009if ((y!=1) & (x!=width)) `123
X`009`009`009 printf("%c[A%c[C",esc,esc); y--; x++; `125 break;
X`009 case 46:
X`009 case 53:`009changedot(); break; /* period = switch dot */
X`009 case 48:
X`009 case 13:`009return; /* zero = end */
X`009`125
X `125
X`125
X
Xchangedot()
X`123
X`009if (screen[x][y]==1) `123`032
X`009 screen[x][y]=0;
X`009 printf(".%c[D",esc);
X`009`125
X`009else `123
X`009 screen[x][y]=1;
X`009 printf("o%c[D",esc);
X`009`125
X`125
X
Xpost_input()
X`123
X`009char incstr[width];
X`009for(x=0;x<width;x++) incstr[x] = '\0';
X`009printf("%c[1;1f",esc);
X`009for (y=1; y<hight+1; y++) `123
X`009 for (x=1; x<width+1; x++) `123
X`009`009if (screen[x][y]==1) strcat(incstr,"o");
X`009`009else strcat(incstr," ");
X`009 `125
X`009 printf("%s\n",incstr);
X`009 for(x=0;x<width;x++) incstr[x] = '\0';
X`009`125
X`009printf("%c[%d;f",esc,hight+2);
X`009for(x=0;x<width;x++) incstr[x] = '\0';
X`009for(x=0;x<width;x++) strcat(incstr," ");
X`009printf("%s\n",incstr);
X`009printf("%s\n",incstr);
X`125
X
Xlife()
X`123
X`009int livecells=0;
X`009/* general area */
X`009for (y=2; y<hight; y++) for (x=2; x<width; x++) `123
X`009`009if (memory[x+1][y]==1)`009`009livecells++;
X`009`009if (memory[x-1][y]==1)`009`009livecells++;
X`009`009if (memory[x][y+1]==1)`009`009livecells++;
X`009`009if (memory[x][y-1]==1)`009`009livecells++;
X`009`009if (memory[x-1][y-1]==1)`009livecells++;
X`009`009if (memory[x+1][y-1]==1)`009livecells++;
X`009`009if (memory[x-1][y+1]==1)`009livecells++;
X`009`009if (memory[x+1][y+1]==1)`009livecells++;
X`009`009livecells=lifeloop(livecells);
X`009`125
X
X`009/* upper left corner */
X`009x=1; y=1;
X`009if (memory[2][1]==1)`009`009livecells++;
X`009if (memory[1][2]==1)`009`009livecells++;
X`009if (memory[width][1]==1)`009livecells++;
X`009if (memory[1][hight]==1)`009livecells++;
-+-+-+-+-+ End of part 1 +-+-+-+-+-