Bombowiec - algorytm


Podrozdziały:

 

Problem algorytmu gry rozwiążemy za pomocą metody zstępującej, która polega na tym, iż zadanie główne rozbijamy na serię zadań mniejszych, które łatwiej objąć umysłem.

 

obrazek

Cała gra składa się z dwóch pętli. Pętla zewnętrzna kontroluje poszczególne rozgrywki i wykonuje się tak długo, aż graczowi znudzi się dalsza gra. Na początku wyświetlamy stronę tytułową. Jest to działanie opisywane w poprzednich rozdziałach, zatem tutaj pominiemy opis. Następnie dokonujemy inicjalizacji struktur danych, z których gra korzysta. Do struktur tych zaliczymy tablicę przechowującą miasto oraz zmienne zawierające dane o położeniu bombowca i zrzucanej bomby.

Po inicjalizacji rozpoczynamy pętlę wewnętrzną, która kontroluje obieg gry. W trakcie obiegu wykonujemy ruch bombowcem (Lot bombowca), sprawdzamy, czy gracz zrzucił bombę (Zrzut bomb) naciskając klawisz spacji, jeśli bomba została zrzucona, to obsługujemy jej lot ku ziemi (Lot bomby) i wstrzymujemy wykonywanie programu na około 1/10 sekundy.

Na końcu pętli wewnętrznej sprawdzamy, czy wystąpił warunek końca obiegu - samolot zderzył się z budynkiem lub całe miasto zostało zniszczone. Jeśli tak, to kończymy rozgrywkę wypisując odpowiedni komunikat.

Kolejny test sprawdza, czy gracz ma ochotę zrezygnować z dalszej gry. Jeśli nie, to pętlę kontynuujemy. W przeciwnym razie algorytm kończy działanie.

Zwróćcie uwagę na sposób rozwiązania problemu gry. Całość rozbiliśmy na mniejsze zadania, które zajmują się tylko wycinkiem problemu. Określiliśmy jedynie kolejność tych podzadań i powiązania pomiędzy nimi. Taka metoda nosi nazwę zstępującej:

 

W metodzie zstępującej skomplikowany problem staramy się rozbić na ciąg mniejszych problemów, których rozwiązanie da rozwiązanie problemu pierwotnego. Zaletą jest to, iż będziemy pracować jedynie z wycinkiem zadania, zatem w dużo prostszych warunkach.



Procedura inicjalizacji

Symbol Przeznaczenie w algorytmie
i,j zmienne sterujące pętli
miasto tablica ilości pięter w poszczególnych domach.
by przechowuje pozycję pionową bomby.
oby poprzednia pozycja pionowa bomby
sx pozycja pozioma samolotu
ox poprzednia pozycja pozioma samolotu
sy pozycja pionowa samolotu
oy poprzednia pozycja pionowa samolotu
obrazek

Na początku procedury inicjującej struktury danych dla gry czyścimy okienko konsoli ustawiając w nim kolor tła na jasnoniebieski. W ten sposób symulujemy wygląd nieba.

Następnie ustawiamy kolor wydruku dla domów. W naszej wersji gry kolor tła jest ciemnogranatowy, a kolor tekstu jasnożółty - domy tworzone są ze znaku minus.

Teraz rozpoczyna się pętla główna, której zadaniem jest ustawienie zawartości tablicy miasto oraz wyświetlenie wygenerowanego miasta w okienku konsoli. Pętla przebiega kolejno wszystkie komórki tablicy miasto od 1 do 80. Dla komórek o numerach leżących w zakresie od 6 do 75 pętla wyznacza ilość pięter oraz drukuje dom w pętli wewnętrznej sterowanej zmienną j. Domy drukowane są od parteru wzwyż. Numeracja wierszy w okienku konsoli rozpoczyna się od góry. Dlatego przy określaniu pozycji wydruku kolejnego piętra musimy zastosować wyrażenie(i, 26 - j). Po inicjalizacji tablicy określamy wartości dla pozostałych zmiennych.

Procedura Lotu Bombowca

Symbol Przeznaczenie w algorytmie
sx pozycja pozioma samolotu
ox poprzednia pozycja pozioma samolotu
sy pozycja pionowa samolotu
oy poprzednia pozycja pionowa samolotu
obrazek

Zadaniem tej procedury jest animacja bombowca przy każdym obiegu pętli głównej gry. Zmienna sx zawiera pozycję poziomą, na której aktualnie znajduje się bombowiec. Zwiększamy ją o 1, czyli przesuwamy bombowiec o jedną kolumnę w prawo. Jednakże musimy sprawdzić, czy nie znalazł się on po tej modyfikacji poza prawą krawędzią okna konsoli. Jeśli pozycja sx przekracza 80, to tak właśnie się stało. W takim przypadku pozycję poziomą sx ustawiamy na 1 - pierwsza kolumna okna konsoli, a pozycję pionową sy zmniejszamy o 1. W efekcie bombowiec wyleci z lewej strony okna i obniży lot o jeden wiersz.

Po wyznaczeniu nowej pozycji starą pozycję ox, oy wymazujemy. Operacja ta będzie po prostu polegała na ustawieniu koloru tła wydruku na jasnoniebieski i wydrukowaniu na pozycji starych współrzędnych bombowca znaku spacji. Kolejna operacja umieści symbol bombowca na nowych współrzędnych sx i sy. Natomiast stare współrzędne ox i oy uaktualniamy - w następnym obiegu pętli pozwolą one wymazać znak bombowca, który właśnie umieściliśmy w okienku konsoli. Jeśli operacje te będą wykonywane cyklicznie co 1/10 sekundy, dadzą złudzenie lotu małego samolociku od strony lewej do prawej. Po każdym przelocie samolocik zniża lot.

