Conway's game of life

Anything QL Software or Programming Related.
Post Reply
User avatar
polka
Trump Card
Posts: 196
Joined: Mon Mar 07, 2011 11:43 am

Conway's game of life

Post by polka »

Everybody knows Conway's game of life ?

If you don't, google for it : it's a famous mathematical simulation (invented by Conway) displaying the life of arbitrary groups of tokens (called cells) on a checkerboard, given two simple rules telling that :
1/ a living cell survives to the next generation if it has 2 or 3 neighbours, no less nor more.
2/ a new cell is born in an empty square if it is surrounded by exactly three living cells.

I found a (short) SuperBasic program of this simulation, that I wrote a long time ago. My program considers a checkerboard (a "world") that although finite does not have boundaries, because it is "warped" in both directions x and y (like a torus).

Normally, a game of life may be displayed in black and white, but my program uses the three colors available in MODE 4, to display the cells just born in GREEN, the cells surviving in WHITE and the cells that just have died in RED.

You can see that the main (longest) procedure of this program is called LIFE, which does REPeat a loop called GENERATION.

Inside this loop GENERATION, you can see two tasks, the first called DAD and the second MOM.

DAD will evaluate for each square of the checkerboard how many cells are surrounding it ; and then MOM, depending on these results, will enforce the two rules to let cells be born or survive.

If you were doing this looking systematically at every square, the execution time would be proportionnal to the total size (number of squares) of the "world". Instead, my design uses two stacks that let DAD and MOM tell each other the often much fewer squares that are to be examined. The execution time is thus not proportionnal to the size of the world but to the number of squares hosting living cells (and neighbours). So, beside the main procedure there are 4 functions to manage these stacks.

Then, there are also three procedures ( BIG SMALL TINY ) to decide of the size of the squares (and inversely, the size of the world)

And an initialisation procedure PLAGUE that clears the whole world of any living cell.

You may populate the world cell by cell calling the procedure CELL, but you may also add procedures creating - with the help of a generic scanning procedure called SYMBIOSIS - complex living organisms, taking for examples GLIDER or BOMBER .

Calling GLIDER for instance, you will observe a little organism that moves diagonally over the "world". On a basic QL even this simple model is rather slow. On an emulator at full speed, it is more interesting, and you may even dare to run the BOMBER : this one is an organism that periodically shoots a GLIDER... but finally gets eaten by them because of the warped world.

The SuperBasic code :

Code: Select all

REM Conway's game of Life: version SuperBASIC
REM Copyright Paul KOPFF, Clamart (France)


WINDOW#1,480,256,20,0
MODE 4 : PAPER#1,0 : CLS
a = RESPR(40960)


1100 DEFine PROCedure PUSH1( n )
1110     POKE_W sp1,n
1120     sp1 = sp1 + 2
1130 END DEFine PUSH1

1140 DEFine FuNction POP1
1150     sp1 = sp1 - 2
1160     IF sp1 = sp1u THEN
1170        sp1 = sp1f
1180        RETurn -1
1190     END IF
1200     RETurn PEEK_W(sp1)
1210 END DEFine POP1

1220 DEFine PROCedure PUSH2( n )
1230     POKE_W sp2,n
1240     sp2 = sp2 - 2
1250 END DEFine PUSH2

1260 DEFine FuNction POP2
1270     sp2 = sp2 + 2
1280     IF sp2 = sp2u THEN
1290        sp2 = sp2f
1300        RETurn -1
1310     END IF
1320     RETurn PEEK_W(sp2)
1330 END DEFine POP2

1340 DEFine PROCedure DOT( x,y,c )
1350     BLOCK lc , hc , x * lm , y * hm , c
1360 END DEFine DOT

1370 DEFine PROCedure BIG
1380     le = 48
1390     he = 32
1400     lm = 10
1410     hm =  8
1420     lc =  8
1430     hc =  6
1440 END DEFine BIG

