Conway's Game of Life

Conway’s Game of Life

Commands:

ESC to exit the game

R to reseed

C to clear

PAUSE to pause/resume the game

CONST CELL = 10 Higher the number, bigger the cell, faster the game

CONST INIT_FILL_PCT = 25 Variables to play with

CONST STATUS_EVERY = 1 Variables to play with

' Conway's Game of Life (PicoCalc / MMBasic)


OPTION DEFAULT INTEGER
RANDOMIZE TIMER

'-----------------------------
' Config
'-----------------------------
CONST SCRW = MM.HRES
CONST SCRH = MM.VRES
CONST CELL = 10                 ' Try 10 or 8 for speed; 5 if you want more detail (slower)
CONST W = SCRW \ CELL
CONST H = SCRH \ CELL

' Colors
CONST wt = RGB(WHITE)
CONST bk = RGB(BLACK)

CONST INIT_FILL_PCT = 25
CONST STATUS_EVERY = 1

DIM a(W-1, H-1)     ' current
DIM b(W-1, H-1)     ' next
DIM gen, running, upd


running = 1
CLS bk

'-----------------------------
' Seed/Clear
'-----------------------------
SUB SeedRandom(pct%)
  LOCAL x, y
  FOR y = 0 TO H-1
    FOR x = 0 TO W-1
      a(x,y) = (RND * 100 < pct%)
    NEXT x
  NEXT y
END SUB

SUB ClearAll
  LOCAL x, y
  FOR y = 0 TO H-1
    FOR x = 0 TO W-1
      a(x,y) = 0
    NEXT x
  NEXT y
END SUB

'-----------------------------
' Draw
'-----------------------------
SUB DrawCell(x, y, alive)
  LOCAL x1, y1, c
  IF alive THEN c = wt ELSE c = bk
  x1 = x * CELL
  y1 = y * CELL
   BOX x1, y1, CELL, CELL, , c, c
END SUB

SUB DrawAll
  LOCAL x, y
  FOR y = 0 TO H-1
    FOR x = 0 TO W-1
      DrawCell x, y, a(x,y)
    NEXT x
  NEXT y
END SUB

SUB StatusBar
  ' redraw occasionally to avoid extra drawing overhead
  BOX 0, 0, 140, 12, , bk, bk
  TEXT 2, 2, "Gen:" + STR$(gen)
  IF running THEN
    TEXT 60, 2, "Run"
  ELSE
    TEXT 60, 2, "Pause"
  ENDIF
END SUB

'-----------------------------
' Init
'-----------------------------
SeedRandom INIT_FILL_PCT
DrawAll
gen = 0
upd = 0
StatusBar

'-----------------------------
' Main loop
'-----------------------------
DO
  ' input (non-blocking)
  k$ = INKEY$
  IF k$ <> "" THEN
    SELECT CASE UCASE$(k$)
      CASE " "         ' pause/resume
        running = 1 - running
        StatusBar
      CASE "R"         ' reseed
        SeedRandom INIT_FILL_PCT
        DrawAll
        gen = 0: upd = 0
        StatusBar
      CASE "C"         ' clear
        ClearAll
        DrawAll
        gen = 0: upd = 0
        StatusBar
      CASE CHR$(27)    ' Esc
        CLS bk
        END
        
    END SELECT
  ENDIF

  IF running THEN
    ' ----- compute next gen into b(), inline neighbor counting with wrap -----
    FOR y = 0 TO H-1
      ym = y - 1: IF ym < 0 THEN ym = H - 1
      yp = y + 1: IF yp = H THEN yp = 0
      FOR x = 0 TO W-1
        xm = x - 1: IF xm < 0 THEN xm = W - 1
        xp = x + 1: IF xp = W THEN xp = 0

        n = a(xm,ym) + a(x,ym) + a(xp,ym) + a(xm,y) + a(xp,y) + a(xm,yp) + a(x,yp) + a(xp,yp)

        IF a(x,y) THEN
          b(x,y) = (n = 2) OR (n = 3)
        ELSE
          b(x,y) = (n = 3)
        ENDIF
      NEXT x
    NEXT y

    ' ----- draw only the cells that changed -----
    FOR y = 0 TO H-1
      FOR x = 0 TO W-1
        IF b(x,y) <> a(x,y) THEN DrawCell x, y, b(x,y)
      NEXT x
    NEXT y

    ' ----- copy b -> a -----
    FOR y = 0 TO H-1
      FOR x = 0 TO W-1
        a(x,y) = b(x,y)
      NEXT x
    NEXT y

    gen = gen + 1
    upd = upd + 1
    IF upd >= STATUS_EVERY THEN
      upd = 0
      StatusBar
    ENDIF
  ENDIF

  ' No PAUSE for max speed; add "PAUSE 1" if you want to throttle
