Implementacja w języku Python

Do implementacji Gry w życie w języku Python wykorzystamy cztery moduły i biblioteki:

  • NumPy – biblioteka zawierająca funkcje i obiekty matematyczne; użyjemy jej do wygodnej obsługi tablic dwuwymiarowych;

  • random – moduł odpowiadający za generowanie liczb pseudolosowychliczba pseudolosowaliczb pseudolosowych wykorzystywanych do inicjalizacji pierwszej populacji;

  • time – moduł zawierający wiele funkcji związanych z czasem oraz datami; użyjemy go do zatrzymywania pętli programu na określoną liczbę sekund;

  • os – moduł zawierający funkcje służące do komunikacji z systemem operacyjnym; wykorzystamy go do czyszczenia okna konsoli.

Na początku je zaimportujemy:

Linia 1. import numpy as np. Linia 2. import random. Linia 3. import time. Linia 4. import os.

NumPy pozwala na wygodną i wydajną obsługę wielowymiarowych tablic. W automacie komórkowym pracujemy na tablicach dwuwymiarowych.

Ciekawostka

Biblioteka NumPy ma wiele zastosowań, wśród nich znajdują się między innymi: zaawansowane obliczenia matematyczne, analizy danych oraz uczenie maszynowe. Cechuje ją prostota użycia oraz wydajność.

Potrzebne będą nam również zmienne globalne do przechowywania informacji o stanie komórki oraz rozmiaru siatki.

Linia 1. ROZMIAR podkreślnik SIATKI znak równości 10. Linia 2. ZYWA znak równości True. Linia 3. MARTWA znak równości False.

Dodatkowo w programie wykorzystamy następujące funkcje:

  • wyczysc_terminal() – funkcja czyszcząca konsolę;

  • stworzSiatke() – funkcja inicjalizująca siatkę oraz generująca pierwszą populację komórek. Siatkę inicjalizujemy, tworząc dwuwymiarową tablicę. Pierwsza populacja generowana jest w taki sposób, że dla każdej komórki losujemy liczbę od 0 do 4. Jeśli wylosowana zostanie liczba 0, dana komórka oznaczona jest jako żywa;

  • wyswietlSiatke() – funkcja wypisująca aktualną zawartość siatki na ekran terminala;

  • ewolucja() – funkcja przeprowadzająca proces ewolucji komórek znajdujących się w siatce zgodnie z zasadami Gry w życie;

  • policzZywychSasiadow() – funkcja zwracająca dla danej komórki liczbę otaczających ją żywych sąsiadów.

Zaczniemy od stworzenia funkcji wyczysc_terminal(). Do wyczyszczenia okna konsoli, po poprzednim wypisaniu zawartości siatki, użyjemy odpowiednich poleceń systemowych:

  • dla systemu Windows: cls,

  • dla systemu Linux: clear.

Wywołujemy funkcję system(), zawartą w module os. Nazwę systemu operacyjnego, na którym działamy, sprawdzimy poprzez zmienną os.name. Dla systemu Windows będzie ona równa nt. Chcemy, aby program dobrał odpowiednią instrukcję dla danego systemu.

Linia 1. kratka Instrukcja wyczyści ekran konsoli. Linia 2. os kropka system otwórz nawias okrągły apostrof cls apostrof if os kropka name znak równości znak równości apostrof nt apostrof else apostrof clear apostrof zamknij nawias okrągły.

Następnie zapiszemy funkcję stworzSiatke(). Planszę będzie reprezentowała dwuwymiarowa tablica, przechowująca informację na temat tego, które komórki są żywe (wartość True), a które martwe (wartość False). Zaczniemy od wypełnienia tej tablicy zerami, wykorzystując poniższą instrukcję:

Linia 1. tablica znak równości numpy kropka zeros otwórz nawias okrągły otwórz nawias okrągły liczba podkreślnik wierszy przecinek liczba podkreślnik kolumn zamknij nawias okrągły zamknij nawias okrągły.

W naszym programie będzie miała następującą postać:

