![]() |
Forum Index : Microcontroller and PC projects : pi pico and Vegipetes game of life for GFXterm
Author | Message | ||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 5089 |
Dear Vegipete, For the pi pico I was testing your "game of life". Using GFXterm64 on linux. I have 2 questions 1/ With the normal starting (the Conway guy) after 20 gereations there is only an oscillator left. This will never stop. But when it reaches the wrap around at the border this oscillator stops. Apparently there is is a wrap around problem at the border. Someting in the "neighbours" function. 2/ When I seed the field with random values, after some generations I end up with some oscillators and some statics (i.e. isolated cubes of 4 cells). But at 50 generations they die, all of a sudden. I expect this is due to the w(i,j) = w(i,j) << 1 causing integers getting too big. And, btw, You have a main loop using variable i, and subroutines also using i. The mainloop i, I replaced with a variable z. The code I tested.... ' A short test program to play the Game of Life, invented ' by John Conway. Unfortunately, Covid19 took John's life ' on April 11, 2020. His legacy lives on in the coutless ' people inspired by his invention of the cellular automaton ' called the Game of Life and his other works. ' ' Written by vegipete, April 22, 2020 for use with GFXTerm. Option DEFAULT INTEGER Dim INTEGER i,j,count Dim INTEGER xs,ys Dim INTEGER sw,sh Dim string GFX$ Dim float w(41,41) GFX$ = Chr$(16) Print GFX$ "?" ' request size of GFXTerm Window Input sw,sh ' grab dimensions - width and height Print Chr$(27)+"[2J"; ' esc sequence to erase the text screen Print "Thank you John Conway. Rest in Peace." xs = 100: ys = 20 ' clear the world to start For i = 0 To 41 For j = 0 To 41 w(i,j) = 0 ' w(i,j) = 1+Rnd()*3 Next j Next i ' seed the world w(19,31) = 3 : w(20,31) = 3 : w(21,31) = 3 w(19,32) = 3 : w(21,32) = 3 w(19,33) = 3 : w(21,33) = 3 w(20,34) = 3 w(17,35) = 3 : w(19,35) = 3 : w(20,35) = 3: w(21,35) = 3 w(18,36) = 3 : w(20,36) = 3 : w(22,36) = 3 w(20,37) = 3 : w(23,37) = 3 w(19,38) = 3 : w(21,38) = 3 w(19,39) = 3 : w(21,39) = 3 showWorld Pause 2000 For z = 0 To 1000 ConwayLife showWorld Print z Next z End ' Calculate a new generation of life, using the classic rules Sub ConwayLife Local integer i,j,count ' wrap the corners w(0,0) = w(40,40) : w(41,41) = w(1,1) w(0,41) = w(40,1) : w(41,0) = w(1,40) ' wrap the edges For i = 1 To 40 w(0,i) = w(40,i) ' left w(41,i) = w(1,i) ' right w(i,0) = w(i,40) ' top w(i,41) = w(i,1) ' bottom Next i ' move most recent generation to previous and clear new generation For i = 1 To 40 For j = 1 To 40 w(i,j) = w(i,j) << 1 Next j Next i ' calculate new generation For i = 1 To 40 For j = 1 To 40 count = Neighbours(i,j) If (w(i,j) And 2) Then ' was cell alive last generation? ' yes so test if it stays alive If (count = 2) Or (count = 3) Then w(i,j) = w(i,j) + 1 ' cell remains alive for new generation EndIf Else ' no so test if it gets born If count = 3 Then w(i,j) = w(i,j) + 1 ' cell becomes alive for new generation EndIf EndIf Next j Next i End Sub ' return number of neighbours around given point Function Neighbours(x,y) Local count count = 0 If (w(x-1,y-1) And 2) Then count = count + 1 If (w(x+0,y-1) And 2) Then count = count + 1 If (w(x+1,y-1) And 2) Then count = count + 1 If (w(x-1,y+0) And 2) Then count = count + 1 If (w(x+1,y+0) And 2) Then count = count + 1 If (w(x-1,y+1) And 2) Then count = count + 1 If (w(x+0,y+1) And 2) Then count = count + 1 If (w(x+1,y+1) And 2) Then count = count + 1 Neighbours = count End Function ' display the current world Sub showWorld Local integer i,j xstart = 50 Print gfx$ "C" 0,0,sw,sh Print gfx$ "I" 255,255,0,4 For i = 1 To 40 For j = 1 To 40 If w(i,j) And 1 Then Print gfx$ "A" xs+10*i,ys+10*j,xs+6+10*i,ys+6+10*j,0,0 EndIf Next j Next i End Sub End Edited 2021-06-04 05:28 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
Shame on me. I see long ago I promised to repost with the edge wrap bug fixed but I never did. (Original posting here.) Here's a fixed version. Initially I ran it on a Mite170. Way too slow. Then I ran it on a MiteF4. Still rather slow. So over to a MaxiMite2 which is fast enough to see results. The eternal shift-array-elements-left should not cause any problem. The excess bits should just fall off the end. Although why I dimmed the w() array as FLOAT I don't know. INTEGER would make more sense, and indeed works fine on my CMM2. Indeed, the program just ran to completion (1001) iterations on my CMM2 with no error. In the subroutines, i and j are declared as LOCAL so they aren't supposed to interfere with main routine variable. ' A short test program to play the Game of Life, invented ' by John CONWAY. Unfortunately, Covid19 took John's life ' on April 11, 2020. His legacy lives on in the coutless ' people inspired by his invention of the cellular automaton ' called the Game of Life and his other works. ' ' Written by vegipete, April 22, 2020 for use with GFXTerm. Option DEFAULT INTEGER Dim INTEGER i,j,count Dim INTEGER xs,ys Dim INTEGER sw,sh Dim string GFX$ Dim float w(41,41) GFX$ = Chr$(16) Print GFX$ "?" ' request size of GFXTerm Window Input sw,sh ' grab dimensions - width and height Print Chr$(27)+"[2J"; ' esc sequence to erase the text screen Print "Thank you John CONWAY. Rest in Peace." xs = 100: ys = 20 ' clear the world to start For i = 0 To 41 For j = 0 To 41 w(i,j) = 0 Next j Next i ' seed the world w(19,31) = 3 : w(20,31) = 3 : w(21,31) = 3 w(19,32) = 3 : w(21,32) = 3 w(19,33) = 3 : w(21,33) = 3 w(20,34) = 3 w(17,35) = 3 : w(19,35) = 3 : w(20,35) = 3: w(21,35) = 3 w(18,36) = 3 : w(20,36) = 3 : w(22,36) = 3 w(20,37) = 3 : w(23,37) = 3 w(19,38) = 3 : w(21,38) = 3 w(19,39) = 3 : w(21,39) = 3 showWorld Pause 2000 For i = 0 To 1000 CONWAYLife showWorld Next i End ' Calculate a new generation of life, using the classic rules Sub CONWAYLife Local integer i,j,count ' move most recent generation to previous and clear new geneartion For i = 1 To 40 For j = 1 To 40 w(i,j) = w(i,j) << 1 Next j Next i ' wrap the corners w(0,0) = w(40,40) : w(41,41) = w(1,1) w(0,41) = w(40,1) : w(41,0) = w(1,40) ' wrap the edges For i = 1 To 40 w(0,i) = w(40,i) ' left w(41,i) = w(1,i) ' right w(i,0) = w(i,40) ' top w(i,41) = w(i,1) ' bottom Next i ' calculate new generation For i = 1 To 40 For j = 1 To 40 count = Neighbours(i,j) If (w(i,j) And 2) Then ' was cell alive last generation? ' yes so test if it stays alive If (count = 2) Or (count = 3) Then w(i,j) = w(i,j) + 1 ' cell remains alive for new generation EndIf Else ' no so test if it gets born If count = 3 Then w(i,j) = w(i,j) + 1 ' cell becomes alive for new generation EndIf EndIf Next j Next i End Sub ' return number of neighbours around given point Function Neighbours(x,y) Local count count = 0 If (w(x-1,y-1) And 2) Then count = count + 1 If (w(x+0,y-1) And 2) Then count = count + 1 If (w(x+1,y-1) And 2) Then count = count + 1 If (w(x-1,y+0) And 2) Then count = count + 1 If (w(x+1,y+0) And 2) Then count = count + 1 If (w(x-1,y+1) And 2) Then count = count + 1 If (w(x+0,y+1) And 2) Then count = count + 1 If (w(x+1,y+1) And 2) Then count = count + 1 Neighbours = count End Function ' display the current world Sub showWorld Local integer i,j xstart = 50 Print gfx$ "C" 0,0,sw,sh Print gfx$ "I" 0,0,255,4 For i = 1 To 40 For j = 1 To 40 If w(i,j) And 1 Then Print gfx$ "A" xs+10*i,ys+10*j,xs+6+10*i,ys+6+10*j,0,0 EndIf Next j Next i End Sub End Visit Vegipete's *Mite Library for cool programs. |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 5089 |
Hi Vegipete, Please look at following behaviour. Running your game on a pi pico. I printed the generation number left on screen, so you can see why it is strange. This is generation 50 from a random seeded field. The red circles are oscillators, they only die when they get corrupted. These are quite isolated, so it will take a few generations before they should get corrupted. The green circles are statics, these will no change shape, but may die if something gets near to them. Now look at generation 51. This is a total different world. Needless to say that generation 52 is a empty field. But what is happening between generation 50 and 51. And apparently this does not happen on a CMM2 ? I fear there is something strange in the math on the pi pico. The code: ' A short test program to play the Game of Life, invented ' by John CONWAY. Unfortunately, Covid19 took John's life ' on April 11, 2020. His legacy lives on in the coutless ' people inspired by his invention of the cellular automaton ' called the Game of Life and his other works. ' ' Written by vegipete, April 22, 2020 for use with GFXTerm. Option DEFAULT INTEGER Dim INTEGER i,j,count Dim INTEGER xs,ys Dim INTEGER sw,sh Dim string GFX$ Dim float w(41,41) GFX$ = Chr$(16) Print GFX$ "?" ' request size of GFXTerm Window Input sw,sh ' grab dimensions - width and height Print Chr$(27)+"[2J"; ' esc sequence to erase the text screen Print "Thank you John CONWAY. Rest in Peace." xs = 100: ys = 20 ' clear the world to start For i = 0 To 41 For j = 0 To 41 'w(i,j) = 0 w(i,j) = 1+Rnd()*3 Next j Next i ' seed the world w(19,31) = 3 : w(20,31) = 3 : w(21,31) = 3 w(19,32) = 3 : w(21,32) = 3 w(19,33) = 3 : w(21,33) = 3 w(20,34) = 3 w(17,35) = 3 : w(19,35) = 3 : w(20,35) = 3: w(21,35) = 3 w(18,36) = 3 : w(20,36) = 3 : w(22,36) = 3 w(20,37) = 3 : w(23,37) = 3 w(19,38) = 3 : w(21,38) = 3 w(19,39) = 3 : w(21,39) = 3 showWorld 'Pause 2000 For i = 0 To 1000 CONWAYLife showWorld Print i If i>49 Then Input a$ EndIf Next i End ' Calculate a new generation of life, using the classic rules Sub CONWAYLife Local integer i,j,count ' move most recent generation to previous and clear new geneartion For i = 1 To 40 For j = 1 To 40 w(i,j) = w(i,j) << 1 Next j Next i ' wrap the corners w(0,0) = w(40,40) : w(41,41) = w(1,1) w(0,41) = w(40,1) : w(41,0) = w(1,40) ' wrap the edges For i = 1 To 40 w(0,i) = w(40,i) ' left w(41,i) = w(1,i) ' right w(i,0) = w(i,40) ' top w(i,41) = w(i,1) ' bottom Next i ' calculate new generation For i = 1 To 40 For j = 1 To 40 count = Neighbours(i,j) If (w(i,j) And 2) Then ' was cell alive last generation? ' yes so test if it stays alive If (count = 2) Or (count = 3) Then w(i,j) = w(i,j) + 1 ' cell remains alive for new generation EndIf Else ' no so test if it gets born If count = 3 Then w(i,j) = w(i,j) + 1 ' cell becomes alive for new generation EndIf EndIf Next j Next i End Sub ' return number of neighbours around given point Function Neighbours(x,y) Local count count = 0 If (w(x-1,y-1) And 2) Then count = count + 1 If (w(x+0,y-1) And 2) Then count = count + 1 If (w(x+1,y-1) And 2) Then count = count + 1 If (w(x-1,y+0) And 2) Then count = count + 1 If (w(x+1,y+0) And 2) Then count = count + 1 If (w(x-1,y+1) And 2) Then count = count + 1 If (w(x+0,y+1) And 2) Then count = count + 1 If (w(x+1,y+1) And 2) Then count = count + 1 Neighbours = count End Function ' display the current world Sub showWorld Local integer i,j xstart = 50 Print gfx$ "C" 0,0,sw,sh Print gfx$ "I" 255,255,0,4 For i = 1 To 40 For j = 1 To 40 If w(i,j) And 1 Then Print gfx$ "A" xs+10*i,ys+10*j,xs+6+10*i,ys+6+10*j,0,0 EndIf Next j Next i End Sub End EDIT: tried the same on an MX170. It dies at generation 22. It must have something to do with the size of the floats/integers. When I change the array from float to integer, the game continues. Must have something to do with bit shifting a float variable. Volhout Edited 2021-06-04 21:18 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
I suppose it depends on how << is implemented in the various firmwares. If it is implemented as *2 then I can see why shifting floats would mess up. I just tried this on a CMM2: 'dim float i=1, j=1 ' change commenting to test different variable types and none of the results make sense compared to how the above Conway Life program runs.dim integer i=1, j=1 do i = i << 1 j = j * 2 print i,j do : loop until inkey$ <> "" loop Perhaps the line w(i,j) = w(i,j) << 1 should be changed to something likew(i,j) = (w(i,j) << 1) AND 254 (Untested)Using '254' would save the previous 7 generations in case someone wanted to implement, say, fading colours as dead cells decay away. Visit Vegipete's *Mite Library for cool programs. |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3378 |
Volhout (or vegipete)--can you post your picomite Game of Life program if it's now working? PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |