Wejściówka na lab.11

Napisz program, który tworzy dynamiczną listę jednokierunkową obiektów – figur geometrycznych jednego, dowolnie wybranego typu z dwóch wykorzystywanych na lab. 10. W tym celu do klasy reprezentującej wybraną figurę geometryczną dodaj pole nast, które ma być dostępne w trybie public, tak aby można było z niego korzystać w funkcji main. Po utworzeniu listy składającej się z co najmniej pięciu obiektów, wywołaj metodę szukaj, która znajduje w liście pierwszą figurę, dla której odległość jej geometrycznego środka od wskazanego przez użytkownika punktu, jest mniejsza niż 1. Użytkownik wskazuje ten punkt na płaszczyźnie przez podanie jego dwóch współrzędnych. Środek geometryczny figury obliczany jest jako średnia z odpowiednich współrzędnych wszystkich wierzchołków tej figury. Odległość między wskazanym punktem a środkiem figury liczymy jak zwykłą odległość euklidesową między punktami na płaszczyźnie. Na koniec działania programu lista powinna być usuwana.

Przy pisaniu kodu metody szukaj oraz instrukcji jej wywołania w funkcji main wzoruj się na przykładowym kodzie zaprezentowanym na slajdzie 157, wykład 10.

Uwaga: kod programu napisanego na lab. 10, zadanie poziomu I, zwłaszcza klasy reprezentujące figury geometryczne, oraz kod wejściówki będą stanowiły punkt startowy do realizacji zadań na lab. 11.

Wskazówki dotyczące zadań semestralnych