1450 DEFine PROCedure SMALL
1460     le = 96
1470     he = 64
1480     lm = 5
1490     hm = 4
1500     lc = 4
1510     hc = 3
1520 END DEFine SMALL

1530 DEFine PROCedure TINY
1540     le = 160
1550     he = 128
1560     lm = 3
1570     hm = 2
1580     lc = 2
1590     hc = 1
1600 END DEFine TINY


1610 DEFine PROCedure LIFE
1620 REPeat GENERATION
1630     BEEP 2000,10
1640     REPeat DAD
1650         c = POP2
1660         IF c = -1 THEN EXIT DAD
1670         m = PEEK(c+a)
1680         IF m > 31 THEN 
1690             x = c MOD le
1700             y = c DIV le
1710             FOR i = -1 TO 1
1720                 xv = ( x + i ) MOD le
1750                 FOR j = -1 TO 1
1760                     yv = ( y + j ) MOD he
1790                     cv = xv + le * yv
1800                     mv = PEEK(cv+a)
1810                     nv = mv MOD 16
1820                     IF nv = 0 THEN PUSH1 cv
1830                     POKE cv+a,mv+1
1840                 END FOR j
1850             END FOR i
1860         ELSE 
1870             IF m > 15 THEN PUSH1 c
1880         END IF 
1890     END REPeat DAD
1900     REPeat MOM
1910         c = POP1
1920         IF c = -1 THEN EXIT MOM
1930         m = PEEK(c+a)
1940         x = c MOD le
1950         y = c DIV le
1960         n = m MOD 16
1970         IF m > 31 THEN 
1980             IF n = 3 OR n = 4 THEN 
1990                 IF m > 48 THEN DOT x,y,7
2000                 PUSH2 c
2010                 POKE c+a,32
2020             ELSE 
2030                 IF m <> 48 THEN 
2040                     DOT x,y,2
2050                     PUSH2 c
2060                     POKE c+a,16
2070                 END IF 
2080             END IF 
2090         ELSE 
2100             IF n = 3 THEN 
2110                 DOT x,y,4
2120                 PUSH2 c
2130                 POKE c+a,48
2140             ELSE 
2150                 IF m > 15 THEN DOT x,y,0
2160                 POKE c+a,0
2170             END IF 
2180         END IF 
2190     END REPeat MOM
2200 END REPeat GENERATION
2210 END DEFine LIFE

2220 DEFine PROCedure PLAGUE
2230     CLS
2240     FOR i = a TO a + he * le
2250         POKE i , 0
2260     END FOR i
2270     sp1u = a + 20478
2280     sp1f = a + 20480
2290     sp2u = a + 40960
2300     sp2f = a + 40958
2310     sp1  = sp1f
2320     sp2  = sp2f
2330 END DEFine PLAGUE


2340 DEFine PROCedure CELL( x,y )
2350     x = x MOD le
2360     y = y MOD he
2370     c = x + le * y
2380     POKE c+a,48
2390     PUSH2 c
2400     DOT x,y,4
2410 END DEFine CELL

2630 DEF PROCedure SYMBIOSIS( xv,yv )
2640     READ n
2650     FOR i = 1 TO n
2660         READ x
2670         READ y
2710         CELL x+xv,y+yv
2720     END FOR i
2730 END DEFine SYMBIOSIS

2420 DEFine PROCedure GLIDER
2430     DATA 5,0,0,1,0,2,0,2,1,1,2
2440     RESTORE 2430
2450     SMALL : PLAGUE
2460     SYMBIOSIS 10,10
2470     LIFE
2480 END DEFine GLIDER

