A few days ago Mathies published two articles about a nice artistic screensaver called drug test on his website. In the second article explaining some details he attributed the basic inspiration for his work to an old QBasic program I wrote. I used this as an occasion to bring Evo, the script he referred to, back to life in a web browser.
The Evo file I found was last changed on January 2nd, 2002. However, the relevant code is older, most likely few years older.
When looking at the inspiration for Evo, things come full circle: It came from Mathies, or from his inaccurate implementation of Conway’s Game of Life respectively. If I remember this correctly, his fault was to not render each generation completely based on the whole previous generation in the “game”. Instead he used just one grid and updated one pixel after the other, row by row and column by column, always based on the current state of the grid.
This didn’t work out so well, I thought, and Evo was my approach to doing something different yet similar then. A major difference is that pixels are chosen randomly to be updated in Evo, so it is non-deterministic – provided that a truly non-deterministic random number generator is used. Still, the rules lead to “stronger” and “weaker” colors and, although the development differs in details, the outcome is usually the same as long as the rules aren’t changed.
Evo has neither a notable artistic quality nor the intriguing fundamental mathematics to be found in Conway’s Game of Life. Nevertheless it’s interesting to see how larger structures form from a fine-grained random initial configuration, how the rules usually lead to red domination after many iterations, going through clearly distinguishable phases before, and how some colors grow well feeding on others, partially to be wiped out themselves when they have consumed all their nourishment.
Evo in the browser
The original code
Here is the relevant part of the original code from the BASIC file I found. It is old. I was young. It wasn’t meant to be published. Please do not understand this as an example of good programming.
'DEKLARATION '----------- DECLARE FUNCTION NC% (FARBE AS INTEGER) DIM E AS INTEGER, K AS INTEGER, N AS INTEGER, X AS INTEGER, Y AS INTEGER DIM SHARED F(1 TO 8) AS INTEGER 'FARBEN (WERTE MÜSSEN GRÖßER ALS 8 SEIN) '------ F(1) = 104 F(2) = 120 F(3) = 124 F(4) = 112 F(5) = 108 F(6) = 115 F(7) = 26 F(8) = 20 'START '----- RANDOMIZE TIMER CLS SCREEN 13 SLEEP .6 COLOR 11 LOCATE 1, 2 PRINT "INITIALISIERUNG "; VIEW SCREEN (97, 37)-(222, 162) FOR N = 1 TO 32000 PSET (CINT(RND * 126) + 97, CINT(RND * 126) + 37), NC(CINT(RND * 7) + 1) NEXT N: SOUND 1000, 1 LOCATE 24, 1 COLOR 9 PRINT "VIEL SPAß BEIM ZUSEHEN! <ESC> = BEENDEN."; LOCATE 1, 2 PRINT STRING$(15, CHR$(0)) DO K = 0 X = CINT(RND * 125) + 97 Y = CINT(RND * 125) + 37 E = NC(POINT(X, Y)) IF NC(POINT(X - 1, Y)) < E THEN PSET (X - 1, Y), NC(E): K = K + 1 IF NC(POINT(X - 1, Y - 1)) < E OR NC(POINT(X - 1, Y - 1)) = E + 1 THEN PSET (X - 1, Y - 1), NC(E): K = K + 1 IF NC(POINT(X, Y - 1)) < E THEN PSET (X, Y - 1), NC(E): K = K + 1 IF NC(POINT(X + 1, Y - 1)) < E OR NC(POINT(X + 1, Y - 1)) = E + 1 THEN PSET (X + 1, Y - 1), NC(E): K = K + 1 IF NC(POINT(X + 1, Y)) < E THEN PSET (X + 1, Y), NC(E): K = K + 1 IF NC(POINT(X + 1, Y + 1)) < E OR NC(POINT(X + 1, Y + 1)) = E + 1 THEN PSET (X + 1, Y + 1), NC(E): K = K + 1 IF NC(POINT(X, Y + 1)) < E THEN PSET (X, Y + 1), NC(E): K = K + 1 IF NC(POINT(X - 1, Y + 1)) < E OR NC(POINT(X - 1, Y + 1)) = E + 1 THEN PSET (X - 1, Y + 1), NC(E): K = K + 1 IF E < 8 AND K = 0 THEN CIRCLE (X, Y), SQR(SQR((VAL(RIGHT$(TIME$, 1)) + 1) * E ^ 3)), NC(E) IF E = 8 AND K < 5 THEN LINE (X - K, Y - K)-(X + K, Y + K), NC(8), B: K = 8 IF K < E - 1 THEN PSET (X, Y), NC(CINT(RND * (E + 1)) + 1) LOOP UNTIL INKEY$ = CHR$(27) FUNCTION NC% (FARBE AS INTEGER) IF FARBE < 9 AND FARBE > 0 THEN NC = F(FARBE): EXIT FUNCTION SELECT CASE FARBE CASE F(1): NC = 1 CASE F(2): NC = 2 CASE F(3): NC = 3 CASE F(4): NC = 4 CASE F(5): NC = 5 CASE F(6): NC = 6 CASE F(7): NC = 7 CASE F(8): NC = 8 END SELECT END FUNCTION
You might come to the conclusion that the function NC and the array F are rather confusing and not really necessary here, because they are used to map eight CGA colors to very similar looking colors from the VGA palette and back. Well, I wanted to be able to change the colors easily.