LOOP

24 Likes

If it isn’t implemented yet, can you make it so that you can draw cells, rather than having them all be random?

Thanks.

Hi!

The code is public. You can make that yourself. If you are like myself and don’t know how to code (especially BASIC), just ask AI to change the code so that it fits your requirements and then have fun testing and debugging :slight_smile: .

Cheers!

2 Likes

AI FOR LIFE!!!

1 Like

AI scrapers are destroying the small web, and AI can die in a fire. As for vibe coders, they are only encouraging AI.

(Yes, I know my code is on GitHub and thus is being used as training material by Microsoft, but that is another story…)

2 Likes

Well, in my defense, I can say that I’m not a programmer and my goal is to make some apps that I would like to play with, see how it works and learn something on the way. I don’t have the time to deepen a programming language on the verge of extinction. I’m not praising AI, I think is dumb as a brick, with no creativity, and I get angry all the time while I use it. But is the fastest way to achieve my goal and I see it as a tool.

The fact that companies want to replace junior developers with AI is just plain stupid and dangerous. It will only lead to an echo chamber where the information from the web will be created by the AI and then fed back to the AI training. Who’s gonna check what is truth and what is not then?

Even if I use AI, it will write some garbage (like writing LINE when it should have been BOX all along) and you could never use that code as it is since it just won’t work. That’s where human intervention is needed to clear all that nonsense and test the code on an actual device.

Will the AI fully replace humans? Never!

Will AI help humans? Sure!

Will AI make us more prone to laziness and ignorance? Probably, but my goal is not to be proficient in BASIC, I just want some code and some apps to play with. That’s it!

<3

I find it fascinating that AI makes life now. didn’t want to offend you.

Why don’t you try to learn some programming then? It is hard to ‘make some apps’ via ‘vibe coding’ without knowing how to program anyways, as AI will inevitably make mistakes, and without knowing how to program you won’t be able to fix them. It is better to just program without using AI to begin with, because then you will know everything you specified for the code to do yourself, rather than having to go back and fix code you don’t understand. I know you say you don’t have the time, but if you don’t have the time to learn some basic programming skills you certainly don’t have the time to fix whatever some LLM will have come up with.

If you want to be all high-level and such, start out with MicroPython/CircuitPython or uLisp or MMBasic (the fact that people here are definitely using it means that it is probably not ‘on the verge of extinction’). Once you get more advanced, if you want to get lower-level, closer to the machine, I would recommend zeptoforth (there are C or C++, but they do not offer the level of interactivity Forth provides, and often are more finicky in how to make them do things).

nit: counting bug on the boundaries.

n = a(xm,ym) + a(x,ym) + a(xp,ym) + a(xm,y) + a(xp,y) + a(xm,yp) + a(x,yp) + a(xp,yp)

For a corner cell, the probe coordinates are “clamped” to W-1, 0, etc. This will result in neighbor cells being counted twice.

A simple fix is to enlarge your cell grid by TWO, so that actual cells sit within (1, 1) … (W, H), while (0, …), (W+1, …), (…, 0), (…, H+1) are all “dead zones” that cannot grow any cells. Then remove the clamps.

1 Like

Here you go, plus a few extra amenities:

' Adapted from Conways Game of Life by C0n57an71n
' https://forum.clockworkpi.com/t/conways-game-of-life/19133

Data "        * * * * * * * *         "
Data "         * * * * * * *          "
Data "        * * * * * * * *         "
Data "                   * *          "
Data "                    * *         "
Data "                   * *          "
Data "                    * *         "
Data "                   * *          "
Data "                                "
Data "       * * *       * *          "
Data "        * *         * *         "
Data "       * * * * * * * *          "
Data "        * * * * * * * *         "
Data "       * * * * * * * *          "
Data "        * *         * *         "
Data "                                "
Data "        * * * * * * * *         "
Data "       * * * * * * * *          "
Data "        * * * * * * * *         "
Data "       * *   * *                "
Data "        * *   * *               "
Data "       * *   * *                "
Data "        * *   * *               "
Data "                                "
Data "        * * * * * * * *         "
Data "       * * * * * * * *          "
Data "        * * * * * * * *         "
Data "       * *   * *   * *          "
Data "        * *   *     * *         "
Data "       * *   * *   * *          "
Data "        * *   *     * *         "
Data "       * *           *          "