Linia 1. def stworz podkreślnik siatke otwórz nawias okrągły zamknij nawias okrągły dwukropek. Linia 2. siatka znak równości np kropka zeros otwórz nawias okrągły otwórz nawias okrągły ROZMIAR podkreślnik SIATKI przecinek ROZMIAR podkreślnik SIATKI zamknij nawias okrągły zamknij nawias okrągły.

Potrzebujemy informacji, które z komórek są żywe, a które martwe w stanie początkowym. Możemy to ustalić na wiele sposobów, między innymi:

  • wczytać zdefiniowane ustawienie siatki, np. z pliku,

  • wylosować dowolne ustawienie.

Wygenerujemy pierwszą populację, korzystając z liczb pseudolosowych. Losowanie polega na wylosowaniu liczby z zakresu <0, 4> i ustawieniu jej na pozycji siatka[i, j] wartości ZYWA, jeżeli wylosowana liczba to 0, lub wartości MARTWA w pozostałych przypadkach. Funkcja zwraca stworzoną siatkę.

Do wygenerowania pseudolosowej liczby całkowitej z danego zakresu służy funkcja randint(). Oto jej przykładowe zastosowanie:

Linia 1. kratka Instrukcja wypisze losową liczbę. Linia 2. kratka całkowitą z zakresu otwórz nawias kwadratowy 1 przecinek 100 zamknij nawias kwadratowy. Linia 3. print otwórz nawias okrągły random kropka randint otwórz nawias okrągły 1 przecinek 100 zamknij nawias okrągły zamknij nawias okrągły.

Realizacja w programie:

Linia 1. def stworz podkreślnik siatke otwórz nawias okrągły zamknij nawias okrągły dwukropek. Linia 2. siatka znak równości np kropka zeros otwórz nawias okrągły otwórz nawias okrągły ROZMIAR podkreślnik SIATKI przecinek ROZMIAR podkreślnik SIATKI zamknij nawias okrągły zamknij nawias okrągły. Linia 4. for i in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 5. for j in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 6. temp znak równości random kropka randint otwórz nawias okrągły 0 przecinek 4 zamknij nawias okrągły. Linia 8. if temp znak równości znak równości 0 dwukropek. Linia 9. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości ZYWA. Linia 10. else dwukropek. Linia 11. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości MARTWA. Linia 13. return siatka.

Kolejna funkcja, którą zapiszemy, to funkcja policz_zywych_sasiadow(). Funkcja ta dla zadanej pozycji siatka[y, x] zwraca liczbę żywych sąsiadów tej pozycji. Funkcja przechodzi po kwadracie 3 x 3 dookoła komórki [y, x], zliczając liczbę żywych sąsiadów. Następnie odejmuje 1, jeżeli komórka [y, x] jest żywa, ponieważ nie powinna zostać policzona jako swój sąsiad. Funkcja zwraca liczbę żywych sąsiadów.

Linia 1. def policz podkreślnik zywych podkreślnik sasiadow otwórz nawias okrągły y przecinek x przecinek siatka zamknij nawias okrągły dwukropek. Linia 2. ile znak równości 0. Linia 4. for i in range otwórz nawias okrągły y minus 1 przecinek y plus 2 zamknij nawias okrągły dwukropek. Linia 5. for j in range otwórz nawias okrągły x minus 1 przecinek x plus 2 zamknij nawias okrągły dwukropek. Linia 6. if 0 otwórz nawias ostrokątny znak równości i otwórz nawias ostrokątny ROZMIAR podkreślnik SIATKI and 0 otwórz nawias ostrokątny znak równości j otwórz nawias ostrokątny ROZMIAR podkreślnik SIATKI and siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości ZYWA dwukropek. Linia 7. ile plus znak równości 1. Linia 9. if siatka otwórz nawias kwadratowy y przecinek x zamknij nawias kwadratowy znak równości znak równości ZYWA dwukropek. Linia 10. ile minus znak równości 1. Linia 12. return ile.

