Zadanie zaliczeniowe z Programowania Obiektowegoi C++ Rok 2OO4/2OO5 Wersja 1.02 I. Wstęp. Za siedmioma górami, za siedmioma lasami starożytne królestwo nawiedził wielki i potężny Kamienny Smok. Wiele szkód uczynił: podpalał lasy i chłopskie chaty, porywał owce i dzieci (powiadano, że trafiały potem na jego stół). Wielu śmiałków próbowało już zgładzić potwora, żadnemu jednak nie udało się dotąd dotrzeć do jego legowiska, gdyż droga doń wiodła przez Labirynt. Niezwyczajny był to Labirynt - pełno w nim bezdennych przepaści, dziwnych, wybuchających miejsc i magii. Próbowano juz wyburzać mury - ale po pewnym czasie odrastały jak przebiśniegi; zamurowywano przepaście, ale po pewnym czasie cegły rozsypywały się w proch. Aż wreszcie przybyła drużyna słynnych pięciu bohaterów pod twoim dowództwem aby zmierzyć się z Niebezpieczeństwem. Dla okolicznych mieszkańców po raz pierwszy zaświecił promień nadziei. II. Opis. 1. Plansza Plansza labiryntu jest podzielona na kwadraty - pola labiryntu. Gracz "chodzi" po labiryncie 5 rycerzami. W jednym ruchu gracz może przesunąć jednego z rycerzy na jedno z czterech pól mających wspólną krawędź z polem, na którym stoi przesuwany rycerz, pod warunkiem, ze nie jest to pole z murem (patrz opis pól labiryntu), że nie jest to pole zajęte przez innego rycerza i że pole mieści się na planszy. (Niektórzy rycerze poruszają się inaczej, patrz ich opis.) Numery pól planszy rosną w dół i w prawo. Plansza labiryntu jest plikiem o formacie opisanym w punkcie 5. 2. Rycerze. Każdy uczestnik wyprawy należy do jednej z 4 kategorii: - rycerz Nadzwyczajny Nie posiada żadnych wyróżniających zdolności, poza wyjątkowym uporem w dążeniu do celu. - rycerz Zjadacz Posiada specjalną, stalową Sztuczną Szczękę, pozwalającą przegryzać niektóre typy murów. Niestety posiada ona ograniczoną liczbę zębów, a zjedzenie jednego muru powoduje utratę jednego z nich. Liczba zębów którą posiada Zjadacz na początku gry zależy od planszy - labiryntu; zużyte zęby może sobie wymienić na nowe w specjalnym polu - magazynie dentystycznym (patrz opis pól labiryntu). Niestety, w żadnym momencie gry Szczęka nie może posiadać więcej zębów, niż na początku planszy. - rycerz Budowniczy Nie rozstaje się nigdy z workiem cegieł. Jego specjalnością jest zamurowywanie Bezdennych Przepaści. Nowe cegły może otrzymać w magazynie budowlanym. Niestety, pojemność jego worka jest ograniczona (ograniczenie zależy od planszy i jest wyznaczone przez liczbę cegieł posiadanych po uruchomieniu planszy). - rycerz Skoczek Potrafi przeskoczyć nad jednym polem labiryntu, niezależnie od tego, jakiego rodzaju jest to pole. Często bywa wykorzystywany jako zwiadowca, co niestety czasem kończy się jego niespodziewaną śmiercią (jeśli wpadnie do dziury lub na minę - gracz nie zawsze widzi pole na które skacze Skoczek). Zgodnie z ogólnymi zasadami nie może skoczyć na pole znajdujące sie poza labiryntem, pole z innym rycerzem lub z murem. 3. Pola labiryntu - pole zwykłe Pole, na które rycerz może wejść, nie mające żadnych własności dodatkowych. - pole mur Można spotkać dwa rodzaje murów: mury jadalne i wieczne. Mury wieczne sa to pola, na które gracz nigdy nie może wejść. Nie można ich zjeść; nie zniszczy ich nawet mina. Mury jadalne są to pola, na które rycerz nie może wejść, chyba że usunie mur poprzez zjedzenie go lub wybuch miny. - pole z miną Jeśli rycerz wejdzie na pole z miną, mina wybucha. W polu rażenia miny znajduje się pole, na którym mina była umieszczona oraz wszystkie pola, które miały wspólną krawędź z tym polem. Wszystkie mury jadalne znajdujące się w polu rażenia miny ulegają zburzeniu, a wszyscy rycerze giną. Niestety na mocy czarów mina pozostaje. - pole teleport Każdy rycerz, który znajdzie się na tym polu, zostanie przeteleportowany na inne pole znajdujące się na planszy. Na szczęście jeden teleport może przenosić tylko w jedno miejsce. Jeśli miejsce docelowe jest zajęte (mur, inny rycerz), to teleport nie działa. - pole dziura Rycerz, który stanie na to pole wpada w przepaść bez dna i ginie. Dziurę może zamurować rycerz Budowniczy (zużywa na to wszystkie posiadane cegły). Po zamurowaniu można bezpiecznie przechodzić przez pole z dziurą. - pola magazyny Każdy magazyn przechowuje pewne zasoby (magazyn dentystyczny - zęby, a magazyn budowniczy - cegły). Magazyny są dwóch typów: -- pole magazyn cegieł Na tym polu rycerz Budowniczy może uzupełnić worek z cegłami. Ładowanie cegieł do worka odbywa się w momencie wejście rycerza na pole z magazynem cegieł. Oczywiście tylko wtedy, gdy rycerz jest budowniczym - w przeciwnym przypadku nic się nie dzieje. -- pole magazyn dentystyczny Na tym polu rycerz Zjadacz może uzupełnić brakujące zęby w Stalowej Szczęce. Uzupełnianie odbywa się w momencie wejścia na pole; jeśli na pole wejdzie rycerz o innej specjalności niż Zjadacz, nic się nie dzieje. - pole legowisko smoka To tu mają dotrzeć rycerze. Jeśli rycerz dojdzie do legowiska smoka, to ukrywa się tam, czekając na resztę towarzyszy (liczba rycerzy, którzy muszą dojść do tego miejsca jest określana w pliku z danymi). Wynika stąd, że gracz nie może go już przesuwać. 4. Inne Rycerz, który zginął w labiryncie, znika z planszy. Jedna jednostka czasu w labiryncie to jeden ruch - czyli jedno przesunięcie rycerza (pod wpływem działania magii czas utracił swoją ciągłość). Gracz widzi pola, na których stoją rycerze, pola, które mają wspólną krawędź z jednym z pól, na których stoją rycerze, oraz wszystkie pola, które widział do tej pory. "Widzenie" pola oznacza, że gracz wie, jakiego typu ono jest, nie widzi jednak dokąd prowadzi teleport. 5. Format pliku z labiryntem. Liczba całkowita dodatnia (w), podana w pierwszym wierszu pliku jest wysokością labiryntu. W drugim wierszu znajduje się liczba równa szerokości labiryntu (s). W następnych w wierszach znajduje się zakodowany opis pól planszy - w każdym wierszu znajduje się opis s pól. (Opis pola labiryntu o współrzędnych (i,j) znajduje się więc w i+2 wierszu i jest to j-ty z kolei symbol). Symbole kodujące pola planszy są oddzielone średnikami. Lista symboli: Z (pole zwykłe) J (mur jadalny) W (mur wieczny) M (pole z miną) Tn,m (teleport przenoszący rycerza na pole o współrzędnych (n,m), gdzie 1<=n<=s, 1<=m<=w) D (pole dziura) C (magazyn cegieł) M (magazyn dentystyczny) L (legowisko smoka, takie pole jest na planszy dokładnie jedno) W następnym wierszu znajduje się para liczb całkowitych oddzielona średnikiem. Są to współrzędne wejścia do labiryntu. W kolejnym wierszu znajduje się 5 symboli (oddzielonych średnikami) opisujących drużynę rycerzy: N (Rycerz Nadzwyczajny) Zn (Rycerz Zjadacz; n jest liczbą całkowitą dodatnią opisującą liczbę zębów, jaką posiada on w swojej Stalowej Szczęce) Bn (Rycerz Budowniczy; n jest liczbą całkowitą dodatnią opisującą liczbę cegieł znajdujących się w jego worku) S (Rycerz Skoczek) W ostatnim wierszu znajduje się liczba całkowita dodatnia nie większa od 5, określająca, ilu rycerzy musi dojść do legowiska smoka, aby gracz został uznany za zwycięzcę. Ponieważ na jednym polu labiryntu może stać tylko jeden rycerz (oczywistym wyjątkiem jest legowisko smoka), to rycerze na polu startowym pojawiają się pojedynczo (gdy jeden zejdzie z tego pola wchodzi tam następny - o ile jeszcze jest oczywiście - kolejność jest zadana kolejnością w danych). Można założyć poprawność danych. Przykładowy plik z planszą może więc wyglądać w ten sposób: 4 3 Z;L;W T1,2;Z;J C2;D1;Z M1;Z;W 4;2 N;S;B3;Z2;S 3 III. Zadanie. Napisz program umożliwiający przeprowadzenie pojedynczej rozgrywki. Program ma na początku wczytać planszę, potem ma ją wyświetlić i umożliwić graczowi wykonywanie poszczególnych ruchów. Interfejs może być tekstowy albo graficzny (za jeden i drugi można dostać maksimum punktów) i sensownie wygodny. Można przyjąć rozsądne ograniczenia danych, umożliwiające wygodne przedstawienie planszy na ekranie (np. dotyczące szerokości i wysokości labiryntu). IV. Historia zmian. 1.00: 25.X.2004 (wersja oryginalna) 1.01: 13.XI.2OO4 1.02: 15.XI.2OO4 Drobne korekty i uściślenia: - przecinek zamiast średnika w Tn,m, - powtórzenie w przypadku Skoczka ogólnej zasady mówiącej na jakie pola nie można wejść.