KodHTML

środa, 23 października 2019

2. Przygoda z automatami komórkowymi 2001

Wiele lat temu (był to rok 2001) automaty komórkowe zainteresowały mnie na chwilę, przy okazji lektury książki Petera Coveney'a i Rogera Higfielda Granice złożoności, Prószyński i S-ka, Warszawa 1997. Napisałem kilka programów w QBASICu, które odtwarzały zestaw reguł rządzących automatem. Poniżej przytaczam program, który losuje położenia punktów w "świecie automatu" i następnie realizuje schemat ewolucyjny według zadanych reguł. Dziś (2019) patrzę na program poniżej i widzę anachroniczność tego kodu. Jeśli znajdę czas przerobię go do jakiejś nowszej wersji BASICa. Tymczasem niech pozostanie po staremu.

Obserwacja zmian na ekranie jest zajmująca. Oczekujemy rychłego ustabilizowania się układu ewoluujących punktów, a tymczasem całość długo zmienia swoją postać. Poniżej pokazuję ekran monitora po pewnej liczbie iteracji.
Ciekawe zjawisko, zwłaszcza, że modyfikuje się pole wokół obiektu. Czuje się tu jakiś związek z fizyką cząstek. Tylko jaki? 
Do dziś nie wiem, czy tego typu podejście zostało zastosowane w fizyce cząstek. Nawet jeśli tak, to w ograniczonym zakresie bo fizycy są zafascynowani właściwościami falowymi układów kwantowych, z których to właściwości wynika nielokalność.

Tekst programu jest poniżej:

'automat komórkowy. odtwarza dane książkowe. Zbudowany 2 marca 2001.
bok = 50        ' bok świata
lewol = 1000    ' liczba ewolucji
screen 10
 dim a(1 to bok, 1 to bok)
 dim b(1 to bok, 1 to bok)
'przypadkowy układ punktów
for j = 1 to 723
  x = int(rnd(1) * bok) + 1
  y = int(rnd(1) * bok) + 1
  a(x, y) = 1: pset (x * 2, y * 2)
next j
'pętla główna
for k = 1 to lewol
  for y = 2 to bok - 1
    for x = 2 to bok - 1
      gosub sasiedzi:
      if a(x, y) = 1 then
        if (suma = 2) or (suma = 3) then b(x, y) = 1
      else
        b(x, y) = 0
      end if
        if suma = 3 then b(x, y) = 1
    next x
  next y

'nowa tablica a i malowanie tablicy b na ekranie, zerowanie tablicy b
 for y = 1 to bok
   for x = 1 to bok
      a(x, y) = 0                     'zerowanie tablicy a
      a(x, y) = b(x, y)               'nadawanie nowych wartości tablicy a
      pset (x * 2, y * 2), 0          'mazanie starego ekranu
     if b(x, y) = 1 then pset (x * 2, y * 2), 1    'malowanie nowego ekranu
     b(x, y) = 0                      'zerowanie tablicy b
   next x
 next y
next k
end
'procedura sasiedzi
sasiedzi:
'oblicza liczbę "pionków" wokół badanego punktu
  suma = 0
      for i = x - 1 to x + 1
        for j = y - 1 to y + 1
          if (i = x) and (j = y) then goto tu
          if a(i, j) = 1 then suma = suma + 1
tu:      next j
      next i
return



2 komentarze:

  1. W tak napisanym programie "przypadkowy układ punktów" będzie zawsze taki sam.
    Funkcję rnd należało zainicjować deklaracją na początku
    RANDOMIZE (zmienna)
    Jako zmienną najlepiej użyć TIMER.
    Tak było w TURBO BASIC
    :D

    OdpowiedzUsuń
  2. Tak jest, ale w QBASICu to działało tak, jak zapisałem.

    OdpowiedzUsuń