2490 DEFine PROCedure BOMBER
2500     DATA 65,0,18,0,19,0,20,1,18,2,11,2,12,2,19,3,10,3,12
2510     DATA 4,12,8,17,8,18,9,8,9,9,9,10,9,16,9,17,10,10,10,18
2520     DATA 11,9,14,7,14,8,15,8,15,9,16,7,20,6,20,7,20,8,21,8
2530     DATA 22,7,22,19,22,20,23,10,23,11,23,12,23,18,23,19
2540     DATA 24,12,24,20,25,11,28,-1,28,0,28,9,28,10,29,-2,29,0
2550     DATA 29,10,29,11,30,0,30,9,34,20,34,21,34,22,35,20
2560     DATA 36,13,36,14,36,21,37,12,37,14,38,14,39,3,39,4
2570     DATA 39,5,40,5,41,4
2580     RESTORE 2500
2590     SMALL : PLAGUE
2600     SYMBIOSIS 6,6
2610     LIFE
2620 END DEFine BOMBER

glider
I did it after coding exactly this same simulation based on the same design with ComputerOne FORTH, to compare. I won't tell you which was faster... :mrgreen:

BYE Paul


May the FORTH be with you !
POLKa
User avatar
polka
Trump Card
Posts: 196
Joined: Mon Mar 07, 2011 11:43 am

Re: Conway's game of life

Post by polka »

Hi all !

I rewrote my "classic Conway's Life" program in FORTH and am proud of it, because I think I optimized it both in speed and size. It is "classic" because it uses the classic rules defined by Conway - but the program could be easily changed to use other rules : because they are in fact just contained inside two 16 bytes data arrays called NI and NR.

The classic Conway's life simulation is developped with "cells" planted on a grid of square locations, following repeated alternations of two tasks :
1 / counting for each square (with or without a cell sitting on it) the number of cells sitting all around it on the 8 "next-door" squares.
2 / following the classic rules :
letting a cell survive to next generation if it had two or three neighbours
letting a cell be born on an empty square if there were exactly three cells in its neighbourhood
So as to update the grid with the next "generation" of cells.

In principle the grid should be of infinite extend in both x and y directions, however this cannot be managed on a monitor screen nor by our finite computer resources. So, there are two ways to consider what may happen when the life simulation spreads outside of the "world" that the program can manage (and the picture that can be displayed) :
1/ you may decide that when a cell should be born just one square outside the world grid, actually it will not, but then the next generation of the border squares will not hold the right number of neighbours.
2/ or you may decide that when a cell should be born just one square outside a border, it will be born just inside the opposite border (be it vertical or horizontal) but then, after a while, your organisms may be polluted "from behind".

Anyway, I chose this second way. So my world of 120x85 cells is "warped" in both x and y directions.

On the attached picture, I show a snapshot of a demo comprising little (diagonally) crawling organisms called "gliders" and one bigger organism which is a "bomber" shooting a new glider every 30 generations. As the world is warped, you see the line of gliders going out of it either through the vertical or horizontal borders but reentering it immediately at the opposite borders. And thus (you may notice that) the bomber will be finally hit from behind ! But it seems shielded from these attacks and simply destroys the incoming gliders without any harm. So after shooting 32 gliders, this warped world does no longer evolve on the whole (but if its dimensions were slightly different, the bomber might be hit somewhere else and desintegrate).

The first of the two afore mentionned tasks, I called it DAD and the second MOM, thus the forth definition of LIFE is simply :

: LIFE BEGIN DAD MOM REPEAT ;

Or if you want to be able to stop it after a while (just by hitting the keyboard) :

: LIFE BEGIN DAD MOM ?TERMINAL UNTIL KEY DROP ;

More comments on the picture :

As (beside black) I could use three colours (in mode 4), I decided (for a better show - instead of black and white) that "just born" cells would be green, "surviving" cells would be white, and "just dying" cells would be red ; the green and red states of a cell lasting thus only one generation.

More comments on the algorithm :

To share informations about the world, DAD and MOM address both a "world map".
In this map of "nibbles" (chuncks of 4 bits per square - half a byte), MOM as she updates the state of the cells, puts 1 when she just killed a cell, 2 when she just gave birth to one and 3 when she let it survive. Then DAD updates these values as he counts the neighbours, and when giving the hand to MOM again, the nibbles will contain results that let MOM enforce Conway's rules. DAD uses the NI data array of 16 bytes to update the counts and MOM, the NR data array to translate the final counts into the new states of the squares of the grid. By simply changing the content of these arrays, one might thus change the rules.

