\ Program by Prof. Ting [needs lib/enter.4th] [needs lib/ansfacil.4th] 4096 string bottom ( allocate 4096 chars ) char O CONSTANT white ( ASCII # ) BL CONSTANT black ( blank ) : address1 ( n -- addr ) ( first area of life objects) 2047 AND ( n modulo 2048 ) BOTTOM + ( add offset to LO ) ; : address2 ( n -- addr ) ( 2nd area for next generation) address1 ( add 2048 to the address1 ) 2048 + ( let address1 do the modulus ) ; : neighbors ( -- ) 2048 0 ( scan the entire map ) DO I 1 + address1 c@ ( add objects in 8 neighbors ) I 1 - address1 c@ + I 79 + address1 c@ + I 79 - address1 c@ + I 80 + address1 c@ + I 80 - address1 c@ + I 81 + address1 c@ + I 81 - address1 c@ + I address1 c@ ( object in this location? ) IF DUP 2 = ( yes. 2 or 3 neighbors? ) SWAP 3 = OR IF 1 ELSE 0 THEN ( over-crowded. ) ELSE 3 = ( empty location ) IF 1 ELSE 0 THEN ( give birth if 3 life neighbors) THEN I address2 c! ( store next generation ) LOOP ; : refresh ( -- ) ( copy next generation to current) BOTTOM 2048 [+] BOTTOM 2048 CMOVE ; : display ( -- ) ( show current map on screen ) BOTTOM 24 0 DO ( show a screen full ) 79 0 DO ( show a line ) DUP C@ ( life object here? ) IF WHITE ELSE BLACK THEN EMIT ( show it ) 1+ ( next location ) LOOP CR 1+ ( next line ) LOOP DROP 79 0 DO [CHAR] = EMIT LOOP CR ( display separation ) ; : init-map ( addr -- ) ( generate a map from some memory ) 2048 0 ( look at a 2048 byte area ) DO random 1 AND ( use its least significant bit ) IF 1 ELSE 0 THEN ( to assign life object ) I address1 c! ( in our current map ) LOOP ; : generations ( n -- ) ( repeat n generations ) 0 DO neighbors ( compute next generation ) refresh ( copy to current map ) display ( and show it ) 2000 ms ( make a pause ) LOOP ; init-map ( initialize the map ) ." How many generations? " enter generations ( do 10 generations )