Option DEFAULT INTEGER
Randomize Timer

'-----------------------------
' Config
'-----------------------------
Const SCRW = 320
Const SCRH = 320
Const CELL = 10                 ' Try 10 or 8 for speed; 5 if you want more detail (slower)
Const W = SCRW \ CELL
Const H = SCRH \ CELL

' Colors

Dim wt(10),editc(10)
wt(1) = RGB(white)
wt(2) = RGB(red)
wt(3) = RGB(orange)
wt(4) = RGB(yellow)
wt(5) = RGB(green)
wt(6) = RGB(cyan)
wt(7) = RGB(blue)
wt(8) = RGB(magenta)
wt(9) = RGB(gray)
wt(10) = RGB(black)
editc(1) = RGB(red)
editc(2) = RGB(cyan)
editc(3) = RGB(blue)
editc(4) = RGB(red)
editc(5) = RGB(red)
editc(6) = RGB(red)
editc(7) = RGB(white)
editc(8) = RGB(cyan)
editc(9) = RGB(green)
editc(10) = RGB(red)

Const INIT_FILL_PCT = 25
Const STATUS_EVERY = 1

Dim a(W+1, H+1)     ' current
Dim b(W+1, H+1)     ' next
Dim gen, upd

colors$="1234567890"
bgcolors$="!@#$%^&*()"
running$ = "running"
StatusBarOn = 1
editx = 1
edity = 1
OldEditX=1
OldEditY=1
bg = 10
colorcycle=0
CellStyle=1
filled=1
CLS wt(bg)

'-----------------------------
' Seed/Clear
'-----------------------------
Sub SeedRandom(pct%)
  Local x, y
  For y = 1 To H
    For x = 1 To W
      a(x,y) = (Rnd * 100 < pct%)
    Next x
  Next y
  ResetEdit
End Sub

Sub ClearAll
  Local x, y
  For y = 1 To H
    For x = 1 To W
      a(x,y) = 0
    Next x
  Next y
  ResetEdit
End Sub

Sub ResetEdit
  Local EditX,EditY,EditC
  EditX = 0
  EditY = 0
  OldEditX = 0
  OldEditY = 0
  OldC = a(0,0)
End Sub

'-----------------------------
' Draw
'-----------------------------
Sub DrawCELL(x, y, alive)
  Local x1, y1, c
  If alive Then c = wt(fg) Else c = wt(bg)
  If filled=1 Then fc=c Else fc=wt(bg)
    x1 = (x-1) * CELL
    y1 = (y-1) * CELL
    Box x1, y1, CELL, CELL, , c, fc
  End If
End Sub

Sub DrawAll
  Local x, y
  For y = 1 To H
    For x = 1 To W
      DrawCELL x, y, a(x,y)
    Next x
  Next y
End Sub

Sub StatusBar
  ' redraw occasionally to avoid extra drawing overhead
  If StatusBarOn = 1 Then
    Text 2, 2, "Generation:" + Str$(gen)+"   Speed: "+Str$((1000-PauseLength)/100)+" ",,,,wt(1),wt(0)
  End If
End Sub

'-----------------------------
' Init
'-----------------------------
For t=1 To 32
  Read logo$
  For d=1 To 32
    If Mid$(logo$,d,1)=" " Then ch=0 Else ch=1
    a(t,d)=ch
  Next d
Next t
fg=5
DrawAll
Text 109,25,"John Conway's",,,,RGB(white)
Text 96,40,"The Game of",,2,,RGB(white)
Text 67,255,"Press F1 for assistance",,,,RGB(white)
Text 71,270,"Press any key to begin",,,,RGB(white)
gen = 0
upd = 0
Do While k$=""
  k$=UCase$(Inkey$)
Loop

fg=6
If k$<>"C" And k$<>"F" Then
  'CLS
  SeedRandom INIT_FILL_PCT
  DrawAll
  If k$=Chr$(145) Or k$="?" Then OldKey$="?"
Else
  CLS
  If k$="F" Then Filled=0
  DrawAll
End If
StatusBar