Każde zadanie wymaga napisania programu implementującego grę.

  1. Program powinien udostępniać pracę w dwóch trybach: gra z drugim graczem (program przyjmuje na przemian polecenia wykonania ruchów od dwóch osób) i gra z komputerem.
  2. W obydwu w/w przypadkach program dokonuje sprawdzenia poprawności ruchu. Jeżeli proponowany ruch jest niezgodny z zasadami gry, program powinien to zakomunikować i odmówić jego wykonania.
  3. W przypadku gry z komputerem wystarczy, że program będzie wykonywał ruchy losowe, tj. wygenerowane z pomocą generatora liczb losowych. Te losowe ruchy również powinny być zgodne z regułami gry. Uwaga: nie ma obowiązku implementowania żadnych strategii zwiększających szanse na wygraną komputera (tzw. „sztucznej inteligencji”).
  4. Powyższe wymagania są dobrym pretekstem do zaimplementowania następującej hierarchii dziedziczenia klas: klasa bazowa gracz i dwie klasy pochodne: gracz-człowiek i gracz-komputer. Jest to też dobra okazja do wprowadzenia do kodu programu polimorfizmu (metod wirtualnych oraz ewentualnie czysto wirtualnych).
  5. Program powinien udostępniać na żądanie użytkownika tablicę wyników wszystkich dotychczas rozegranych gier. W tablicy powinny znaleźć się nazwy graczy (w przypadku gry z komputerem – 'komputer’). Tablica ta powinna być zapisywana do pliku.
  6. Powinna istnieć możliwość przerwania w każdym momencie już rozpoczętej gry i wyjścia z programu. W takiej sytuacji aktualny stan gry powinien zostać zapisany do pliku. Przy ponownym uruchomieniu programu powinna istnieć możliwość powrotu do przerwanej rozgrywki.
  7. Wszystkie dane wprowadzane z klawiatury przez użytkownika oraz wczytywane z pliku powinny być kontrolowane pod względem ich poprawności. Np. kiedy dane mają być liczbowe, to po pierwsze należy sprawdzić, czy wprowadzony tekst jest liczbą, a po drugie – czy liczba ta należy do dozwolonego przedziału lub zbioru wartości. Tak samo w przypadku odczytywania danych z pliku, należy sprawdzać, czy są one zgodne ze składnią pliku. W razie odstępstwa, należy wyświetlić komunikat o błędzie i zaprzestać pobierania danych z uszkodzonego pliku. Generalnie zasada jest taka, że program nie może przerwać swojej pracy lub zacząć działać błędnie z powodu niepoprawnych danych.

lab.10 – hint

Zadania pierwszego i drugiego poziomu na lab. 10 będą polegały na rozwinięciu kodu napisanego na lab. 9 (dopisaniu nowych składowych do obydwu klas: (1) trapez i (2) trójkąt lub prostokąt, oraz zademonstrowaniu ich poprawnego działania). Jeżeli ktoś nie zrealizował całego zakresu zadania na lab.9 poziom 1, dobrym pomysłem jest dokończenie tego samodzielnie w domu, tak żeby na zajęciach zająć się od razu realizacją bieżącego materiału.

Wejściówka na lab.10

Zaprojektuj klasę, która posłuży do tworzenia obiektów reprezentujących macierze przechowujące liczby rzeczywiste.

Klasa macierz posiada pola do zarządzania dwuwymiarową, dynamiczną tablicą reprezentującą komórki macierzy. Wszystkie pola są prywatne.

Posiada trzy konstruktory:

  1. domyślny, inicjalizujący wszystkie pola tak, aby powstała macierz o wymiarach 1 na 1; w tym przypadku nie powinny być alokowane żadne dodatkowe zmienne dynamiczne,
  2. konstruktor z argumentami opisującymi wymiary macierzy; wymiary mogą być dowolne większe od zera. Pamięć pod komórki macierzy powinna być alokowana dynamicznie. Przy okazji działania tego konstruktora przetestuj, jakie są górne granice dostępnej pamięci w twoim komputerze, tj. podając coraz większe wymiary macierzy doprowadź do sytuacji, kiedy alokacja pamięci w końcu nie powiedzie się. Zapisz uzyskane wartości graniczne, będą potrzebne na wejściówce,
  3. konstruktor kopiujący, który utworzy drugą macierz identyczną co do rozmiaru i zawartości.

oraz destruktor, który zwalnia dynamicznie zaalokowane zasoby.

Posiada też seter i geter do komórek macierzy. Obydwie metody powinny kontrolować poprawność argumentów wejściowych, tj. czy współrzędne żądanej komórki mieszczą się w dozwolonych granicach.

Dodatkowo posiada metodę, która realokuje rozmiar macierzy, tj. powiększa jej rozmiar lub pomniejsza. W przypadku pomniejszenia, część informacji zapisanej w komórkach macierzy jest tracona. W przypadku powiększenia nowo dodane komórki są zapełnianie wartością domyślną (dowolnie ustaloną).

Napisz prosty program testujący działanie wszystkich konstruktorów, destruktora i metod klasy macierz. Utwórz obiekt z wykorzystaniem konstruktora domyślnego. Utwórz drugi obiekt reprezentujący macierz o dowolnym rozmiarze i zainicjuj go wartościami losowymi z przedziału (-1,1) (użyj do tego setera). Utwórz trzeci i czwarty, obydwa będące kopiami odpowiednio pierwszego i drugiego obiektu. Porównaj zawartość komórek miedzy oryginałami i kopiami (użyj do tego getera).

Wejściówka na lab.9

Zaprojektuj klasę, reprezentującą figurę na płaszczyźnie: trapez.

Zaproponuj zestaw pól dla tej klasy, pozwalający na jednoznaczne określenie jej położenia na płaszczyźnie względem początku układu współrzędnych oraz jednoznacznie określający jej rozmiary (np. długości boków, podstawy, itd.). Dla uproszczenia przyjmij, że trapez jest zawsze rysowany w określonej pozycji, np. podstawą równolegle do osi X. Projektując zestaw pól postaraj się zminimalizować ich liczbę. Np. gdyby to dotyczyło kwadratu, to do określenia położenia wystarczą współrzędne jednego z wierzchołków, np. lewy-dolny, a do określenia rozmiarów – długość jednego boku. Za pomocą tych wartości jesteśmy już w stanie łatwo wyznaczyć w kwadracie współrzędne wszystkich pozostałych wierzchołków oraz długości pozostałych boków.

Zbiór pól reprezentujących położenie trapezu powinien być rozłączny ze zbiorem pól reprezentujących jego rozmiary, tak aby ewentualne operacje zmiany położenia nie obejmowały modyfikacji pól rozmiaru, a np. skalowanie nie modyfikowało pól położenia.

Wszystkie pola mają być niedostępne z zewnątrz (zadeklarowane jako private).

Do klasy dodaj trzy metody zadeklarowane jako publiczne:

  1. Pierwsza – ma ustalać położenie i rozmiary figury, tj. modyfikować wartości pól opisujących położenie i rozmiar. Nowe wartości dla pól powinny być podawane w argumentach wywołania metody. Metoda powinna kontrolować poprawność wartości podawanych w argumentach wywołania i jeżeli są nieprawidłowe (np. ujemne długości boków) powinna je zastępować bezpiecznymi wartościami domyślnymi.
  2. Druga – powinna wypisywać wartości wszystkich pól figury w oknie konsoli oraz dodatkowo wypisywać aktualne współrzędne wszystkich jej wierzchołków wyliczone na podstawie wartości pól.
  3. Trzecia – powinna wyrażać przekształcenie symetrii środkowej, tj. jako argument powinna przyjmować współrzędne punktu symetrii środkowej na płaszczyźnie, względem którego figura ma zostać przekształcona, a w swoim działaniu powinna przeliczyć wszystkie wartości tych pól, które są odpowiedzialne za położenie tak, aby w rezultacie tego działania przyjęły one wartości określające położenie figury po przekształceniu.

Napisz program, który w funkcji main deklaruje obiekt typu trapez, po czym:

  1. inicjalizuje go wartościami pobranymi od użytkownika, tak aby powstał prawidłowy trapez, korzystając z metody nr 1,
  2. wywołuje na rzecz tego obiektu metodę wypisującą wszystkie pola i współrzędne w oknie konsoli,
  3. prosi użytkownika o podanie współrzędnych punktu symetrii środkowej i wywołuje na rzecz tego obiektu metodę przekształcenia dla zadanego punktu,
  4. ponownie wywołuje na rzecz tego obiektu metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby zobaczyć nowe położenie figury,
  5. ponownie wywołuje na rzecz tego obiektu metodę symetrii środkowej z tym samym punktem symetrii co poprzednio,
  6. a na koniec jeszcze raz wywołuje metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby sprawdzić, czy figura wróciła na swoje miejsce.

Wejściówka na lab.8

Napisz program, który pobiera nazwę pliku od użytkownika, otwiera plik tekstowy o podanej nazwie w trybie do odczytu, odczytuje z niego niewielką liczbę dodatnią całkowitą, po czym zamyka go. Sprawdź za pomocą asercji, czy liczba w pliku rzeczywiście jest dodatnia i czy nie jest większa od 100 (przyjmij, że inny napis niż liczba całkowita nie może w nim wystąpić). Następnie zaczyna sprawdzać zręczność użytkownika: wyświetla na ekranie dowolny napis testowy, po czym oczekuje na wprowadzenie tego napisu przez użytkownika za pomocą klawiatury mierząc czas, jaki jest potrzebny użytkownikowi na wprowadzenie tego napisu. Do pomiaru czasu użyj funkcji time i difftime. Ta czynność pomiaru powtarzana jest tyle razy, ile wynosi liczba odczytana z pierwszego pliku. Rezultat każdego pomiaru czasu zapisywany jest do listy dynamicznej. Dla skończonej serii pomiarów zapisanych w liście obliczana jest mediana. Po zakończeniu testu zręczności program pobiera od użytkownika jeszcze jedną nazwę pliku, otwiera go w trybie do zapisu i zapisuje tam całą zawartość listy dynamicznej oraz – w ostatnim wierszu – mediana. Na koniec plik jest zamykany a lista usuwana.

Uwagi:
Zaproponuj własny sposób sprawdzenia, czy plik o podanej nazwie istnieje. Następnie napisz funkcję, która jako argument wywołania przyjmuje nazwę pliku, a zwraca wartość zero, jeżeli pliku nie ma, oraz 1 – jeżeli istnieje. Użyj tej funkcji w swoim programie do sprawdzenia, czy pierwszy plik istnieje, a jeżeli nie (np. kiedy użytkownik zrobi błąd, źle podając nazwę tego pliku), poproś o ponowne podanie nazwy pliku. Użyj tej funkcji do sprawdzenia również, czy drugi plik – do zapisu – istnieje, a jeżeli istnieje, poproś użytkownika o ponowne podanie nazwy pliku do zapisu (chcemy chronić już istniejące pliki przed ich nadpisaniem nowymi danymi).

Do sprawdzania błędów związanych z dostępem do pliku wykorzystaj stałą errno a do generowania komunikatów funkcje strerror i perror. Wszelkie komunikaty o sytuacjach błędnych, jakie wystąpiły w trakcie pracy programu związane np. z dostępem do plików, wysyłaj do standardowego strumienia dla komunikatów o błędach stderr.