W następnym kroku zapisujemy funkcję ewolucja(). Dla danej siatki dokonuje ona jednej iteracji ewolucji. Funkcja tworzy tablicę ile_sasiadow o wymiarach takich jak siatka, przechowującą liczbę żywych sąsiadów dla każdej komórki w siatce. Następnie przechodzi po każdej komórce i – w zależności od jej stanu (żywej lub martwej) i liczby żywych sąsiadów – wykonuje odpowiednią akcję:

  • Jeżeli komórka jest martwa i ma dokładnie 3 sąsiadów, ożywa.

  • Jeżeli komórka jest żywa i ma mniej niż 2 sąsiadów, umiera z samotności.

  • Jeżeli komórka jest żywa i ma więcej niż 3 sąsiadów, umiera z przeludnienia.

  • W pozostałych przypadkach stan komórki się nie zmienia.

Funkcja wyswietl_siatke() służy do wyświetlania zawartości siatki na ekranie w postaci graficznej. W tym celu na podstawie wartości komórek używa znaków Unicode o kodach U+25A0 (czarny kwadrat) i U+25A1 (biały kwadrat), aby zbudować wizualizację siatki na ekranie.

W tej wersji Gry w życie nie będziemy używać biblioteki graficznej. Zastąpimy ją, wypisując informacje o stanie planszy w oknie terminala. Wykorzystamy czarne i białe kwadraty, które są znakami Unicode.

Linia 1. print otwórz nawias okrągły cudzysłów Pełny kwadrat dwukropek cudzysłów plus u apostrof lewy ukośnik u25a0 apostrof zamknij nawias okrągły. Linia 2. print otwórz nawias okrągły cudzysłów Pusty kwadrat dwukropek cudzysłów plus u apostrof lewy ukośnik u25a1 apostrof zamknij nawias okrągły.

Po wywołaniu kodu w terminalu ujrzymy:

Linia 1. Pełny kwadrat dwukropek ■. Linia 2. Pusty kwadrat dwukropek □.

Funkcja main() jest główną funkcją programu i odpowiada za sterowanie automatem komórkowym. W pierwszym kroku tworzy ona siatkę, wywołując funkcję stworz_siatke(). Następnie w nieskończonej pętli wywołuje funkcję wyswietl_siatke(siatka) do wyświetlenia aktualnego stanu siatki, następnie wywołuje funkcję ewolucja(siatka) do wyznaczenia nowego stanu siatki, a na końcu wykonuje funkcję time.sleep(0.5), która opóźnia program na pół sekundy, aby umożliwić użytkownikowi obserwowanie zmian w siatce. Pętla nieskończona powoduje, że program działa, dopóki nie zostanie zatrzymany przez użytkownika.

Do spowolnienia programu użyjemy funkcji sleep() z modułu time.

Linia 1. kratka Instrukcja zatrzyma program na dokładnie. Linia 2. kratka trzy sekundy. Linia 3. time kropka sleep otwórz nawias okrągły 3 zamknij nawias okrągły.

Implementacja Gry w życie w języku Python bez użycia biblioteki graficznej wygląda następująco:

