Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:11 01 Aug 2025 Privacy Policy
Jump to

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 : pi pico and Vegipetes game of life for GFXterm

Author Message
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5089
Posted: 07:24pm 03 Jun 2021
Copy link to clipboard 
Print this post

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: Canada
Posts: 1132
Posted: 02:27am 04 Jun 2021
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 5089
Posted: 10:54am 04 Jun 2021
Copy link to clipboard 
Print this post

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: Canada
Posts: 1132
Posted: 03:39pm 04 Jun 2021
Copy link to clipboard 
Print this post

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
dim integer i=1, j=1

do
 i = i << 1
 j = j * 2
 print i,j
 do : loop until inkey$ <> ""
loop
and none of the results make sense compared to how the above Conway Life program runs.

Perhaps the line
w(i,j) = w(i,j) << 1
should be changed to something like
w(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 States
Posts: 3378
Posted: 04:52pm 08 Jun 2021
Copy link to clipboard 
Print this post

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
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025