Procedura Zrzutu Bomb

Symbol Przeznaczenie w algorytmie
c przechowuje kod naciśniętego klawisza
by pozycja pionowa bomby
bx pozycja pozioma bomby
sx pozycja pozioma samolotu
sy pozycja pionowa samolotu
oby poprzednia pozycja bomby w pionie
obrazek

Procedura ma za zadanie zainicjować spadek bomby po naciśnięciu przez gracza klawisza spacji. Na samym początku sprawdzamy zatem, czy jest naciśnięty jakikolwiek klawisz. Zadanie to wykonuje funkcja KeyPressed. Jeśli żaden klawisz nie jest naciśnięty, to kończymy procedurę - lot bombowca kontynuuje się bez zakłóceń.

Gdy wykryjemy naciśnięcie klawisza, odczytujemy jego kod do zmiennej c. Ponieważ gracz może przez przypadek nacisnąć jeden z klawiszy funkcyjnych, które zwracają dwa kody, pierwszy o wartości 0 i drugi będący tzw. kodem matrycowym klawisza funkcyjnego, kod klawisza odczytujemy dotąd, aż będzie to wartość różna od 0.

W dalszej kolejności sprawdzamy, czy naciśniętym klawiszem był klawisz spacji. Jeśli nie, kończymy procedurę. Jeśli naciśnięto klawisz spacji, to sprawdzamy, czy ostatnio zrzucona bomba dotarła już do gruntu, czyli czy by jest równe 0. Jeśli poprzednia bomba jeszcze jest w locie, ignorujemy naciśnięcie klawisza spacji i kończymy procedurę. Jeśli można zrzucić bombę, to odpowiednio ustawiamy zmienne przechowujące jej pozycję i kończymy.

Procedura Lotu Bomby

Symbol Przeznaczenie w algorytmie
by pozycja bomby w pionie
bx pozycja bomby w poziomie
oby poprzednia pozycja bomby w pionie
miastobx element tablicy przechowującej wysokości domów na pozycji bx
obrazek

Procedura steruje lotem bomby oraz niszczeniem budynków, jeśli bomba trafiła w budynek. Na początku sprawdzamy, czy bomba wykonuje lot. W takim przypadku współrzędna pionowa będzie większa od zera. Jeśli nie, to kończymy procedurę.

Wymazujemy bombę na starej pozycji, którą zawsze przechowujemy w zmiennej oby. Polega to na wypisaniu spacji o kolorze tła nieba na pozycji bomby. Po tej operacji zmniejszamy wysokość bomby w by i uaktualniamy oby, aby w następnym obiegu pętli głównej bomba została wymazana.

Teraz sprawdzamy, czy bomba uderza w budynek. Jeśli tak, to zmniejszamy wysokość budynku do pozycji pionowej bomby i ustawiamy odpowiednie kolory tła i tuszu, aby zasymulować coś w rodzaju wybuchu.

Kolejny test sprawdza, czy bomba jeszcze jest w locie. Jeśli tak, to rysujemy ją w postaci gwiazdki na odpowiednich współrzędnych ekranu i kończymy procedurę.

Procedura Końca Obiegu

Symbol Przeznaczenie w algorytmie
sy pozycja samolotu w pionie
miastosx wysokość domu na pozycji poziomej samolotu przechowywana w tablicy miasto
t zmienna pomocnicza do obliczania sumy wysokości domów pozostałych w mieście
i zmienna pomocnicza dla licznika pętli
miastoi wysokość domu na pozycji i-tej
obrazek

Funkcja ta wywoływana jest na końcu każdego obiegu pętli i ma za zadanie sprawdzić, czy gra została zakończona negatywnie lub pozytywnie.

Negatywne zakończenie mamy w przypadku zderzenia się samolotu z budynkiem, którego nie udało się zniszczyć bombą. W tym celu wystarczy sprawdzić wysokość budynku na aktualnej pozycji samolotu w poziomie. Jeśli jest ona równa wysokości lotu bombowca, to gra kończy się raczej tragicznie i zwracamy true, co jest informacją dla pętli gry, iż następnego obiegu już nie będzie. Na schemacie blokowym nie określamy akcji, która ma być w takim wypadku wykonana - pozostawiamy to inwencji programisty. W naszym programie wypisujemy na pozycji bombowca kratkę #, a obok czerwony napis KRACH.

Jeśli samolot nie spotkał się jeszcze ze swoim przeznaczeniem, sprawdzamy, czy wszystkie domy w mieście zostały zniszczone. W tym celu wystarczy zsumować wysokości domów z pozycji od 6 do 75 tablicy miasto. Jeśli otrzymamy wynik zero, w mieście nie ma już żadnego domu i grę kończymy z gratulacjami - również zwracamy true.

W przeciwnym razie obieg nie dobiegł jeszcze końca i gra toczy się dalej. Zatem zwracamy false.

Procedura Końca Gry

Pozostała nam ostatnia już funkcja Końca Gry. Z uwagi na jej prostotę nie będziemy rysować schematu blokowego. Funkcja ta wypisuje na ekranie pytanie, czy gracz chce zagrać jeszcze raz. Jeśli wciśnie on klawisz T, to funkcja zwraca wartość false, a true w każdym innym przypadku.