Wyjście Spis treści Poprzedni Następny
Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor: mgr Jerzy Wałaszek, wersja 3.0 |
©2008 mgr
Jerzy Wałaszek |
Grę w Życie opracujemy poznaną w poprzednich przykładach
metodą zstępującą. Przypominamy, iż polega ona na rozbiciu problemu na mniejsze
podproblemy i opracowanie każdego z nich z osobna. Dzięki takiemu podejściu
zadanie staje się prostsze.
W naszym przypadku grę rozpoczniemy wyświetleniem strony tytułowej oraz krótkiej instrukcji obsługi programu. Operacji tych nie będziemy opisywać, ponieważ są to działania standardowe i na pewno nie sprawią kłopotu początkującym programistom.
Kolejna procedura ma za zadanie wyzerować planszę gry, umieścić gracza na jej środku oraz wyświetlić planszę w oknie konsoli.
Wszelkie działania realizuje specjalna funkcja
Akcja. Oczekuje ona na wciśnięcie klawisza przez użytkownika,
interpretuje go wywołując odpowiednie procedury i jeśli naciśniętym klawiszem
był klawisz różny od [Escape], zwraca true, co powoduje
kontynuację pętli. W przypadku klawisza [Escape] funkcja
zwraca false, pętla ulega przerwaniu i gra kończy się.
Symbol | Przeznaczenie w algorytmie |
---|---|
i,j | zmienne licznikowe pętli |
pobc[] | tablica logiczna reprezentująca planszę gry |
pozycja | zmienna typu COORD zawierająca pozycję gracza w obrębie planszy |
pokolenie | numer pokolenia organizmów |
Plansza gry zrealizowana jest w postaci logicznej tablicy
dwuwymiarowej. Indeksy elementów odpowiadają dokładnie pozycjom znakowym w
okienku konsoli. Dlatego tablica ma następującą definicję:
var pobc : array[2..24,2..79] of boolean; |
Elementy tej tablicy są wartościami logicznymi. Wartość false oznacza, iż dana
komórka nie zawiera żywego organizmu, a wartość true oznacza, że zawiera.
Pierwsze dwie pętle adresują kolejno wszystkie elementy tej tablicy i
wprowadzają do nich wartość logiczną false - komórki puste. Następnie ustawiamy
pozycję gracza na współrzędne X=40 i Y=12, co odpowiada środkowi okna konsoli i
planszy gry. Zmienna pokolenie zawiera numer generowanego pokolenia. Teraz
zerujemy ją.
Na koniec wywołujemy procedurę Plansza, która wyczyści nam okno
konsoli i wyświetli w nim pustą planszę gry. Po tej operacji procedurę kończymy.
Symbol | Przeznaczenie w algorytmie |
---|---|
i,j | zmienne licznikowe pętli |
pobc[] | tablica logiczna reprezentująca planszę gry |
pokolenie | numer pokolenia organizmów |
populacja | zlicza ilość żywych komórek na planszy |
Procedura generuje planszę dla gry. Na środku pierwszego wiersza okna konsoli wypisujemy aktualny numer pokolenia. Informacja ta przydaje się przy badaniu rozwoju różnych układów żywych komórek.
Plansza gry jest w niebieskim kolorze tła. Znaki są intensywnie białe. Wyświetlenie planszy polega na drukowaniu spacji na pozycjach znakowych okna konsoli, dla których komórka planszy ma wartość logiczną false, a znaków 'O' dla komórek planszy zawierających żywy organizm.
Ponieważ odwołania do procedury GotoXY są dosyć wolne, przy wyświetlaniu planszy tworzymy w zmiennej s cały wiersz komórek, który następnie drukujemy przy pomocy jednej instrukcji. Przeglądanie planszy realizowane jest w dwóch pętlach sterowanych zmiennymi i i j.
W trakcie tworzenia planszy zliczamy w zmiennej populacja liczbę komórek zawierających żywy organizm. Po wyświetleniu planszy umieszczamy na środku ostatniego wiersza informację o ilości żywych komórek.
Zmienna populacja jest zmienną globalną.
Wykorzystywana jest również przez procedurę cyklicznego generowania pokoleń do
wstrzymania tej generacji, jeśli wszystkie organizmy uległy wymarciu. W takim
przypadku nie ma sensu tworzenie następnych pokoleń, ponieważ plansza jest pusta
i nic na niej już nie wyrośnie.
Symbol | Przeznaczenie w algorytmie |
---|---|
pobc[] | dwuwymiarowa tablica logiczna reprezentująca planszę gry |
pokolenie | numer pokolenia organizmów |
populacja | zlicza ilość żywych komórek na planszy |
pozycja | rekord typu COORD zawierający bieżącą pozycję kursora gracza |
Funkcja Akcja pełni rolę centralną w naszej grze. Ponieważ schemat blokowy byłby dosyć rozbudowany, pokazaliśmy go w wersji uproszczonej, co z resztą bardzo często się praktykuje - schematy blokowe mają za główne zadanie naszkicowanie idei działania algorytmu oraz powiązania jego elementów ze sobą, a szczegóły implementacyjne pozostawia się do fazy kodowania operacji algorytmu za pomocą wybranego języka programowania.
Na początku wywołujemy procedurę Kursor, która powinna w sposób widoczny wyróżnić pozycję gracza na planszy. My zrealizowaliśmy kursor mrugający, gdyż ruch przyciąga uwagę. Procedura wykonywana jest do momentu naciśnięcia jakiegokolwiek klawisza.
Odczytujemy kod naciśniętego przez gracza klawisza i badamy go podejmując odpowiednie działania. Jeśli jest to klawisz Enter, wywołujemy procedurę Następne Pokolenie, która na bazie bieżącego stanu planszy wygeneruje nowe pokolenie organizmów zgodnie z podanymi na początku rozdziału regułami. Kończymy algorytm zwracając wartość logiczną true, która spowoduje kontynuację pętli w programie głównym.
Wykrycie naciśnięcia klawisza Escape spowoduje zwrócenie przez funkcję wartości logicznej false, która przerwie pętlę programu głównego i zakończy działanie programu. Wszystkie pozostałe opcje zawsze kończą zwracając wartość true, zatem nie będziemy już o tym pisać.
Klawisz spacji powoduje zmianę stanu komórki na pozycji gracza. Ponieważ plansza gry jest tablicą wartości logicznych, wystarczy dokonać prostej negacji zawartości odpowiedniej komórki. Dodatkowo zerujemy zmienną pokolenie, ponieważ dokonaliśmy modyfikacji i rezultat jest czymś nowym, co nie powstało z poprzedniej generacji komórek. Zatem pokolenia będą liczone od tego momentu od nowa. Wywołujemy procedurę rysowania planszy i kończymy.
Klawisz F1 pełni funkcję włączania/wyłączania samoczynnej animacji kolejnych pokoleń. Po naciśnięciu tego klawisza algorytm wchodzi w pętlę warunkową, w której generuje następne pokolenie komórek, odczekuje około 1/3 sekundy i sprawdza naciśnięcie klawisza. Jeśli żaden klawisz nie został naciśnięty lub nie jest to klawisz F1, pętla kontynuuje się. W przypadku wykrycia klawisza F1 lub wymarcia wszystkich żywych komórek na planszy pętla zostaje zakończona.
Klawisze ze strzałkami zmieniają współrzędne bieżącej pozycji gracza, które umieszczono w zmiennej pozycja. Zasada jest taka, iż wyjście gracza poza krawędź planszy powinno przewinąć jego pozycję do krawędzi przeciwnej - współrzędne w zmiennej pozycja muszą zawsze wskazywać jedną z komórek planszy gry.
Na koniec klawisz Delete powoduje
wymazanie całego pola gry i umieszczenie gracza na środku. Wykorzystujemy tutaj
poznaną już wcześniej procedurę usuwania organizmów z planszy.
Symbol | Przeznaczenie w algorytmie |
---|---|
i,j | zmienne licznikowe pętli adresujących kolejne elementy tablic pobc[] i pnst[] |
pobc[] | tablica zawierająca obecne pokolenie organizmów |
pnst[] | tablica, w której tworzymy następne pokolenie organizmów |
pokolenie | numer pokolenia |
ls | liczba żywych sąsiadów dla komórki pnst[i,j] |
k | zmienne licznikowa kolumn |
w | zmienna licznikowa wierszy |
x,y | przechowuje współrzędne sąsiedniej komórki w stosunku do badanej komórki pnst[i,j] |
Zadaniem tej procedury jest wyznaczenie nowego pokolenia organizmów. Na początku tworzymy dwie zagnieżdżone pętle sterowane zmiennymi i i j. Pętle te adresują kolejne elementy tablicy pnst[]. Następnie dla każdej takiej komórki znajdujemy liczbę sąsiadów w tablicy pobc[]. Do tego celu służą kolejne dwie zagnieżdżone pętle sterowane zmiennymi k - kolumny i w - wiersze. Zwróć uwagę, iż wartości k oraz w są przesunięciami względem aktualnej pozycji i przebiegają wartości od -1 do 1. Współrzędne komórki obliczamy jako sumy współrzędnych i,j oraz k,w: Pozwala to zaadresować wszystkie 9 komórek leżących w prostokącie obejmującym pozycję (i,j):
k=(-1) | k=0 | k=1 | |
---|---|---|---|
w=(-1) | (i-1,j-1) | (i,j-1) | (i+1,j-1) |
w=0 | (i-1,j) | (i,j) | (i+1,j) |
w=1 | (i-1,j+1) | (i,j+1) | (i+1,j+1) |
Współrzędne sąsiednich komórek wyliczane są w zmiennych
Po zakończeniu pętli k i w w zmiennej ls mamy liczbę żywych komórek otaczających komórkę pnst[i,j]. Jeśli w obecnym pokoleniu komórka ta żyje, to w następnym będzie wciąż żywa, gdy liczba jej sąsiadów wynosi 2 lub 3. Jeśli komórka w obecnym pokoleniu jest martwa, to ożyje w następnym, jeśli liczba sąsiadów wyniesie dokładnie 3.
Po zakończeniu pętli i i j
w tablicy pnst[] mamy ustawione następne pokolenie
organizmów. Przepisujemy zawartość tej tablicy do pobcn[],
czyli następne pokolenie staje się pokoleniem obecnym. Zwiększamy numer
pokolenia, wyświetlamy zmodyfikowaną planszę gry i kończymy algorytm.
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe