opis_programu.pdf
(
147 KB
)
Pobierz
Dariusz Mikołajczuk
Opis programu labirynt
NAJWAŻNIEJSZE ZMIENNE
W funkcji
main
zadeklarowane są następujące istotne struktury danych:
•
flist *first
– wskaźnik do pierwszego elementu listy jednokierunkowej przechowującej
listę plików schematów labiryntów (znajdujących się w folderze
data\
).
struct flist {
usint num;
numer danej planszy odpowiadający pozycji w pliku
.
data\file_list.txt zawiera się w przedziale 1 … file_count.
uchar tab[56];
ścieżka do pliku ze schematem wraz z prefiksem „data\”.
struct flist *next;
wskaźnik do kolejnego elementu listy.
};
•
unsigned short int file_count
– liczba istniejących plików ze schematami labiryntów.
•
FILE *plik_z_plansza
– aktualnie używany plik z planszą. Wykorzystywany tylko
podczas ładowania danych do następującej tablicy.
•
pos_data **tab
– dynamiczna tablica dwuwymiarowa następujących struktur:
struct pos_data {
bool now;
-
określa czy aktualnie znajdujemy się w tym punkcie (podczas gry).
bool checked;
-
określa czy wykonano już przejście przez dany punkt
(wykorzystywane podczas sprawdzania czy istnieje przejście przez labirynt).
bool iso;
-
jeśli przez dany punkt istnieje przejście (dotyczy to też korytarzy
na zewnątrz labiryntu dany parametr ustawiony jest na true, w innym
wypadku na false.
struct kierunki{
- określają kierunki, w które można przejść z danego punktu.
bool up;
bool down;
bool right;
bool left;
};};
•
pos a
– przechowuje rozmiary labiryntu.
struct pos {
unsigned short int x;
unsigned short int y;
};
1
Przykładowa zawartość tablicy labiryntu wraz z rozmiarami.
0
1
2
3
4
5
6
7
8
9
10
11
12
0
1
X
X
X
X
O
O
O
X
X
X
X
2
O
O
O
X
X
X
X
O
O
X
X
3
X
X
O
O
O
O
X
X
X
X
X
4
X
X
X
X
X
O
O
O
O
O
X
5
X
X
X
X
X
X
X
X
X
O
X
6
O
O
O
O
X
X
X
X
X
O
X
7
O
O
O
O
O
O
O
O
X
O
X
8
X
X
X
X
X
X
X
O
X
O
X
9
O
O
O
O
O
O
O
O
X
O
O
Kolor jasnoszary reprezentuje korytarze na zewnątrz labiryntu, ciemnoszary – dane
pochodzące z pliku schematu. X – oznacza ścianę, O – korytarz.
W danym przypadku rozmiary labiryntu przechowywane przez zmienną a wynoszą:
a.x = 11;
a.y = 9;
Do poszczególnych elementów tablicy odwołujemy się najpierw poprzez podanie
numeru wiersza, potem kolumny np.:
pos b;
b.x = 5;
b.y = 6;
tab[b.y][b.x].iso;
2
DZIAŁANIE PROGRAMU (streszczenie)
Funkcja główna
main
wykonuje następujące działania:
Wczytanie listy plików schematów:
file_list_load(&first, &file_count);
Wykonywane jednorazowo, wczytanie ścieżek wszystkich (istniejących) plików
wymienionych w pliku
data\file_list.txt
do listy jednokierunkowej.
Funkcja
file_list_load
obsługuję takie błędy jak nieistnienie pliku
file_list.txt
oraz brak zawartości tego pliku. Pomija puste linie tegoż pliku oraz nieistniejące pliki
wymienione w nim.
Przyjmowane jest, że pojedyncza linia zawiera pojedynczą nazwę pliku w folderze
data\
(bez ścieżki). Nazwa pliku oraz rozszerzenie nie są odróżniane, w obydwu mogą
pojawiać się spacje.
W
file_count
zapisywana jest ilość plików (tzn. numer ostatniego pliku).
Następnie zostaje uruchomiona nieskończona pętla główna, która:
1.
Znajduje w liście plansz, tę o danym numerze
num
(początkowo
num
= 1) oraz pobiera
z niej ścieżkę do pliku schematu labiryntu.
2.
Otwiera plik spod pobranej ścieżki.
3.
Wykonuje pierwszy odczyt pliku mający na celu ustalenie rozmiarów labiryntu.
Polega to na sprawdzeniu ilości znaków w pierwszym niepustym wierszu oraz ilości
wierszy pliku. Wszelkie błędy w zapisie pliku: nieprawidłowe białe znaki oraz
nieprawidłowe znaki; są rozpoznawane (wspólnie z kolejną funkcją odczytującą).
Błędy są zgłaszane, po czym następuje przejście do kolejnego kroku pętli i wczytanie
kolejnej losowej planszy.
4.
Przydzielenie pamięci dla tablicy przechowującej labirynt na podstawie odczytanych
rozmiarów labiryntu.
5.
Kolejny odczyt pliku ze schematem labiryntu. Ostatecznie wczytywane są dane do
tablicy labiryntu. Przy czym przetwarzane tu są tylko obszary tablicy odpowiadające
wnętrzu labiryntu. Określane są tu parametry
iso
oraz
now
dla każdego z punktów
labiryntu
.
6.
Po pomyślnym wczytaniu labiryntu plik ze schematem jest zamykany. Uruchamiana
jest funkcja
okresl_strzalki(tab, a)
, która dla każdego z punktów labiryntu
(włącznie z zewnętrznymi korytarzami) określa parametry umożliwiające łatwe
sprawdzenie możliwych kierunków poruszania.
Ustalane są też parametry
iso, now, checked
dla zewnętrznych korytarzy.
3
7.
Uruchamiana jest funkcja sprawdzająca czy istnieje przejście przez labirynt. Po kolei
sprawdzane są wszystkie wejścia do labiryntu. Dla każdego wejścia:
◦Analizowany jest aktualny punkt w jakim się znajdujemy na podstawie strzałek
oraz parametrów
iso, checked
oraz współrzędnych aktualnej pozycji, jest to
zadaniem funkcji
otoczenie(pos_data **tab, pos_act *act, pos a).
◦Jeżeli z danego punktu istnieje tylko jedno wyjście (korytarz) oznacza aktualny
punkt jako sprawdzony
checked
i przechodzi do kolejnego punktu.
◦Jeżeli aktualny punkt jest punktem węzłowym (maksymalnie trzy wyjścia)
wykonuje:
▪wybiera jedno, którym aktualnie podąży np.
up.
▪ustawia pozycje aktualnego punktu tablicy jako sprawdzoną:
checked.
▪na szczycie stosu zapisuje aktualną pozycję, wraz ze wszystkimi możliwymi
wyjściami z niej, oczywiście w naszym przypadku parametr
up
jest
zanegowany (użyte przejście zawsze jest negowane).
▪przechodzi do kolejnego, uprzednio wybranego punktu (
up).
◦Jeżeli aktualnie napotkano ślepy zaułek (drogę bez wyjścia) przechodzi do
pozycji węzłowej znajdującej się na szczycie stosu, usuwa ją ze stosu i powraca
do początku algorytmu.
◦Jeżeli napotka ślepy zaułek, a stos jest pusty, próbuje wejść kolejnym wejściem
labiryntu. O ile jakieś zostały, jeśli nie oznacza to, że przejście nie istnieje.
◦Kiedy po wykonaniu aktualnego przejścia znajdujemy się w prawej krawędzi
labiryntu (przy wyjściu) oznacza to, że przejście istnieje.
8. Kiedy wiadomo czy istnieje przejście przez daną planszę uruchamiany jest interfejs,
czyli funkcja
graj()
. Która:
◦Wyświetla informacje jeśli przejście nie istnieje, wówczas przechodzi do kolejnej
planszy.
◦Jeśli labirynt jest za duży do wyświetlenia w standardowym oknie konsoli wyświetla
odpowiedni komunikat i przechodzi do kolejnej planszy.
◦Jeśli wszystko poszło pomyślnie wyświetla prosty interfejs umożliwiający
poruszanie się po labiryncie. Sterowanie:
▪
kursory
– poruszanie się po labiryncie.
▪
spacja
– przejście do kolejnej (losowej) planszy, poprzedzone pytaniem.
▪
q –
wyjście z programu, poprzedzone pytaniem.
◦Po przejściu przez labirynt wyświetlane jest pytanie co robić dalej:
▪
spacja
– zmienia planszę na kolejną losową.
▪
n
– ta sama plansza.
▪
q
– wyjście z programu.
Opuszczenie funkcji
graj()
, gdy wybrano przejście do kolejnej planszy lub napotkano
błąd, powoduje wylosowanie nowego numeru planszy oraz przejście do kolejnego kroku
głównej pętli.
4
OBSŁUGA BŁĘDÓW
Kody błędów:
•
0
–
sukces
, brak błędu.
•
1
–
błąd niekrytyczny:
◦niektóre pliki z file_list.txt nie zostały wczytane (z powodu ich braku).
◦niepoprawny plik ze schematem labiryntu.
◦labirynt zbyt duży aby go wyświetlić.
◦brak przejścia przez daną planszę.
Błąd niekrytyczny powoduje wyświetlenie komunikatu o błędzie, jeśli to konieczne –
przejście do kolejnej losowej planszy oraz kontynuowanie pracy programu.
•
2
–
błąd krytyczny:
◦plik
data\file_list.txt
nie istnieje.
◦plik powyższy jest pusty lub nie zawiera żadnej poprawnej nazwy pliku.
◦nie odnaleziono w liście jednokierunkowej planszy o poszukiwanym numerze
num
(błąd praktycznie niemożliwy).
◦błąd przy otwarciu pliku (który znajduje się już w liście), na wypadek gdyby plik
został usunięty podczas pracy programu.
Błąd krytyczny powoduje wyświetlenie komunikatu błędu i zakończenie pracy
programu.
•
99
–
błąd krytyczny
, spowodowany niemożliwością przydzielenia pamięci na
dynamiczne struktury danych. Powoduje wyświetlenie komunikatu o braku pamięci oraz
zakończenie pracy programu.
5
Plik z chomika:
mikdor
Inne pliki z tego folderu:
labirynt_windows_version.tar.bz2
(171 KB)
opis_programu.pdf
(147 KB)
labirynt.exe
(32 KB)
labirynt.dev
(0 KB)
lab.o
(18 KB)
Inne foldery tego chomika:
BCD
labirynt linux version
Zgłoś jeśli
naruszono regulamin