Linia 1. kratka Najpierw importujemy potrzebne moduły. Linia 2. import numpy as np. Linia 3. import random. Linia 4. import time. Linia 5. import os. Linia 7. kratka Inicjalizujemy przydatne zmienne globalne. Linia 8. ROZMIAR podkreślnik SIATKI znak równości 10. Linia 9. ZYWA znak równości True. Linia 10. MARTWA znak równości False. Linia 12. def wyczysc podkreślnik terminal otwórz nawias okrągły zamknij nawias okrągły dwukropek. Linia 13. os kropka system otwórz nawias okrągły apostrof cls apostrof if os kropka name znak równości znak równości apostrof nt apostrof else apostrof clear apostrof zamknij nawias okrągły. Linia 15. def stworz podkreślnik siatke otwórz nawias okrągły zamknij nawias okrągły dwukropek. Linia 16. kratka Tworzymy dwuwymiarową tablicę za pomocą. Linia 17. kratka modułu NumPy. Linia 18. siatka znak równości np kropka zeros otwórz nawias okrągły otwórz nawias okrągły ROZMIAR podkreślnik SIATKI przecinek ROZMIAR podkreślnik SIATKI zamknij nawias okrągły zamknij nawias okrągły. Linia 20. kratka Generujemy pierwszą populacje komórek. Linia 21. for i in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 22. for j in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 23. kratka Losujemy liczbę w zakresie otwórz nawias kwadratowy 0 przecinek 4 zamknij nawias kwadratowy. Linia 24. temp znak równości random kropka randint otwórz nawias okrągły 0 przecinek 4 zamknij nawias okrągły. Linia 26. kratka Komórka staje się żywa przecinek gdy wylosujemy zero. Linia 27. if temp znak równości znak równości 0 dwukropek. Linia 28. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości ZYWA. Linia 29. else dwukropek. Linia 30. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości MARTWA. Linia 32. return siatka. Linia 35. def policz podkreślnik zywych podkreślnik sasiadow otwórz nawias okrągły y przecinek x przecinek siatka zamknij nawias okrągły dwukropek. Linia 36. ile znak równości 0. Linia 38. kratka Przechodzimy po kwadracie 3 x 3 dookoła komórki. Linia 39. for i in range otwórz nawias okrągły y minus 1 przecinek y plus 2 zamknij nawias okrągły dwukropek. Linia 40. for j in range otwórz nawias okrągły x minus 1 przecinek x plus 2 zamknij nawias okrągły dwukropek. Linia 41. kratka Sprawdzamy przecinek czy nie wyszliśmy poza zakres siatki i czy sąsiad jest żywy. Linia 42. if 0 otwórz nawias ostrokątny znak równości i otwórz nawias ostrokątny ROZMIAR podkreślnik SIATKI and 0 otwórz nawias ostrokątny znak równości j otwórz nawias ostrokątny ROZMIAR podkreślnik SIATKI and siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości ZYWA dwukropek. Linia 43. ile plus znak równości 1. Linia 45. kratka Ponieważ sprawdzaliśmy również podaną komórkę przecinek. Linia 46. kratka to jeżeli ona jest żywa przecinek musimy ją odjąć. Linia 47. kratka minus sama komórka nie jest swoim sąsiadem. Linia 48. if siatka otwórz nawias kwadratowy y przecinek x zamknij nawias kwadratowy znak równości znak równości ZYWA dwukropek. Linia 49. ile minus znak równości 1. Linia 51. return ile. Linia 54. def ewolucja otwórz nawias okrągły siatka zamknij nawias okrągły dwukropek. Linia 55. kratka Inicjalizujemy tablicę przechowującą liczbę. Linia 56. kratka żywych sąsiadów dla danej komórki. Linia 57. ile podkreślnik sasiadow znak równości np kropka zeros otwórz nawias okrągły otwórz nawias okrągły ROZMIAR podkreślnik SIATKI przecinek ROZMIAR podkreślnik SIATKI zamknij nawias okrągły zamknij nawias okrągły. Linia 59. kratka Dla każdej komórki liczymy liczbę żywych. Linia 60. kratka sąsiadów. Linia 61. for i in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 62. for j in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 63. ile podkreślnik sasiadow otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości policz podkreślnik zywych podkreślnik sasiadow otwórz nawias okrągły i przecinek j przecinek siatka zamknij nawias okrągły. Linia 65. kratka Dokonujemy ewolucji każdej z komórek zgodnie. Linia 66. kratka z regułami Gry w życie. Linia 67. for i in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 68. for j in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 69. kratka Komórka jest martwa i ma 3 sąsiadów minus oży. Linia 70. if siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości MARTWA dwukropek. Linia 71. if ile podkreślnik sasiadow otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości 3 dwukropek. Linia 72. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości ZYWA. Linia 74. kratka Komórka jest żywa i ma za mało sąsiadów minus ginie. Linia 75. elif siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości ZYWA and ile podkreślnik sasiadow otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy otwórz nawias ostrokątny 2 dwukropek. Linia 76. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości MARTWA. Linia 78. kratka Komórka jest żywa i ma za dużo sąsiadów otwórz nawias okrągły przeludnienie zamknij nawias okrągły minus ginie. Linia 79. elif siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości ZYWA and ile podkreślnik sasiadow otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy zamknij nawias ostrokątny 3 dwukropek. Linia 80. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości MARTWA. Linia 81. elif siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości ZYWA and ile podkreślnik sasiadow otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy zamknij nawias ostrokątny 3 dwukropek. Linia 82. siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości MARTWA. Linia 85. def wyswietl podkreślnik siatke otwórz nawias okrągły siatka zamknij nawias okrągły dwukropek. Linia 86. kratka Czyścimy terminal po poprzednim wypisaniu. Linia 87. kratka zawartości siatki. Linia 88. wyczysc podkreślnik terminal otwórz nawias okrągły zamknij nawias okrągły. Linia 90. kratka Wypisujemy zawartość siatki. Linia 91. for i in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 92. for j in range otwórz nawias okrągły ROZMIAR podkreślnik SIATKI zamknij nawias okrągły dwukropek. Linia 93. if siatka otwórz nawias kwadratowy i przecinek j zamknij nawias kwadratowy znak równości znak równości ZYWA dwukropek. Linia 94. print otwórz nawias okrągły u apostrof lewy ukośnik u25a0 apostrof przecinek end znak równości apostrof apostrof zamknij nawias okrągły. Linia 95. else dwukropek. Linia 96. print otwórz nawias okrągły u apostrof lewy ukośnik u25a1 apostrof przecinek end znak równości apostrof apostrof zamknij nawias okrągły. Linia 98. print otwórz nawias okrągły apostrof lewy ukośnik n apostrof przecinek end znak równości apostrof apostrof zamknij nawias okrągły. Linia 100. print otwórz nawias okrągły apostrof lewy ukośnik n apostrof przecinek end znak równości apostrof apostrof zamknij nawias okrągły. Linia 103. def main otwórz nawias okrągły zamknij nawias okrągły dwukropek. Linia 104. siatka znak równości stworz podkreślnik siatke otwórz nawias okrągły zamknij nawias okrągły. Linia 106. while True dwukropek. Linia 107. wyswietl podkreślnik siatke otwórz nawias okrągły siatka zamknij nawias okrągły. Linia 108. ewolucja otwórz nawias okrągły siatka zamknij nawias okrągły. Linia 109. kratka Zatrzymujemy program na pół sekundy przecinek. Linia 110. kratka aby móc lepiej obserwować działanie. Linia 111. kratka naszego automatu komórkowego. Linia 112. time kropka sleep otwórz nawias okrągły 0 kropka 5 zamknij nawias okrągły. Linia 114. if podkreślnik podkreślnik name podkreślnik podkreślnik znak równości znak równości apostrof podkreślnik podkreślnik main podkreślnik podkreślnik apostrof dwukropek. Linia 115. main otwórz nawias okrągły zamknij nawias okrągły.

Słownik

klasa
klasa

rodzaj szablonu (wzorca) opisującego zbiór zmiennych oraz funkcji służących do ich przetwarzania; korzystając z klasy można tworzyć obiekty, będące rozbudowanymi odpowiednikami zmiennych; można powiedzieć, że obiekt jest zmienną typu klasa

metoda
metoda

funkcja należąca do klasy i służąca do operowania na jej obiektach (zmiennych)

lista
lista

struktura danych; w języku Python wykorzystywana jest do implementacji tablic

liczba pseudolosowa
liczba pseudolosowa

liczba wygenerowana za pomocą generatora pseudolosowego; ciąg liczb przez niego wygenerowanych wydaje się losowy dla obserwatora

Matplotlib
Matplotlib

biblioteka służąca do tworzenia wykresów w języku Python; posiada również funkcje odpowiadające za wyświetlanie grafik oraz animacji; składnią oraz nazwami funkcji jest bardzo zbliżona do języka programowania Matlab