Skip to content

Commit

Permalink
Added generic implementation of cellular automaton
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Feb 12, 2024
1 parent 7ab2d19 commit ead2ed9
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 7 deletions.
19 changes: 12 additions & 7 deletions Applications/Automaton/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@

_Rule 30 nearest neighbour one-dimensional cellular automaton_

An implementation of the "rule 30" nearest-neighbour one-dimensional cellular automaton, also known as an "elementary cellular automaton".
An implementation of nearest-neighbour one-dimensional cellular automata, also known as "elementary cellular automata". Each generation in this class of automaton consists of a single row of cells each of which may be in one of two possible states, alive (1) or dead (0).

If the current cell and the cells to the left and right of it follow one of the patterns shown in the following table, with the status of the current cell indicated by the middle digit of each pattern, the current cell will be alive in the next generation:
This folder contains both hard-coded "rule 30" implementations (see the references for more information) and a generic implementation where the rules for calculating the next generation are configurable.

## Example - Rule 30

For the rule 30 automaton, if the current cell and the cells to the left and right of it follow one of the patterns shown in the following table in the current generation, with the status of the current cell indicated by the middle digit of each pattern, the current cell will be alive in the next generation:

| Generation | Pattern 1 | Pattern 2 | Pattern 3 | Pattern 4 |
| ------------------ | --------- | --------- | --------- | --------- |
Expand All @@ -20,12 +24,13 @@ Pattern 1 can therefore be expressed as:

> If the cell to the left of the current cell is alive and the current cell and cell to the right are dead in the current generation, then in the next generation the current cell will be alive
Two versions of the program are given:
## Program Files

| File | Description |
| ------------------ | ------------------------------------------------------------- |
| automaton_ansi.bas | Uses ANSI colour codes to output the state of each generation |
| automaton_text.bas | Uses plain text to output the state of each generation |
| File | Rule | Description |
| --------------------- | ---- | ----------------------------------------------------------------------------------------------------------- |
| automaton_generic.bas | Any | Configurable patterns in the DATA statements. Uses ANSI colour codes to output the state of each generation |
| automaton_ansi.bas | 30 | Uses ANSI colour codes to output the state of each generation |
| automaton_text.bas | 30 | Uses plain text to output the state of each generation |

Both implementations require the terminal emulator to use a fixed-width font to ensure proper alignment of the output.

Expand Down
71 changes: 71 additions & 0 deletions Applications/Automaton/automaton_generic.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
10 REM The data statements contain the patterns of three adjacent cells
20 REM that will lead to the current cell being alive in the next generation
30 REM End the patterns with the value 999
40 DATA 110, 100, 011, 001, 999
50 DIM CG(31), NG(31), LCP(8), CCP(8), RCP(8)
60 REM Read the patterns. At the end of this process, LCP contains the left
70 REM cell pattern values, CCP contains the current cell pattern values and
80 REM RCP contains the right cell pattern values
90 NP = 0
100 READ P : IF P > 111 THEN GOTO 160
110 NP = NP + 1
120 LET LCP(NP) = INT(P / 100)
130 LET CCP(NP) = INT((P - 100 * LCP(NP)) / 10)
140 LET RCP(NP) = P - 100 * LCP(NP) - 10 * CCP(NP)
150 GOTO 100
160 REM Ideally, let the width be an odd number so the
170 REM middle cell has the same number of cells to its
180 REM left and right. The CG() and NG() arrays must be
190 REM dimensioned to the same width.
200 LET W = 31
210 REM The following is the ANSI colour code for each cell
220 LET AC = 32
230 PRINT "How many generations do you want to see?"
240 INPUT NUMG
250 IF NUMG < 1 THEN PRINT "You must specify at least 1 generation" : GOTO 230
260 REM Initialize the current generation with a single
270 REM cell in the middle
280 FOR I = 1 TO W : LET CG(I) = 0 : NEXT I
290 LET I = 1 + INT(W / 2)
300 LET CG(I) = 1
310 REM Print the current generation
320 GOSUB 590
330 REM Generate and print the next NUMG generations
340 FOR G = 1 TO NUMG - 1
350 REM Initialize the next generation
360 FOR I = 1 TO W : LET NG(I) = 0 : NEXT I
370 REM Populate the next generation
380 FOR I = 1 TO W
390 REM Calculate the states of the left, current, and right cells
400 IF I = 1 THEN LET LC = 0
410 IF I > 1 THEN LET LC = CG(I - 1)
420 LET CC = CG(I)
430 IF I = W THEN LET RC = 0
440 IF I < W THEN LET RC = CG(I + 1)
450 REM Compare the states to the patterns
460 FOR J = 1 TO NP
470 IF LC <> LCP(J) OR CC <> CCP(J) OR RC <> RCP(J) THEN GOTO 520
480 REM Found a match, so the current cell is alive in the next
490 REM generation
500 NG(I) = 1
510 GOTO 530
520 NEXT J
530 NEXT I
540 REM Copy the next generation into the current one and print it
550 FOR I = 1 TO W : CG(I) = NG(I) : NEXT i
560 GOSUB 590
570 NEXT G
580 END
590 REM Print the current generation
600 FOR I = 1 TO W
610 IF CG(I) = 0 THEN PRINT " "; : GOTO 690
620 REM Create a text representation of the colour code
630 REM STR$() will add a leading space that must be
640 REM removed
650 LET AC$ = STR$(AC)
660 LET AC$ = RIGHT$(AC$, LEN(AC$) - 1)
670 PRINT CHR$(27);"[";AC$;";7m";" ";
680 PRINT CHR$(27);"[0m";
690 NEXT I
700 PRINT ""
710 RETURN

0 comments on commit ead2ed9

Please sign in to comment.