'-----------------------------
' Main loop
'-----------------------------
Do
  ' input (non-blocking)
  If OldKey$<>"" Then
    k$=OldKey$
    OldKey$=""
  Else
    k$ = Inkey$
  EndIf
  If k$ <> "" Then
    oldfg = fg
    oldbg = bg
    If Instr(colors$+bgcolors$,k$)<>0 Then
      fgpos=Instr(colors$,k$)
      bgpos=Instr(bgcolors$,k$)
      If fgpos<>0 Then
        fg=fgpos
      Else
        bg=bgpos
      EndIf
    Else
      Select Case UCase$(k$)
        Case "?",Chr$(145)  ' display help
          Box 0,82,320,156,, RGB(white),RGB(white)
          Box 3,85,314,150,, RGB(red)
          Text 96,82,"The Game of Life",,1,,RGB(black),RGB(white)
          Text 16,106,"[Spc]  Pause (Edit mode)/toggle cell",,,,RGB(black),RGB(white)
          Text 16,118,"[Esc]  Quit/Exit edit mode",,,,RGB(black),RGB(white)
          Text 16,130," +/-   Increase or decrease speed",,,,RGB(black),RGB(white)
          Text 16,142,"  S    Toggle status bar",,,,RGB(black),RGB(white)
          Text 16,154,"  C    Clear",,,,RGB(black),RGB(white)
          Text 16,166,"  R    Reseed",,,,RGB(black),RGB(white)
          Text 16,178," 0-9   Set cell color",,,,RGB(black),RGB(white)
          Text 16,190," !-)   Set background color",,,,RGB(black),RGB(white)
          Text 16,202,"  H    Highlight new growth",,,,RGB(black),RGB(white)
          Text 16,214,"  F    Toggle filled cells",,,,RGB(black),RGB(white)
          k$=""
          Do While k$=""
            k$=Inkey$
          Loop
          OldKey$=k$
          DrawAll
        Case "S"         ' toggle status bar
          StatusBarOn = -StatusBarOn
          DrawAll
          If StatusBarOn = 1 Then StatusBar
        Case "-"         ' decrease speed
          If PauseLength < 1000 Then
            PauseLength = PauseLength+100
          End If
          StatusBar
        Case "+"         ' increase speed
          If PauseLength>0 Then
            PauseLength = PauseLength-100
          End If
          StatusBar
        Case " "         ' pause/resume
          If Running$ = "running" Then
            running$ = "paused"
            DrawAll
          Else
            If a(EditX,EditY) = 1 Then
              a(EditX,EditY) = 0
            Else
              a(EditX,EditY) = 1
            End If
          End If
        Case "F"         ' toggle style
          If filled=1 Then filled=0 Else filled=1
          DrawAll
        Case "R"         ' reseed
          SeedRandom INIT_FILL_PCT
          DrawAll
          gen = 0: upd = 0
          StatusBar
        Case "C"         ' clear
          ClearAll
          DrawAll
          running$="paused"
          gen = 0: upd = 0
          StatusBar
        Case Chr$(27),Chr$(13)  ' Esc
          If Running$ = "paused" Then
            Running$ = "running"
            If a(EditX,EditY) = 1 Then
              c = wt(fg)
            Else
              c = wt(bg)
            End If
            If filled=1 Then fc=c Else fc=wt(bg)
            Box (EditX-1)*CELL, (EditY-1)*CELL, CELL, CELL, , c, fc
          Else
            If k$ = Chr$(27) Then
              Box 0, 142, 320, 30, , RGB(white), RGB(white)
              Box 3, 145, 314, 24, , RGB(red)
              Text 18,151,"Are you sure you want to quit? (y/N)",,1,,RGB(black),RGB(white)
              k$=""
              Do While k$=""
                k$=Inkey$
              Loop
              If k$=Chr$(27) Or LCase$(k$)="y" Then
                Color RGB(green),RGB(black)
                CLS
                End
              Else
                DrawAll
              EndIf
            End If
          End If
        Case Chr$(128)   ' Up
          If EditY > 1 and running$="paused" Then
            EditY = EditY-1
          End If
        Case Chr$(131)   ' right
          If EditX < W and running$="paused" Then
            EditX = EditX+1
          End If
        Case Chr$(130)  ' Left
          If EditX > 1 and running$="paused" Then
            EditX = EditX-1
          End If
        Case Chr$(129)  ' down
          If EditY < H and running$="paused" Then
            EditY = EditY+1
          End If
        Case "H"
          If ColorCycle=1 Then
            ColorCycle=0
          Else
            ColorCycle=1
          End If
      End Select
    End If
    If fg<>OldFG Or bg<>OldBg Then
      DrawAll
    EndIf
  Else
    If running$="running" And k$="" Then
      Pause PauseLength
    EndIf
  EndIf

  If running$ = "running"  Then
    ' ----- compute next gen into b(), inline neighbor counting with wrap -----
    For y = 1 To H
      ym = y - 1': If ym < 0 Then ym = H - 1
      yp = y + 1': If yp = H Then yp = 0
      For x = 1 To W
        xm = x - 1': If xm < 0 Then xm = W - 1
        xp = x + 1': If xp = W Then xp = 0

        n = a(xm,ym) + a(x,ym) + a(xp,ym) + a(xm,y) + a(xp,y) + a(xm,yp) + a(x,yp) + a(xp,yp)

        If a(x,y) Then
          b(x,y) = (n = 2) Or (n = 3)
        Else
          b(x,y) = (n = 3)
        EndIf
      Next x
    Next y

    ' ----- draw only the CELLs that changed -----
    If ColorCycle=1 Then
      fg=fg+1
      If fg=bg Then fg=fg+1
      If fg=11 Then fg=1
    End If
    For y = 1 To H
      For x = 1 To W
        If b(x,y) <> a(x,y) Then DrawCELL x, y, b(x,y)
      Next x
    Next y

    ' ----- copy b -> a -----
    For y = 1 To H
      For x = 1 To W
        a(x,y) = b(x,y)
      Next x
    Next y

    gen = gen + 1
    upd = upd + 1
    If upd >= STATUS_EVERY And running$="running" Then
      upd = 0
      StatusBar
    EndIf
  Else
      If running$ = "paused" And K$<>""  Then
        If a(editx,edity) = 1 Then
          c = wt(fg)
        Else
          c = wt(bg)
        End If
        If filled=1 Then oldfc=oldc Else oldfc=wt(bg)
        If EditX<>OldEditX Or EditY<>OldEditY Then Box (OldEditX-1)*CELL, (OldEditY-1)*CELL, CELL, CELL, , oldc, oldfc
        editbg=c
        Box (EditX-1)*CELL,(EditY-1)*CELL , CELL, CELL, , editc(fg), editbg
        Line (EditX-1)*CELL,(EditY-1)*CELL),(EditX*CELL)-1,(EditY*CELL)-1,,editc(fg)
        Line (EditX-1)*CELL,(EditY*CELL)-1,(EditX*CELL)-1,(EditY-1)*CELL,,editc(fg)
        OldEditX = EditX
        OldEditY = EditY
        OldC = c
      EndIf
  EndIf
