Przenieś się ze mną na chwilę do roku 2014. To w tym roku piłkarze notują pamiętne zwycięstwo z Niemcami, polscy siatkarze zdobywają mistrzostwo świata, a Kamil Stoch zdobywa swoje złote medale na olimpiadzie. Oprócz kibicowania naszym sportowcom, od kilku lat mój wolny czas wypełnia mi uczestnictwo w wydarzeniach lokalnej społeczności JUG. To takie kółko dla programistów, gdzie ludzie za darmo dzielą się wiedzą. Spotkania mają najczęściej formę wykładów. To niesamowicie wygodny sposób na poszerzanie horyzontów. Od czasu do czasu, zdarzają się też warsztaty, które są z kolei okazją do praktycznego zapoznania się z nowym językiem, biblioteką czy paradygmatem.
Kilka lat później z aktywnego uczestnika zamienię się w osobę, która przez jakiś czas sama będzie miała okazję organizować i prowadzić tego typu wykłady. Zachęcam Cię do zapoznania się ze wpisem, w którym opowiadam, jak to wyglądało, nie pomijając szczegółów od kuchni https://kodujmy.pl/a-gdyby-tak-zrobic-serial-o-javie/
PS. Są nagrania do wykładów!
Warsztat, który zmienia wszystko
15 listopada biorę udział w warsztacie, który jest zupełnie inny niż wszystkie dotychczas, inny niż te, które do tej pory znałem. Jak się później okaże, to doświadczenie odciśnie piętno na tym, jak będę podchodził w przyszłości do programowania. Do warsztatu jeszcze wrócę w dalszej części artykułu. Tymczasem spróbujmy rozwikłać zagadkę, czym jest „gra dla 0 graczy”?
Gra dla 0 graczy
W grach tego typu zaczynamy od pewnego stanu początkowego. To, co wydarzy się dalej, zależy od reguł zdeterminowanych w grze, nie jest to natomiast w żaden sposób zależne od gracza. Sam gracz może pełnić istotną funkcję w przygotowaniu stanu początkowego, później natomiast nie jest już potrzebny do dalszego przebiegu gry.
The Incredible Machines
Popularną grą, która jest dobrym przykładem gry dla 0 graczy, jest Incredible Machines z 1993 roku. Pamiętam doskonale, iż ta gra mieściła się na jednej dyskietce, co na tamte czasy, było godne podziwu. Sama rozgrywka polega na rozmieszczeniu różnych elementów na planszy, tak aby po uruchomieniu symulacji osiągnąć cel etapu. Tym mogło być np. wbicie piłki do kosza (patrz screen poniżej). Do dyspozycji mamy taśmociągi, silniki, chomiki biegające w klatce, kule kręgli czy rękawice bokserskie, które możemy dowolnie rozmieszczać na ekranie. o ile wiesz, czym jest maszyna Goldberga lub efekt domina to gwałtownie załapiesz, o co chodzi w tej rozgrywce i porwiesz się w wir rozwiązywania zagadek logicznych.
Ten artykuł nie jest jednak o klasykach gier, dlatego zostawmy na boku „Niesamowite maszyny”, a przejdźmy do głównego wątku tego artykułu.
Jeżeli zainteresował się powyższy wątek, zachęcam Cię do spróbowania swoich sił i zagrania w nią na jednym z dostępnych emulatorów.
Grę łatwo znajdziesz w sieci np. tutaj: https://www.myabandonware.com/game/the-incredible-machine-1mg/play-1mg
Gra w życie
Tematem przewodnim tego artykułu jest inna Gra w życie. Ten najpopularniejszy automat komórkowy działa dokładnie w myśl powyższych zasad (przygotowujemy stan początkowy, a reszta dzieje się sama). Został opracowany w 1970 przez brytyjskiego matematyka Johna Conwaya.
Zasady
Gra toczy się na nieskończonej planszy (płaszczyźnie) podzielonej na kwadratowe komórki. Każda komórka ma ośmiu „sąsiadów” (tzw. sąsiedztwo Moore’a), czyli komórki przylegające do niej bokami i rogami.
Każda komórka może znajdować się w jednym z dwóch stanów: może być albo: „żywa” (włączona), albo „martwa” (wyłączona).
Stany komórek zmieniają się w pewnych jednostkach czasu. Stan wszystkich komórek w pewnej jednostce czasu jest używany do obliczenia stanu wszystkich komórek w następnej jednostce. Po obliczeniu wszystkie komórki zmieniają swój stan dokładnie w tym samym momencie. Stan komórki zależy tylko od liczby jej żywych sąsiadów.
Startując od jakiegoś stanu, gra będzie toczyć się sama, bez ingerencji gracza. To, co wydarzy się dalej, napędzane jest przez kilka prostych reguł, które brzmią następująco:
- Martwa komórka, która ma dokładnie 3 żywych sąsiadów, staje się żywa w następnej jednostce czasu (rodzi się),
- Żywa komórka z 2 albo 3 żywymi sąsiadami pozostaje przez cały czas żywa,
- Przy innej niż powyższa, liczbie sąsiadów umiera z „samotności” (1 lub mniej sąsiadów),
- albo „zatłoczenia” (4 lub więcej sąsiadów)
Wydawać by się mogło, iż przy tak prostych kilku zasadach, nie możemy liczyć na nic spektakularnego. Nic bardziej mylnego! O grze w życie powstała cała masa ciekawych materiałów, a ludzie modelujący rozgrywkę przy jej użyciu potrafią zawstydzić najlepszych budowniczych w Minecrafcie.
Notacja wpływająca na reguły
Gra do dzisiaj jest obiektem ciekawych badań i rozważań wśród matematyków. Powstała np. notacja, która definiuje alternatywne zasady gry. Prosty ciąg znaków w następującym formacie: X / Y pozwala na zdefiniowanie- alternatywnych do Conwaya- zasad. Wzór należy czytać następująco:
- X – to liczby komórek w sąsiedztwie, dla których żywe komórki przeżywają (dla oryginalnej gry w życie jest to 23),
- Y – liczby komórek w sąsiedztwie, dla których martwe komórki ożywają (dla oryginalnej gry w życie jest to 3).
Alternatywnych wariantów tej gry jest zbyt wiele, aby wspomnieć o wszystkich (218 = 262144) ale przytoczę kilka wartych uwagi:
Reguła | Nazwa | Właściwości |
23/3 | Gra w życie | Klasyczny wariant gry w życie |
12345/3 | Labirynt | Tworzy wzory przypominające labirynty. |
1357/1357 | Replikator | Automat replikujący Edwarda Fredkina, każda struktura jest z czasem zastępowana przez jej kilka kopii |
1358/357 | Ameba | Dobrze zbalansowana między życiem a śmiercią, ma statki |
45678/3 | Koral | Wzory rosną powoli, tworzą struktury przypominające rafę koralową. |
Więcej reguł na polskiej wikipedii: https://pl.wikipedia.org/wiki/Gra_w_%C5%BCycie
Zadanie podczas sandoboxa praktyk w TomTom
W ciągu ośmiu edycji praktyk, które, mam przyjemność organizować w swoim dziale w TomTomie, to właśnie Gra w życie jest drugim projektem, który wykonują praktykanci w ramach naszej „piaskownicy”. Zadanie polega na stworzeniu projektu opierającego swoje założenia na powyższym klasyku.
Pierwszy etap praktyk (półtora miesiąca) prowadzimy w formie praktycznych warsztatów. Staramy się, aby w tym czasie praktykanci poznali najważniejsze zagadnienia, które okażą się później niezbędne, podczas pozostałych miesięcy praktyk.
Osobiście, nazywam ją Sandboxem (piaskownicą), ponieważ, są tam stworzone warunki zoptymalizowane pod naukę. Możesz i choćby powinieneś popełniać tam dużo błędów, aby jak najwięcej nauczyć się od bardziej doświadczonych kolegów. Z drugiej strony, ponieważ pracujesz nad własnymi projektami, nie ma ryzyka, iż usuniesz niechcący bazę produkcyjną (taka okazja zawsze istnieje w dalszej części praktyk)
Najistotniejsza w tym wszystkim jest jednak otoczka. Realizując to zadanie, chcemy, aby ludzie poczuli różnicę między projektami tworzonymi do szuflady a tymi realizowanymi komercyjnie. Jest kilka punktów, które zasługują na uwagę:
Code Review
To najistotniejszy punkt na całej liście. Gdybym miał wybierać tylko jeden punkt, to właśnie przegląd kodu byłby tym, co daje zdecydowanie najlepsze przyspieszenie w twoim rozwoju. choćby w tak prostym projekcie, jak ten jest sporo decyzji projektowych, które należy przyjąć. Przykładem niech będzie, chociażby w jaki sposób reprezentować stan gry i jakie niesie to konsekwencje. To rodzi pole do bardzo ciekawych dyskusji. Nie ma lepszego i szybszego sposobu nauki niż, kontakt z bardziej doświadczonymi programistami, którzy dzielą się swoim bogatym doświadczeniem.
Dobre praktyki
Punktem powiązanym jest wiedza. Ją możesz pozyskać dzięki wcześniej wspomnianych przeglądów kodu, ale również podczas warsztatu czy zwykłej rozmowy z bardziej doświadczonymi osobami. Docelowo dzięki dobrym praktykom uczestnicy uczą się jak pisać kod, który oprócz tego, iż działa, został jeszcze w dodatku nieźle zaprojektowany, gotowy na rozbudowy, łatwiejszy w utrzymaniu. To właśnie takie dobre zasady podpowiedzą Ci jak podzielić kod na mniejsze kawałki i jaka klasa/obiekt/funkcja powinna mieć jaką odpowiedzialność. Jednym z naturalnych podziałów w Grze w życie jest odseparowanie warstwy wizualizacji od samego silnika reguł. Takie podejście otwiera możliwość, chociażby łatwiejszego testowania.
Testy
Mając już wyodrębniony silnik, można go łatwiej przetestować, najlepiej przy pomocy testów jednostkowych. Realizacja projektu to też dobra okazja do przetestowania w praktyce TDD. Gra w życie sprawdzi się tutaj bardzo dobrze, dzięki jasno zdeterminowanym regułom, które wygodnie da się opisać przy pomocy przypadków testowych.
Podział na serwer i aplikacje kliencką
Program praktyk nakierowany jest na poznanie zarówno nowoczesnego stacka backendowego, jak i części frontendowej. Co ciekawe, to właśnie ta druga część przysparza najwięcej wyzwań w trakcie tego zadania. choćby jeżeli w dzisiejszych czasach, swoją karierę wiążesz z backendem, to znajomość podstaw na frontendzie przyda Ci się, chociażby do lepszej współpracy z kolegami, rozumiejąc, jak wygląda to po drugiej stronie.
Eksperymenty
Podczas każdej edycji, zachęcamy uczestników do tego, aby eksperymentować ze swoim projektem i oprócz podstawowego zakresu, zastanowić się jakie funkcjonalności można dorzucić od siebie. W trakcie 7 edycji, które nadzorowałem, widziałem wiele ciekawych pomysłów. Byli uczestnicy, którzy tworzyli heatmapy na podstawie informacji jak często na danym polu znajdowało się życie. Zdarzyło się też, iż projekt został na tyle rozbudowany, iż umożliwiał na ustawienie alternatywnych zasad, o których wspominałem powyżej. Nie wspominając już o samym dopracowaniu interfejsu użytkownika, dzięki, któremu łatwiej można było generować gotowe struktury czy wręcz całe scenariusze symulacji.
Code retreat
Wspominając o eksperymentach, mogę wrócić do wątku z początku artykułu, czyli o warsztacie, który okazał się kamyczkiem milowym w mojej karierze programisty. Code retreat bo taką nosi nazwę, to warsztat, który odbywa się co roku i swoim zasięgiem obejmuje cały glob. Lokalne grupy społeczności programistycznych, spotykają się wtedy wspólnie, aby pokodować i skupić się na dobrych praktykach programistycznych.
Łódzki JUG przez kilka lat, organizował ją również w moim rodzinnym mieście. W roku 2015 miałem okazję spróbować osobiście. Do dzisiaj wspominam to całe wydarzenie jako świetną odskocznię od codziennej pracy. Wydarzenie to wprowadziło nieco zamieszania do mojego dotychczasowego myślenia o programowaniu. Nie jest to bowiem warsztat, który da się łatwo porównać do innych.
Co w nim takiego niezwykłego?
Głównym celem warsztatu był trening umiejętności programistycznych. Zasady polegały na tym, aby cały warsztat odbył się w cyklu 5 jednakowych sesji. Każda sesja polegała na:
- Dobraniu ludzi w pary, gdzie w myśl pair programmingu, jedna osoba była obserwatorem, a druga nawigatorem,
- Wspólnym zadaniem każdej pary, było napisanie silnika gry w życie. Jako dodatkowy element każda sesja cechowała się jasno zdefiniowanym ograniczeniem np.
- Nie używamy instrukcji warunkowych w kodzie,
- piszemy wszystko w paradygmacie funkcyjnym,
- nie używamy myszki,
- dodajemy nowy stan do gry o nazwie zombie cechujący się nową zasadą,
- <inne ograniczenie wzmacniające naszą kreatywność>
- Po określonym czasie następował moment, w którym usuwaliśmy kod (sic!)
- Następnie przystępowaliśmy do sesji retrospektywy, gdzie wspólnie z innymi parami dzieliliśmy się doświadczeniami zebranymi podczas przed chwilę odbytej sesji.
- Nowe losowanie par, nowa zasada i powtarzamy całą sesję od nowa.
Jak łatwo się domyślić, punkt trzeci spotykał się z olbrzymim oporem wśród uczestników. Zasada to jednak zasada i jak się w trakcie warsztatu okazywało, nie została stworzona bezcelowo. Miała bowiem na celu uniknięcie sytuacji w której, kod mógł być wykorzystany w następnej sesji, jak i nie pozwolić, aby istniejący już kod hamował naszą kreatywność w kolejnym etapie.
Jak wspomniałem na początku, jest to wydarzenie globalne, gdzie udział biorą zespoły z całego świata. Dobrą praktyką jest łączenie się podczas dwóch sesji na samym początku i na zakończenie warsztatu z zespołem z innej części świata. Na sesji porannej my zaczynamy, ktoś inny już kończy, na sesji popołudniowej odwrotnie. Jest to okazja do krótkiej wymiany kilku zdań i życzenie powodzenia, grupie, która właśnie zaczyna.
Dlaczego warto?
Mocno polecam każdemu, wzięcie udziału w tego typu warsztacie chociaż raz w życiu. Mnie osobiście nauczył:
- na jak wiele różnych sposobów można rozwiązać to samo zadanie, choćby zmienając jedynie osobę z którą się współpracuje lub język w którym piszemy,
- jak ograniczenia powodują wzrost naszej kreatywności i uczą nas zupełnie nowego podejścia do problemu,
- oraz na koniec, iż gra w życie to rodzaj problemu, który świetnie nadaje się do nauki i podnoszenia umiejętności programistycznych.
Dobre do portfolio
No dobra, ale co jeśli, nie masz możliwości wzięcia udziału w stażu, a na kolejną edycję Code Retreat przyjdzie Ci czekać niemal rok. o ile jesteś na etapie nauki, polecam pochylić się nad tym problemem i spróbować własnych sił. W tym projekcie jest wiele obszarów, w ramach których można wykazać jakość Twoich umiejętności oraz je rozwinąć. Zarówno w części związanej z samym silnikiem, jak i w kwestii wizualizacji. Jest to projekt, w którym, możemy pokazać ładne testy oraz jak sprytnie poradziliśmy sobie z implementacją alternatywnych do Gry w życie zasad, o których wspominałem powyżej. Kończąc na przyjemnej dla oka wizualizacji i funkcjonalnym interfejsie użytkownika.
Jeżeli skusisz się na stworzenie takiego projektu, koniecznie daj mi o tym znać! Idealnie gdyby była, to wersja z możliwością wpływania na reguły.
Jeżeli szukasz elementów, które pomogą Ci zwiększyć szanse wykorzystania tego projektu w swoim portfolio, zachęcam Cię do zapoznania się z tym artykułem.
https://kodujmy.pl/9-rad-dla-osob-bez-doswiadczenia-szukajacych-pierwszej-pracy-lub-stazu-w-programowaniu/