Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Elementary Cellular Automaton
#1
Adapted from Coding Challenge 179: Elementary Cellular Automata (youtube.com)
Original javascript code: Wolfram CA / The Coding Train
More on it at Elementary Cellular Automaton -- from Wolfram MathWorld

Code: (Select All)
Option _Explicit
_ControlChr Off

Const true = -1, false = 0

Dim ruleValue As _Unsigned _Byte
Dim Shared ruleSet$
Dim nav$, newValue$
Dim As Long w, total, i, x, y, k
Dim As _Byte l, r, state, newState, firstTime, done
Dim As _Unsigned Long c
Dim As _MEM m1, m2

firstTime = true
ruleValue = 99
w = 2

'setup
Screen _NewImage(1000, 800, 32)
_Display
Color _RGB32(0), _RGB32(255)
total = _Width / w

'main loop
Do
    ruleSet$ = Right$(String$(8, "0") + _Bin$(ruleValue), 8)
    ReDim As _Byte cells(total - 1), nextCells(total - 1)
    cells(Int(total / 2)) = 1
    y = _FontHeight
    Cls

    'draw loop
    Do
        For i = 0 To total - 1
            x = i * w
            If cells(i) Then
                If x < _Width / 2 Then
                    c = _RGB32(map(x, 0, _Width / 2, 200, 0))
                Else
                    c = _RGB32(map(x, _Width / 2, _Width, 0, 200))
                End If
            Else
                _Continue
            End If
            Line (x, y)-Step(w, w), c, BF
        Next

        y = y + w
        If y > _Height Then Exit Do

        'calculate next generation
        For i = 0 To total - 1
            l = cells((i - 1 + total) Mod total)
            r = cells((i + 1) Mod total)
            state = cells(i)
            newState = calculateState(l, state, r)
            nextCells(i) = newState
        Next

        m1 = _Mem(cells())
        m2 = _Mem(nextCells())
        _MemCopy m2, m2.OFFSET, m2.SIZE To m1, m1.OFFSET
    Loop

    If ruleValue > 0 Then nav$ = Chr$(27) + " " Else nav$ = Space$(2)
    nav$ = nav$ + "Rule " + Right$(String$(3, "0") + _Trim$(Str$(ruleValue)), 3)
    If ruleValue < 255 Then nav$ = nav$ + " " + Chr$(26)
    nav$ = nav$ + "; w =" + Str$(w)
    _PrintString (_Width / 2 - _PrintWidth(nav$) / 2, 0), nav$
    If firstTime Then
        Locate 3, 1
        Print "use left/right arrows to change rule set or"
        Print "enter a rule number directly (0-255);"
        Print "up/down arrows to change box width."
        firstTime = false
    End If

    _Display
    _KeyClear
    done = false
    Do
        k = _KeyHit
        Select Case k
            Case 27: System
            Case 19200: If ruleValue > 0 Then ruleValue = ruleValue - 1: Exit Do
            Case 19712: If ruleValue < 255 Then ruleValue = ruleValue + 1: Exit Do
            Case 18432: w = w + 2: total = _Width / w: Exit Do
            Case 20480: If w > 2 Then w = w - 2: total = _Width / w: Exit Do
            Case 13, 48 To 57
                'insert mode
                If k > 13 Then newValue$ = Chr$(k) Else newValue$ = ""
                _KeyClear
                Do
                    Locate 2, 1
                    Print "Enter new rule (0-255): "; newValue$; "_ ";
                    _Display
                    k = _KeyHit
                    Select Case k
                        Case 48 To 57
                            newValue$ = newValue$ + Chr$(k)
                        Case 8
                            If Len(newValue$) Then newValue$ = Left$(newValue$, Len(newValue$) - 1)
                        Case 13
                            If Val(newValue$) >= 0 And Val(newValue$) <= 255 Then
                                ruleValue = Val(newValue$)
                                done = true
                                Exit Do
                            Else
                                Beep
                            End If
                        Case 27
                            done = true
                            Exit Do
                    End Select
                    _Limit 30
                Loop
        End Select
        _Limit 30
    Loop Until done
Loop

Function calculateState%% (a As _Byte, b As _Byte, c As _Byte)
    Dim neighborhood$
    Dim value As _Byte

    neighborhood$ = _Trim$(Str$(a)) + _Trim$(Str$(b)) + _Trim$(Str$(c))
    value = 8 - Val("&B" + neighborhood$)
    calculateState%% = Val(Mid$(ruleSet$, value, 1))
End Function

Function map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
    map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
End Function
Reply
#2
------
Reply
#3
This is very interesting. I especially like how a few of the rules might even be random generators.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#4
------
Reply
#5
(01-13-2024, 05:48 AM)Sprezzo Wrote: Look who it is. You lost weight.

Nice to see you both around.  I haven't seen either of you around here in ages.  Smile
Reply
#6
Wow, cool stuff I've not seen this variation on automata.

After first 128 I supposed maybe I'd see a reverse pattern, nope but many more black backgrounds. Rules of interest 54, 57, 60, 73, 82, 89, 105, 109, 110, 124 then stopped noting.

Anyone consider rules for outcome based on rule number? Like anything in common with rules that generate single line stuff?
b = b + ...
Reply
#7
Hi from beautiful Greece  Fellippe.
 
Reply
#8
@Sprezzo I did lose weight, thanks for noticing! Sorry I probably didn't notice the deeper meaning of the automata when you posted your version back in the day (I likely just focused on the visuals). I like it how yours shows a visual representation of the rules below the main view.

@TerryRitchie About rule 30: "In fact, this rule is used as the random number generator used for large integers in the Wolfram Language (Wolfram 2002, p. 317)." https://mathworld.wolfram.com/Rule30.html

@SMcNeill Thank you, man.

@bplus there are some classes of behavior these rules fall into, but I wouldn't be able to give more details (they're out there).

@gaslouk hey there, man!
Reply




Users browsing this thread: 3 Guest(s)