Loop

The original code is generally compatible with PicoMite BASIC, but this version is specific to the display dimensions of the PicoCalc. I make no apologies for weird design choices. Anyway, I’ll also add it to my GitHub.

1 Like

No, I don’t want to be “all high-level" and such”. Thanks for the concern, but I think I know better what I want, how much time and resources I have to dedicate to them. The reason I bought the PicoCalc is that I like tinkering, is portable and I can play with the code and test it straight away, instead of losing time on my phone doom scrolling.

Why should I learn countless programming languages when I don’t need them in life? Why shouldn’t I spend my time instead with my vacuum tube radios collection restoration or painting or tinkering or writing poems on my typewriters? From a professional point of view would make more sense to me learning ladder programming for Siemens or Rockwell PLC than BASIC.

PicoCalc gives me something to do with the minimum required resources. Do I prefer to do something else instead? For sure, but life is full of constraints and that’s the way it is.

Just because your goal in life is to be a good developer, doesn’t mean everyone should have the same goal like you.

Thanks, but I didn’t asked for it. I don’t want somebody to “fix” the code. I would do it myself when I feel like and now is not the time.

If I post the code on the forum is just for other people to have fun with it as they please.

I bought the PicoCalc because I like visualizing math. That’s it!

No, @PeterL did, which is the reason my post shows it’s a reply to @PeterL. But I guess I misunderstood when you said “You can make that yourself.’

Sorry! My bad… Feel free to do whatever you like with it.

You say you want to create apps, yet you are unwilling to learn that necessary to do so well and want to use AI to do so for you. This is just like saying that one wants to restore vacuum tube radios without understanding analog electronics – how would you react if I said I wanted to work with vacuum tubes but I refused to learn anything related to electronics?

Let’s keep the discussion at a certain level…

a few years ago people said the same about stackoverlow…

@C0n57an71n you did a good job!