Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Conway’s game of life
Page 2 of 3 | |||||
Author | Message | ||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4271 |
Hi Jim, Your code works fine on an MX170 (2873ms) and an Armmite F4 (1235ms). No changes needed. Regards, Volhout P.S. nice to see life develop, in the end there are only stable blocks and oscillators. Occasionally a traveler that rips it all up. And the unpredictability. You think it died out, and 4 generations later you are looking at hundreds of yellow cells. This must be why they are hesitant to lift the Corona restrictions.... How appropriate to play with this in Corona time. PicomiteVGA PETSCII ROBOTS |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Hey Jim, ... and the INTEGER and FLOAT keywords removing and the SELECT/CASE structure replacing entirely. The Maximite's use MMBasic 4.5, not 5.x ... unless there is a Firmware update I haven't noticed? Oh, and you've reverted to the brute force method of calculating the adjacent cells instead of using my optimised version Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6108 |
My main interest was having the various displays working. I remembered the INTEGER/FLOAT difference after posting but forgot totally about SELECT I intend to try your optimization again now I have a working version with timing included. It will be interesting to see what the improvement is on the faster processors. Jim VK7JH MMedit  MMBasic Help |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
When I started this I was working towards a Maximite version. I started with the DOS MMBasic version to prove the algorithm and didn't fully realise how blindingly fast the DOS version is compared to the 'Mite versions. The Micromite with TeraTerm version is a lot faster, and then Tom's clever algorithm improved the speed even further. Jim's three dimension array and flip-flop toggle to switch between two arrays simplified the program. It's a pity that there is no MMBasic 5 for the Maximite. I suspect that if there was then an awful lot of existing Maximite programs and games would not work without modification but I, for one, wouldn't mind that. It could spawn a new area of creativity and learning. Jim, thank you for the extra demo entries it was something that I was going to do as well - with a view to providing an editor for creating and saving startup screens. Unfortunately for me I only have the original MM backpack and I don't think that would do your version justice. In the quest for speed, for the NextGen sub I am going to use only global variables, reduce their names to single letters where they are not and declare them at the very beginning of the program. Also investigate the use of a font rather than draw circles. Bill Keep safe. Live long and prosper. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6108 |
I did try that. In the draw_cell() sub, there is a text printing line commented out. Simply uncomment that line and comment the circle drawing line. With the drawing circles: On my H7, seed pattern 5 gives a time of 234mS per generation and pattern 6 gives 250mS. With printing "O" On my H7, seed pattern 5 gives a time of 224mS per generation and pattern 6 gives 230mS. So, text is a little faster but not by much on the H7. After that, I didn't bother drawing a bug shaped font. I am sure that different 'mites will show a greater improvement using text. Jim VK7JH MMedit  MMBasic Help |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Hi Bill, Ignoring the global/local question I'm not sure it matters where you declare them, it is the order that is significant because lookup uses a traversal through the list in the order they were declared. You probably want something like: mw = ... ' matrix width mh = ... ' matrix height Dim m(mw+1,mh+1,1) ' matrix of life x = 0 : y = 0 ' column and row iterators a = 0 : b = 0 : c = 0 : d = 0 ' used to calculate adjacencies ... That's assuming there is no equivalent of a ReDim statement in which case you could declare 'm' using dummy dimensions, put 'mw' and 'mh' later in the list and correct the dimensions of 'm' later. Or you could just declare 'm' to be BIG to start with and then only use a limited window on it, e.g. Dim m(60,60,1) ' 28K of matrix - Gulp! x = 0 : y = 0 ' column and row iterators a = 0 : b = 0 : c = 0 : d = 0 ' used to calculate adjacencies mw = ... ' matrix width mh = ... ' matrix height If mw > 59 Then Error "Matrix width must be <= 59" If mh > 59 Then Error "Matrix height must be <= 59" ... I also have some other options to explore for speeding up the graphics if/when you want to discuss them. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
I suppose that's due to calculating the position of each "O" as you print it. I personally like the visual effect of calculating the whole next generation and then printing it all at once (as in my LifeC01). The pause while calculating the next generation and the quick update allows you to digest the current pattern and the effect of the update. The different colours could still be catered for but I find them confusing. Regarding variables: Yes, that's what I meant. To declare them before any other variables. Dim m(60,60,1) ' 28K of matrix - Gulp! x = 0 : y = 0 ' column and row iterators a = 0 : b = 0 : c = 0 : d = 0 ' used to calculate adjacencies Again, this is what I meant. I don't know how you can check on the dimensions after the array has been dimensioned except maybe by PEEKing at it somehow. That's a bit much for me tonight. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Well I made the changes as above to my Maximite version of Life. Using Jims timing method the times were roughly: 970 mS the original with no crunch 960 mS the original with crunch on load and remove blank lines 940 mS the modified version with crunch on load and remove blank lines and remove non-mandatory spaces. Less improvement than I had hoped for and I'm too old to learn C. So I've left it as is. Bill Keep safe. Live long and prosper. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6108 |
Still not for the Maximite but I have added a counter and the option to toggle display wrapping on/off ' John Conway's Game of Life for Micromite MMBasic ' Bill McKinley ' adapted by TassyJim DIM Bx$ DIM INTEGER MatX = 40 ' Matrix horizontal size DIM MatY ' Matrix vertical size - gets calculated later depending on screen size DIM FLOAT RandL = 0.3 ' For random life. less than =< RandL means there is life ' Make it high and you get a lot of cells but they die quickly DIM PT = 000 ' Pause time in mS between display updates DIM INTEGER initialPause = 3000 ' time to display starting pattern DIM INTEGER DIAM, a, b = 1, gen DIM INTEGER dying, dyingOn = RGB(127,0,0) DIM INTEGER wrap DIM FLOAT rate DIAM = MM.HRES/matX MatY = INT( MatX *MM.VRES/MM.HRES) ' Zero based matrix has one more cell all round than is displayed DIM M(MatX+1, MatY+1,2) ' The matrix of life DO ChkScr ' Print intro IF Bx$ = "Q" OR Bx$ = "q" THEN EXIT DO CLS InitM ' Initialize the random matrix (or demo) initial_gen PAUSE initialPause TIMER = 0 ' reset for next timer DO ' Program loop NextGen ' Calculate the next generation PAUSE PT rate = TIMER - PT TIMER = 0 LOOP UNTIL INKEY$ <> "" ' loop forever or until a keypres LOOP SUB ChkScr ' Print intro DO CLS PRINT " CONWAY'S GAME OF LIFE" PRINT " Press a key to start " PRINT " and another to stop " PRINT " W to wrap display " PRINT " 0-9 for a demo " PRINT " Q to quit " DO Bx$ = INKEY$ LOOP UNTIL Bx$ <> "" IF Bx$ = "W" OR Bx$ = "w" THEN ' toggle display wrapping wrap = 1 - wrap ENDIF LOOP UNTIL Bx$ <> "W" AND Bx$ <> "w" ' loop if last command was toggle wrap END SUB SUB InitM ' Initialise the matrix of life LOCAL INTEGER x,y FOR y = 1 TO MatY FOR x = 1 TO MatX M(x, y, b) = 0 NEXT x NEXT y x = 0 rate = 0 gen = 0 SELECT CASE Bx$ CASE "1" ' glider RESTORE seed1 CASE "2" ' blinker RESTORE seed2 CASE "3" ' toad RESTORE seed3 CASE "4" ' beacon RESTORE seed4 CASE "5" 'Penta-decathlon RESTORE seed5 CASE "6" ' pulsar RESTORE seed6 CASE "7" ' RESTORE seed7 CASE "8" ' RESTORE seed8 CASE "9" ' RESTORE seed9 CASE "0" ' diehard RESTORE seed0 CASE "Q","q" ' do nothing x = -1 CASE ELSE ' random set FOR y = 2 TO MatY-1 FOR x = 2 TO MatX-1 IF RND() <= RandL THEN M(x, y, b) = 1 ELSE M(x, y, b) = 0 ENDIF NEXT x NEXT y dying = dyingOn END SELECT IF x = 0 THEN ' we need to read a set configuration DO READ x READ y IF x = -1 THEN EXIT DO IF y = -1 THEN PRINT "Error in Data",x,y: EXIT DO M(x, y, b) = 1 LOOP dying = y*dyingOn ENDIF END SUB SUB initial_gen FOR y = 1 TO MatY FOR x = 1 TO MatX IF M(x, y, b) = 1 THEN draw_cell(x, y, RGB(YELLOW)) ENDIF NEXT x NEXT y END SUB SUB NextGen ' Breed the next generation LOCAL INTEGER x, y, d, i a = 1 - a b = 1 - a gen = gen + 1 IF wrap = 1 THEN ' wrap the corners M(0,0, a) = M(MatX,MatY, a) M(MatX+1,MatY+1, a) = M(1,1, a) M(0,MatY+1, a) = M(MatX,1, a) M(MatX+1,0, a) = M(1,MatY, a) ' wrap the edges FOR i = 1 TO MatX M(i,0, a) = M(i,MatY, a) ' top M(i,MatY+1, a) = M(i,1, a) ' bottom NEXT i FOR i = 1 TO MatY M(0,i, a) = M(MatX,i, a) ' left M(matX+1,i, a) = M(1,i, a) ' right NEXT i ENDIF FOR y = 1 TO MatY IF y = 2 THEN TEXT 1,1,STR$(gen,10)+" "+STR$(rate,5,0) FOR x = 1 TO MatX d = M(x-1,y-1,a) + M(x-1,y,a) + M(x-1,y+1,a) d = d + M(x,y-1,a) + M(x,y+1, a) d = d + M(x+1,y-1,a) + M(x+1,y,a) + M(x+1,y+1,a) d = d MOD 10 IF M(x,y,a) = 1 THEN IF d = 2 OR d = 3 THEN draw_cell(x,y, RGB(GREEN)) M(x,y,b) = 1 ELSE draw_cell(x,y, dying) M(x,y, b) = 10 ' flag this cell to be cleared next generation ENDIF ELSE IF d = 3 THEN draw_cell(x,y, RGB(YELLOW)) M(x,y,b) = 1 ELSE IF M(x,y,a) = 10 THEN draw_cell(x,y, 0) M(x,y,b) = 0 ENDIF ENDIF NEXT x NEXT y END SUB SUB draw_cell(x, y, col) CIRCLE (x - 0.5) * DIAM, (y - 0.5) * DIAM, DIAM/2 - 2, 1,,col, col 'text x * DIAM, y * DIAM,"O","LT",1,1,col ', col END SUB ' seeds are pairs of x,y cells ending in -1 then 0 or 1 for coloured dying cells seed1: ' glider DATA 4,7,5,7,6,7,6,6,5,5,-1,0 seed2: ' blinker DATA 4,7,5,7,6,7,-1,0 seed3: ' toad DATA 5,7,6,7,7,7,4,8,5,8,6,8,-1,0 seed4: ' beacon DATA 4,7,5,7,4,8,7,9,6,10,7,10,-1,0 seed5: 'Penta-decathlon DATA 5, 7,6, 7,7, 7,5, 8,7, 8,5, 9,6, 9,7, 9 DATA 5, 10,6, 10,7, 10,5, 11,6, 11,7, 11,5, 12 DATA 6, 12,7, 12,5, 13,7, 13,5, 14,6, 14,7, 14,-1,1 seed6: ' pulsar DATA 5,3,6,3,7,3,11,3,12,3,13,3,3,5,8,5,10,5,15,5 DATA 3,6,8,6,10,6,15,6,3,7,8,7,10,7,15,7 DATA 5,8,6,8,7,8,11,8,12,8,13,8,5,10,6,10,7,10,11,10,12,10,13,10 DATA 3,11,8,11,10,11,15,11,3,12,8,12,10,12,15,12 DATA 3,13,8,13,10,13,15,13,5,15,6,15,7,15,11,15,12,15,13,15 DATA -1, 1 seed7: ' LW spaceship DATA 3,2,6,2,7,3,3,4,7,4,4,5,5,5,6,5,7,5,-1,1 seed8: ' MW spaceship DATA 5,2,3,3,7,3,8,4,3,5,8,5,4,6,5,6,6,6,7,6,8,6,-1,1 seed9: ' HW spaceship DATA 7,4,8,4,3,5,4,5,5,5,6,5,8,5,9,5,3,6,4,6,5,6,6,6,7,6,8,6 DATA 4,7,5,7,6,7,7,7,-1,1 seed0: 'diehard DATA 8,5,2,6,3,6,4,6,7,7,8,7,9,7,-1,1 Jim VK7JH MMedit  MMBasic Help |
||||
GerryL Newbie Joined: 24/01/2019 Location: AustraliaPosts: 33 |
I thought I posted this yesterday but it must have got lost, Last year I started on a windows based C++ program (a MMBasic GUI editor) but it’s been 20 years since I undertook any programming in a Windows environment and not being a programmer I soon realized I needed to do a lot of catch up on all the changes to the language, especially in the standard template library area. Consequently, I looked for another project without Windows GUI overheads to update my skills and so created a console program that would optimise a MMBasic program so the interpreter could digest the code quicker. My draft optimizer does the following: 1. Substitutes the CONST value directly into the code statement and so CONST statements are removed. If the value of the CONST is an equation this is resolved to a value prior to substitution. If MM.VRES or MM.HRES are part of the equation the optimiser asks these to be entered. 2. LOCAL and STATIC variables are turned into global variables. If a LOCAL variable is initialised to a value in the declaration then a statement gets added to the start of the SUB/FUNC to ensure it is still initialised. STATIC and global initialisation remain. Variables that are not specifically declared in a program (created on the fly) are formally declared as global depending on their suffix ($!%) or if not present the OPTION setting (float is default). This essentially makes the program similar to OPTION EXPLICIT. 3. All variables are assessed for the number of times they are used. If a variable is used in a FOR/DO loop (including variables in SUB/FUNC called within the loop) then they are given a default usage of 20, if there is nested FOR/DO variables then they would get a usage of 400 etc. The use of the value 20 is arbitrary. 4. The variables are then declared based on usage with the highest usage variables declared first. 5. Variables are then renamed, starting with the first 26 of A,B ..Z, next 26 AA,BA.. ZA etc. 6. SUB and FUNCTION names are renamed to a 3 character code starting at ZZZ, WZZ etc. Note that all renaming avoids any built-in commands/functions. SUB and FUNCTION declaration parameters are also renamed. 7. Remove comments and any surplus spaces. This creates MMBasic code that is pretty hard to follow, so you need to ensure you have all the bugs out before optimizing. I ran TassyJims version of Game of Life (the version posted on 29 April) through my "optimiser' and then ran it on my H7 using Seed pattern 5. Results are, Un-optimised code time = 230 msecs (similar ballpark to TassyJim’s time). Note I did add a do loop to clear the INKEY$ prior to the actual life loop as it was only doing one iteration due to a character being in the in buffer for some reason. Optimised the original code giving a code time = 213 msecs. I then changed the variables that did not change once initialised to CONST's to take advantage of item 1 above and the time after optimisation came down to 206 msecs. Although you gain some improvement in speed (in this case about 10%) optimised code does not make a big difference, and I suspect that is because the way MMBasic reads the code lines and looks up variables is very efficient (or I missed something in understanding whats going on in MMBasic or in the way I optimized the code). Whatever, I gained a lot out of the excercise and will now get back to my original project. Just as a side issue I first came across the Game of Life back in the 1990’s as part of a demo to a DOS based scientific data acquisition software package called ASYST. It was similar to BASIC but used a stack for data entry so data was entered in reverse polish notation. It came with some pretty powerful built in maths and graphics commands so you could do some amazing stuff with just a few lines of code. If you had very deep pockets you could purchase the compiler. Unfortunately, it never progressed into the Windows environment and was superseded by a National Instruments product. Below is the optimized copy of TassyJims version of Game of Life (posted on 29 April), DIM FLOAT A(40+1,24+1,2) DIM INTEGER B DIM INTEGER C DIM INTEGER D DIM INTEGER E DIM INTEGER F DIM INTEGER G = 1 DIM INTEGER H DIM FLOAT L DIM FLOAT M DIM INTEGER N DIM INTEGER O DIM STRING P DIM INTEGER Q DO ZZZ IF P = "Q" OR P = "q" THEN EXIT DO CLS YZZ XZZ PAUSE 3000 TIMER=0 O=0 DO LOOP UNTIL INKEY$ <> "" DO WZZ PAUSE 0 O=O+1 IF O=40 THEN PRINT TIMER/40 LOOP UNTIL INKEY$ <> "" LOOP SUB ZZZ CLS PRINT " CONWAY'S GAME OF LIFE" PRINT " Press a key to start " PRINT " and another to stop " PRINT " 0-9 for a demo" PRINT " Q to quit " DO P=INKEY$ LOOP UNTIL P <> "" END SUB SUB YZZ FOR B=1 TO 24 FOR E=1 TO 40 A(E,B,G)=0 NEXT E NEXT B E=0 SELECT CASE P CASE "1" RESTORE SEED1 CASE "2" RESTORE SEED2 CASE "3" RESTORE SEED3 CASE "4" RESTORE SEED4 CASE "5" RESTORE SEED5 CASE "6" RESTORE SEED6 CASE "7" RESTORE SEED7 CASE "8" RESTORE SEED8 CASE "9" RESTORE SEED9 CASE "0" RESTORE SEED0 CASE "Q","q" E=-1 CASE ELSE FOR B=1 TO 24 FOR E=1 TO 40 IF RND()<=0.3 THEN A(E,B,G)=1 ELSE A(E,B,G)=0 ENDIF NEXT E NEXT B END SELECT IF E=0 THEN DO READ E READ B IF E=-1 THEN EXIT DO IF B = -1 THEN PRINT "Error in Data",E,B: EXIT DO A(E,B,G)=1 LOOP N=B*8323072 ENDIF END SUB SUB XZZ FOR M=1 TO 24 FOR L=1 TO 40 IF A(L,M,G)=1 THEN VZZ(L,M,RGB(YELLOW)) ENDIF NEXT L NEXT M END SUB SUB WZZ F=1-F G=1-F FOR D=1 TO 24 FOR C=1 TO 40 H=A(C-1,D-1,F)+A(C-1,D,F)+A(C-1,D+1,F) H=H+A(C,D-1,F)+A(C,D+1,F) H=H+A(C+1,D-1,F)+A(C+1,D,F)+A(C+1,D+1,F) H=H MOD 10 IF A(C,D,F)=1 THEN IF H=2 OR H=3 THEN VZZ(C,D,RGB(GREEN)) A(C,D,G)=1 ELSE VZZ(C,D,N) A(C,D,G)=10 ENDIF ELSE IF H=3 THEN VZZ(C,D,RGB(YELLOW)) A(C,D,G)=1 ELSE IF A(C,D,F)=10 THEN VZZ(C,D,RGB(BLACK)) A(C,D,G)=0 ENDIF ENDIF NEXT C NEXT D END SUB SUB VZZ(J,K,I) CIRCLE(J-0.5)*20,(K-0.5)*20,20/2-2,1,,I,I END SUB SEED1: DATA 4,7,5,7,6,7,6,6,5,5,-1,0 SEED2: DATA 4,7,5,7,6,7,-1,0 SEED3: DATA 5,7,6,7,7,7,4,8,5,8,6,8,-1,0 SEED4: DATA 4,7,5,7,4,8,7,9,6,10,7,10,-1,0 SEED5: DATA 5,7,6,7,7,7,5,8,7,8,5,9,6,9,7,9 DATA 5,10,6,10,7,10,5,11,6,11,7,11,5,12 DATA 6,12,7,12,5,13,7,13,5,14,6,14,7,14,-1,1 SEED6: DATA 5,3,6,3,7,3,11,3,12,3,13,3,3,5,8,5,10,5,15,5 DATA 3,6,8,6,10,6,15,6,3,7,8,7,10,7,15,7 DATA 5,8,6,8,7,8,11,8,12,8,13,8,5,10,6,10,7,10,11,10,12,10,13,10 DATA 3,11,8,11,10,11,15,11,3,12,8,12,10,12,15,12 DATA 3,13,8,13,10,13,15,13,5,15,6,15,7,15,11,15,12,15,13,15 DATA-1,1 SEED7: DATA 3,2,6,2,7,3,3,4,7,4,4,5,5,5,6,5,7,5,-1,1 SEED8: DATA 5,2,3,3,7,3,8,4,3,5,8,5,4,6,5,6,6,6,7,6,8,6,-1,1 SEED9: DATA 7,4,8,4,3,5,4,5,5,5,6,5,8,5,9,5,3,6,4,6,5,6,6,6,7,6,8,6 DATA 4,7,5,7,6,7,7,7,-1,1 SEED0: DATA 8,2,2,3,3,3,4,3,7,4,8,4,9,4,-1,1 |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
I just stumbled across this. I have not tried it yet. Bill Keep safe. Live long and prosper. |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3820 |
This: "2. LOCAL and STATIC variables are turned into global variables." Will break many programs. John |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Here is another version of the text version of Life. Will run on the Micromite MkII with TeraTerm, MMBasic for DOS, the CMM and hopefully the CMM2. It uses MM.DEVICE$ to determine which device is running it. TassyJim's demos are included as well. If someone can verify that it works on the CMM2 that would be good too. LifeD06.zip I might have tried to get in running on an LCD screen but I don't know how to detect if one is fitted. There may be a way to do that but I haven't found it. Bill Keep safe. Live long and prosper. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6108 |
Line 79 gives an error randomize timer randomize is not used. Random number generator doesn't need it. Apart from that, it does run on the CMM2 Jim VK7JH MMedit  MMBasic Help |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9172 |
Note for CMM2 To avoid the screen updating in a wave you can use the CMM2 framebuffers as follows: At top of program PAGE WRITE 1 This tells the program that all output will go to framebuffer no. 1. The display always shows no. 0 After each generation is calculated PAGE COPY 1 to 0,B This copies framebuffer 1 to framebuffer 0 and the image is instantly updated. The optional parameter "B" tells the copy to wait for frameblanking before starting the copy to ensure there are no tearing effects. For any resolution the copy is much faster than the framerate (60Hz @ 800x600 or 75HZ for all other resolutions) |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Jim, how many frames per second are you getting on the CMM2. I was idly wondering if a BASIC implementation of the Another World VM might be possible on the CMM2 ... but I suspect you need to be able to fill 1000 polygons at 20 FPS. Might have to aim lower and consider Elite instead. Regards, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Thanks Jim, I hope that replacing line 79 with: if DV <> 2 then randomize timer will fix that. Thanks Peter (Matherp), That would be exactly the effect I want. I hoped the 'wave' effect would not be so noticeable on the CMM2 because of its speed. Although I am excited with the CMM2 I am afraid that the more clever things it can do will be a bit beyond a hack like me. Bill Keep safe. Live long and prosper. |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9172 |
This is better: if MM.device$<>"Colour Maximite 2" and left$(mm.device$,3)<> "ARM" then randomize timer All the Armmites have a H/W random number generator Edited 2020-05-08 20:21 by matherp |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
And we are back where we started with Life running on an LED matrix: It's Life Bill ... Admittedly not as big as the LED matrix Bill originally pointed me at, but size isn't everything Code to follow later once I've tidied it to my liking. Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
...but not as we know it I'm impressed with the speed of updates. It looks like you can send the data to the devices with the display unchanged and latch the outputs with a single instruction? Have you seen this post? Bill Keep safe. Live long and prosper. |
||||
Page 2 of 3 |
Print this page |