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 |
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.
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:
|
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 |
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
Symbol | Przeznaczenie w algorytmie |
---|---|
sx | pozycja pozioma samolotu |
ox | poprzednia pozycja pozioma samolotu |
sy | pozycja pionowa samolotu |
oy | poprzednia pozycja pionowa samolotu |
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.
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 |
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.
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 |
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ę.
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 |
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.
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.