In a raw approach of the problem, DAD and MOM would systematically explore the whole world each time they execute. The runtime would thus depend on the size (width x height) of the world, and even in the case of my rather small 120x85 world, this would be very ineffective.

Thus, I designed MOM and DAD to use also two stacks to signal to each other which cells are "interesting". MOM will push on her stack only the squares that she gave a value 1 2 or 3, and DAD will look for neighbours only of those ; then he will push onto his own stack only squares which actually had neighbours, so that MOM may only examin those. Thus the runtime does not depend on the size of the world, only on its population. The memory space shared by the two stacks is the biggest to be used by this program : I dimensionned it to 85x128 16bits words, so to never risc stack overflow even in a world so populated that every square were "interesting" either for DAD or for MOM.

Benchmarking ?

Having a slightly modified LIFE program read the QL time each 30 generations of the demo, I determined that each added glider added 4.2 seconds to this period of 30 generations. To shoot the first (and also every following) glider, the bomber itself used 33 seconds of runtime in 30 generations. So with n gliders already crawling, the periods of 30 generations last :

33 + 4.2 x n seconds

and reach a limit of 167-168 seconds for 32 gliders - as then, they start to hit the bomber from behind, their number no longer increases.

These durations were measured with my "plain" oooooold QL, bought in 1984. The ComputerOne FORTH system with this program loaded does not use more than 64Kb and so it runs even on any unexpanded 128Kb machine.

I soon will try to port in onto Digital Precision SuperForth, which seems to be rather more available than ComputerOne's (WHY ?).

Bye Paul
Attachments
demo at 8 times the speed of QL
demo at 8 times the speed of QL
Last edited by polka on Mon Jul 06, 2015 3:00 pm, edited 1 time in total.


May the FORTH be with you !
POLKa
User avatar
Mr_Navigator
QL Fanatic
Posts: 782
Joined: Mon Dec 13, 2010 11:17 pm
Location: UK, Essex
Contact:

Re: Conway's game of life

Post by Mr_Navigator »

Great example of the classic simulation Polka, did the forth version run substantially faster than the SuperBasic version?


-----------------------------------------------------------------------------------
QLick here for the Back 2 the QL Blog http://backtotheql.blogspot.co.uk/
User avatar
polka
Trump Card
Posts: 196
Joined: Mon Mar 07, 2011 11:43 am

Re: Conway's game of life

Post by polka »

I included the SuperBasic source of Conway's LIFE because it may be more readable than the Forth code (anyway, of my Forth code). But although I tested it and it runs exactly like the Forth program, I did not measure execution times, as I found that it was TBTB (too boring to benchmark).

As you seem interested, I did it however today, in the following way : you remember that the Forth DEMO displays a "bomber" that adds a new "glider" every 30 generations, and this causes an increase of the run time of 4.2sec ; which means that 30 generations of a lone isolated glider in Forth take this exact time : 4.2sec.

With the SuperBasic program, the same 30 generations of the life of a single glider take guess what... 142sec, almost 34 times more time !


So you see that Forth is fast, compared to SuperBasic, however this Forth program was totally coded in Forth. Not even the graphic word DOT is in machine code. I had coded an assembler word PIXEL for other applications, that (I measured) is only about six times faster plotting one pixel than DOT (which has to plot 6 pixels, so it does not make sense to use PIXEL instead).

Staying with pure Forth, it will be much easier to port the program to Digital Precision SuperFORTH, which I am doing right now.

So, I will be able to compare the performing of these two implementations (I guess there will not be much difference), and give you a version of the program for a FORTH that is nowadays PD (I do not know the status of Computer One FORTH).

But WHY is it more difficult to port assembler words than plain Forth code ?

Because these two Forth engines reserve some of the 68000 registers in different ways : thus, unless you save and restore them systematically (which I never do because it takes time), you cannot use the same set of registers in your own machine code, depending on the target Forth engine.

