RL2: Karramba!#
Dawno, dawno, w Krainie Deszczowców zaginął sławny badacz latających żab – profesor Baltazar Gąbka. Z Krakowa na ratunek wyrusza ekspedycja kierowana przez niemniej słynnego podróżnika – Wawelskiego Smoka (buhuhahaha!) – któremu w niebezpiecznej wyprawie towarzyszy książęcy kucharz – Bartolini Bartłomiej herbu Zielona pietruszka (mamma mia! do usług!). Ich śladem podąża tajemniczy Don Pedro…
…szpieg z Krainy Deszczowców.
Krakowiacy doskonale wiedzą, że Deszczowcy są bardzo niezadowoleni po wizycie profesora Gąbki i nie idą po Smoka. Idą po nich, a ekspedycja tylko stoi im na drodze. Dlatego chcą mieć podgląd na żywo stanu ratunkowej wyprawy, aby przygotować się w razie zagrożenia i zapewnić powodzenie wyprawy. Sprytny szpieg przewidział jednak obawy mieszkańców grodu Księcia Kraka i, śledząc Smoka i Bartłomieja Bartoliniego, zaciera po nich ślady, aby nie były widoczne z dala.
Mając mało zaufania do studentów Uniwersytetu Jagiellońskiego, krakowiacy zwracają się do uczelni technicznej z prośbą o napisanie aplikacji umożliwiającej śledzenie poczynań wyprawy. Wybór padł na naszą Uczelnię, a do wykonania zadania wyznaczono właśnie Ciebie, mistrza swego fachu. Pomóż mieszkańcom Krakowa zabezpieczyć powodzenie ekspedycji!
W pliku board_utils.h znajdziesz pomocnicze funkcje (z ich opisami) służące stworzeniu planszy i ruchom postaci. Skorzystaj z tych funkcji w swoim kodzie.
Etapy:#
Etap 1 (5 pkt)#
Program jako argumenty przyjmuje dwie liczby całkowite większe od \(2\): \(n\) i \(m\). Utwórz plik o nazwie BOARD_FILE i rozmiarze \(m \times (n+1)\) bajtów, a następnie zmapuj jego zawartość do obszaru pamięci dzielonej. Następnie zainicjalizuj zmapowaną pamięć, używając dostarczonej funkcji fill_board (z pliku board_utils.h).
Po inicjalizacji, w pętli wykonaj STEP_COUNT losowych ruchów ekspedycji (pobierz ruch funkcją get_random_move i wykonaj go przy pomocy move_pos), zaczynając z losowego miejsca. Pozycję ekspedycji oznaczaj (za pomocą set_char) znakiem S, a ślad po niej znakiem =. Po każdym ruchu czekaj \(100\) ms.
Na samym końcu wypisz Expedycja zakończona!, zwolnij wszystkie zasoby i zakończ działanie programu. Możesz podejrzeć zawartość stworzonego pliku, aby upewnić się, czy pamięć została poprawnie wypełniona. Aby śledzić zmiany w pliku na żywo, użyj watch -n 0.1 tail board podczas działania programu.
Etap 2 (5 pkt)#
Utwórz proces Don Pedro, który posłuży do śledzenia przebiegu ekspedycji. W tym etapie mapa staje się sekcją krytyczną – zabezpiecz dostęp do niej pojedynczym współdzielonym muteksem.
Don Pedro najpierw śpi WAIT_N*100 ms, a potem wykonuje STEP_COUNT ruchów, śledząc ekspedycję. W tym celu:
- jeśli Don Pedro jest na tropie Smoka (
has_trailzwraca niezerową wartość), to zmień zawartość pola, na którym aktualnie przebywa Don Pedro, na spację (); w przeciwnym wypadku, zmień zawartość tego pola na kropkę (.) i wypisz w terminaluKarramba!, - pobierz ruch do wykonania funkcją
get_trail_movei wykonaj go (move_pos).
Etap 3 (5 pkt)#
Ekspedycja zdaje sobie sprawę, że jest śledzona. Smok wpadł zatem na pomysł, aby wysyłać szpiegowi fałszywe sygnały dotyczące kierunku, w którym ekspedycja się uda. Stwórz w tym celu (i otwórz do zapisu) w procesie-rodzicu plik FIFO o nazwie FIFO_NAME i otwórz go do odczytu w procesie szpiega.
Po każdym wykonanym ruchu, ekspedycja wysyła przez FIFO wylosowany ruch (funkcją get_random_move).
Don Pedro, teraz w nieskończonej pętli, czeka na wiadomości w FIFO. Sprytny szpieg wie, że wiadomości, które dostaje, to zmyłka, dlatego po odebraniu każdej wiadomości wypisuje Kierunek <znak>? Nie ze mna te numery, karramba!, a następnie wykonuje ruch zgodnie z poprzednim etapem.
Proces ekspedycji, po wykonaniu STEP_COUNT ruchów, zamyka kolejkę, sygnalizując koniec podróży. Gdy Don Pedro wykryje, że kolejka została zamknięta, przerywa pętlę i kończy się. Na samym końcu proces-rodzic usuwa plik kolejki.
Etap 4 (6 pkt)#
Don Pedro dzielnie śledzi poczynania Smoka Wawelskiego i Bartłomieja Bartoliniego. Czasem jednak z Krainy Deszczowców przyjdzie nakaz wykonania specjalnej misji, którą szpieg musi niezwłocznie obsłużyć. Utwórz w procesie Don Pedro gniazdo sieciowe nasłuchujące na porcie PORT. Za każdym razem, gdy zostanie nawiązane połączenie, Don Pedro wypisuje Polaczono z dowodztwem -- odbiór! i zamyka to połączenie.
Połączenie można wykonać np. za pomocą polecenia netcat [-z] localhost <port> (flaga -z rozłącza natychmiastowo po połączeniu). Uwaga – Don Pedro powinien nadal oczekiwać na komunikaty z łącza. Oczekiwanie zrealizuj za pomocą epoll (ew. poll lub select).
Etap 5 (4 pkt)#
Zrealizuj wykonanie misji specjalnej. Zamiast kończyć połączenie od dowództwa (netcat), oczekuj na jeden z czterech znaków: W, A, S lub D, oznaczające stronę, w którą szpieg ma wykonać krok.
Po odebraniu poprawnego znaku wypisz Komunikat <znak> -- przyjęto!, postaw na aktualnym polu znak *, a następnie wykonaj ruch funkcją move_pos, przekazując otrzymany znak. Pozostałe znaki są ignorowane.
Znaki czytamy, oczekując jednocześnie na komunikaty z pozostałych etapów, do momentu rozłączenia się klienta. Don Pedro może być połączony tylko z jednym kanałem dowództwa jednocześnie, odrzucaj nadmiarowe połączenia. Jednak po rozłączeniu się z dowództwem, kolejne połączenie powinno zostać zaakceptowane.