BYE Paul


May the FORTH be with you !
POLKa
User avatar
polka
Trump Card
Posts: 196
Joined: Mon Mar 07, 2011 11:43 am

Re: Conway's game of life

Post by polka »

I pulled myself out of QPC2 for a moment to finish porting my FORTH CONWAY's LIFE simulation on Digital Precision SuperFORTH. Did I tell you that I prefered ComputerOne FORTH (which is not called "Super..." but that I find better) ?

One plus of SuperFORTH is its capacity to compile also plain text files (beside the classic FORTH specific file system loading source code - and other data - from 1024bytes blocs).

This is convenient for dispatching the programs (for instance on this forum) and the listing may seem more readable to most. Now, here is the source code of this simulation, running on SuperFORTH :

Code: Select all

: .< 0 <# #S #> TYPE ;
: >< ( n,a,b --- [a<=n<=b] ) >R OVER <= SWAP R> <= AND ;

CR CR .( Conway's life in a )

   120 DUP .< .( x) DUP CONSTANT ww              ( world width )
   85 DUP . .( torus shaped world) DUP CONSTANT wh   ( height )

   * DUP 2/ CREATE wm ALLOT ( world map of nibbles 4bits/cell )

   2* CREATE ws HERE >R ALLOT HERE R> CONSTANT da CONSTANT ma

   VARIABLE ds VARIABLE ms ( DAD and MOM stack pointers )   HEX

   CREATE ss F0F , F0F0 , 70 , 7 , 7000 , 700 , 7070 , 707 ,
   CREATE ni A0A , 404 , 506 , 708 , 80A , B0C , D0D ,
   CREATE nr 0 , 101 , 101 , 303 , 100 , 0 , 200 ,  CR  DECIMAL

: sd ( color,x,y --- )
  384 * SWAP 4 + 2 /MOD 2* ROT +
  DUP >R 2 A@ OVER 2* ss + @ AND
  ROT DUP
  IF
    2* ROT + 2* ss + @ OR
  ELSE
    DROP SWAP DROP
  THEN
  DUP R@ 2 A!
  R> 128 + 2 A!
;

: cs ( clear DAD and MOM stacks ) da ds ! ma ms ! ;
: >d ds @ !  2 ds +! ; ( DAD push : any first added next-door )
: >m -2 ms +! ms @ ! ; ( MOM push : any born/surviving/killed )
: <d ds @ da = IF -1 ELSE -2 ds +! ds @ @ THEN ;    ( DAD pop )
: <m ms @ ma = IF -1 ELSE ms @ @  2 ms +! THEN ;    ( MOM pop )

: xy> ( x,y --- m ) ww * + ;
: xy< ( m --- x,y ) ww /MOD ;

: n@ ( m --- n ) 
  2 /MOD wm + C@ SWAP 
  IF 
    16 / 
  ELSE 
    15 AND 
  THEN ;

: n! ( n,m --- ) 
  2 /MOD wm + DUP >R C@ SWAP
  IF
    15 AND SWAP 16 * OR
  ELSE
    240 AND OR
  THEN
  R> C! 
;

: egg
  BEGIN
    <m ( pops MOM )
    DUP -1 <>
  WHILE
    DUP n@ 2 8 ><
    IF
      2 -1 DO
        2 -1 DO
          DUP 
          xy< 
          I J ROT 
          + wh MOD >R 
          + ww MOD R>
          xy>
          DUP >R
          n@ DUP 4 <
          IF
            R@ >d
          THEN
          ni + C@
          R> n!
        LOOP
      LOOP
      DROP
    ELSE
      DUP n@ 1 =
      IF
        9 OVER n! >d
      ELSE
        DROP
      THEN
    THEN
  REPEAT
  DROP
;

: hen
  BEGIN
    <d ( pops DAD )
    DUP -1 <>
  WHILE
    DUP DUP n@
    nr + C@
    DUP ROT xy< sd
    DUP
    IF
      OVER >m
    THEN
    SWAP n!
  REPEAT
  DROP
;

: LIFE
  BEGIN
     egg hen
     1 KEYROW 64 =
  UNTIL
;

: FLU
  CLS
  cs
  ww wh * 2/ 0 
  DO 
    0 I wm + C!
  LOOP
; 
  
: LAY ( x,y --- )
  xy> DUP >m
  2 OVER n!
  2 SWAP xy< sd
;

.( Creating incrementally complex organisms)

VARIABLE components   
VARIABLE flag  0 flag !   
VARIABLE A_C

: S1 SWAP ;   : S7 NEGATE ;   : S2 NEGATE S1 ;   : S6 SWAP S7 ;
: S3 SWAP S2 ;   : S5 NEGATE S6 ;   : S4 NEGATE S3 ;     : SO ;

CREATE S ' SO , ' S1 , ' S2 , ' S3 , ' S4 , ' S5 , ' S6 , ' S7 ,

CREATE g8 
          0 C, 1 C, 2 C, 3 C, 4 C, 5 C, 6 C, 7 C,
          1 C, 0 C, 7 C, 6 C, 5 C, 4 C, 3 C, 2 C,
          2 C, 3 C, 4 C, 5 C, 6 C, 7 C, 0 C, 1 C, 
          3 C, 2 C, 1 C, 0 C, 7 C, 6 C, 5 C, 4 C, 
          4 C, 5 C, 6 C, 7 C, 0 C, 1 C, 2 C, 3 C, 
          5 C, 4 C, 3 C, 2 C, 1 C, 0 C, 7 C, 6 C,
          6 C, 7 C, 0 C, 1 C, 2 C, 3 C, 4 C, 5 C, 
          7 C, 6 C, 5 C, 4 C, 3 C, 2 C, 1 C, 0 C, 

: *g8 3 PICK 8 * + g8 + C@ ;

: bio+ 2- , C, C, C, 5 components @ +! ; 

: ;BIO 0 flag ! ;

: c [ HERE A_C ! ] 
  flag @ 
  IF 
    A_C @ bio+ 
  ELSE 
    DROP LAY
  THEN 
;

: BIO:
  CREATE  HERE components ! 0 , -1 flag ! 
  DOES> flag @
  IF 
    bio+ 
  ELSE  
    DUP @ OVER + 2+ SWAP 2+ 
    DO 
      I 4 + C@ 
      I 3 + C@
      I 2 + C@ 
      *g8 >R 
      2 PICK 2* S + @ EXECUTE 
      3 PICK + SWAP 
      4 PICK + SWAP R> I @ EXECUTE 
    5 +LOOP 
    DROP DROP DROP
  THEN 
;

 BIO: g 0 0 0 c 1 0 0 c 2 0 0 c 2 1 0 c 1 2 0 c ;BIO
 BIO: r 0 0 0 c 1 0 0 c 1 1 0 c 2 1 0 c 0 2 0 c ;BIO
 BIO: b  0 20 6 g  4 12 4 g  8 18 6 r  9  8 1 g 14  7 1 r
 20  6 1 g 22 20 6 r 23 10 1 g 28  9 1 r 30  0 4 g 34 22 6 g
 38 14 4 g 39  3 1 g ;BIO : demo FLU 70 30 2 b LIFE ;

 BIO: l5 0 0 0 c 1 0 0 c 2 0 0 c 3 0 0 c 4 0 0 c ;BIO
 BIO: 7l5 0 0 0 l5 6 0 0 l5 12 0 0 l5 18 0 0 l5 24 0 0 l5
 30 0 0 l5 36 0 0 l5 ;BIO : joli FLU 37 42 0 7l5 LIFE ;

 BIO: m1 0 0 0 c 0 1 0 c 1 2 0 c 2 2 0 c 3 2 0 c ;BIO

2VARIABLE #DEV
: 4TXT #OUT 2@ #DEV 2! #OUT 2! ;
: DONE #OUT 2@ CLOSE #DEV 2@ #OUT 2! ;
: DEDE
FLU ROT ROT 4TXT 25 5 2 b TIME 15 0 DO egg hen LOOP 2DUP TIME
D- 4 ROLL 0 DO I 30 * 45 + . 30 0 DO egg hen LOOP 2OVER TIME 
D- 2DUP D. 2SWAP 2OVER D- D. CR LOOP 2DROP 2DROP DONE
;

END_FILE
This program has two parts :
1/ from beginning to (& including) the definition of the function LAY, it implements exactly the same algorithm as shown in SuperBasic, a few posts above.
2/ after, it adds words for defining incrementally complex organisms : meaning that you may compose organisms with organisms with organisms etc.

For a start, let me just explain the first part : it's my solution for the famous issue of "hen vs egg". Look at the word LIFE, it repeats alternances of "egg" and "hen" - starting with "egg" (my opinion).

With ComputerOne FORTH, to stop the process at will, I used a convenient word ?TERMINAL reacting to a hit of the keyboard. This function is absent from SuperFORTH and I could only replace it with a call to KEYROW, that I coded (for speed) to work only with the space bar - and you have to hold it down till the function executes.

Beside the essential word LIFE, you have LAY a word to put an egg on a given square (a simple way to populate initially the world), and FLU a word to empty the whole world (the famous H4N1 avian flu virus).

To see this simulation running on a real QL or an emulator that uses the same display memory mapping, you have to install and start SuperFORTH, but if necessary - first thing :

Code: Select all

( Login block, called by COLD, modify as required )                                                                             
0 OPEN CON_503x256a4x0   ( the main console window )            
2DUP #IN 2! 2DUP #OUT 2!                                        
#DEFAULT CLOSE ' #DEFAULT >BODY 2!                              
4 MODE 0 PAPER 0 STRIP 4 INK 0 0 CSIZE 0 1 BORDER ( parameters )
MDV1_                                                           
( LOAD_FILE MDV1_EDITOR_FTH ) 
to edit BLK1 (the boot block) so that EDIT is NOT LOADED (commented out, as you see - with brackets) and the default window is enlarged as much as possible (minimum 503x256a4x0 - up to 512x256 if your monitor permits). Then restart it with these new boot settings.

Then load (compile) the program with command :

LOAD_FILE flp2_CONWAY_fth

and start the demo :

DEMO

Another "pretty" demo is started calling JOLI.

To time the execution, you may also use DEDE :

2 OPEN flp2_times 50 DEDE

that will write run times in a "new" text file for 50 surges of 30 generations (on a real QL, this takes time !) - each 30 generations a new "glider" is shot by the "bomber". Contrary to DEMO, DEDE cannot be stopped in the middle.

Have good entertainment !

BYE Paul


May the FORTH be with you !
POLKa
78squirel78
ROM Dongle
Posts: 22
Joined: Sat Oct 25, 2014 5:39 pm

Re: Conway's game of life

Post by 78squirel78 »

Hi,
I installed Q-emulator with SuperForth under Win8.
As I don't want to take your time, can you give me the way to program
Forth in the blocks.
I have a Superforth+Reversi PDF printed manual. But it is a reference
manual, NOT a user Guide.

Links are welcome, as I only found yours, and after having Jupiter_Aced
(I mean Power-it and type VLIST and Voilà !), I am a little bit lost, not about
Forth, but about QL behaviours for newbies like me !

Thank you to have taken time to read me !

Best regards,

Guy


tcat
Super Gold Card
Posts: 633
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: Conway's game of life

Post by tcat »

Hi Paul,

Just discovered your code with Conway's simulation. I am learning FORTH at the moment, and spotted DEMO and JOLI are not defined in the code, while DEDE is.

I wonder what DEDE and JOLI does?

EDIT> Now I see there are in lower case 'demo', 'joli', sorry.

Many thanks
Tom


Post Reply