Panowie wielkie dzieki za zainteresowanie tematem. Naprawde pod tym wgledem forum wymiata - obawialem sie kazdy oleje moj problem a tu prosze - sa uzytkownicy, ktorym naprawde zalezy zeby podyskutowac i dzielic sie spostrzezeniami :) to naprawde budujace :)
Takie zadania są fajne. W pracy zawodowej klepię i klepię w kółko zadania z tej samej dziedziny, monotonia uwstecznia. Miło chociaż pomyśleć o czymś zupełnie innym niż się robi na co dzień, albo przypomnieć sobie jak to było w szkole :)
Ale teraz do rzeczy: mam teraz ogromny metlik i juz sam nie wiem jak sie do tego zabrac. wiec moze od poczatku. Rozwazam dwie opcje - klase abstrakcyjna np. "shape" z ktorej dziedziczyłbym metody dla klas pozostalych i konstruktor z parameterem "number" jako ilosc tych kwadracikow - takie rozwiazanie jednak kloci sie z "Interfejs powinny implementowac klasy przechowujace konkretne figury."
Prowadzący chciał żebyś wykazał się umiejętnością tworzenia hierarchii klas i (być może) szablonów. A to zadanie akurat można zrobić prościej bez takich zaawansowanych mechanizmów języka. Nie wiem co powiedzieć...
pomijam juz rozwodzenie sie nad sensem tego zdania, interpretuje je tak ze program musi byc przygotowny na n klas. No bo przeciez w momencie pisania programu nie jestem w stanie wymyslec ilez to klas mi potrzeba - figure z jakiej ilosci kwadracikow wymysli sobie uzytkownik.
Chwila. W momencie pisania musisz wiedzieć ile Ci potrzeba klas. Jakbyś nie wiedział, to byś nie mógł napisać programu z klas. Klasy są po to, że w
początkowym etapie projektu rzadko wiadomo jak będzie wyglądał projekt pod koniec. Np. w połowie realizacji projektu klient powie że poza takimi
figurami, potrzeba jeszcze figur w których kwadraciki łączą się narożnikami. Gdy napiszesz program z użyciem klas, to jest większe prawdopodobieństwo
że uda się go łatwo dostosować do nowych wymagań klienta. Jednak gdy piszesz program, gdy realizujesz jakiś konkretny projekt, to musisz wiedzieć ile
jakich klas potrzebujesz.
Dlatego tez dla mnie najbardizej naturalnym rozwiazaniem jest szablon.
Nie. Szablon naturalnym rozwiązaniem jest wtedy, gdy:
- ten sam kod ma działać na różnych typach
- ważna jest ultra wydajność i ten sam kod ma działać na różnych stałych - w tym przypadku kompilator wygeneruje
kilka wersji kodu, każda wersja optymalna dla każdej stałej.
Czyli w tym programie uzyskasz dzięki szablonom odwrotny efekt. W trakcie pisania byś musiał przewidzieć wszystkie
rozmiary figur jakie użytkownik sobie zażyczy i wygenerować wszystkie w trakcie kompilacji. Jeśli użytkownik będzie
chciał nową figurę, to program nie zaoferuje mu takiej możliwości. Ale na tych które wygenerujesz w trakcie kompilacji
przy pomocy szablonów, program będzie działał efektywniej, szybciej i mniej pamięci zajmie.
Mechanizmem który wychodzi na przeciw temu że nie wiesz co sobie zażyczy użytkownik jest PARAMETRYZACJA. I w
tym projekcie naturalnym rozwiązaniem jest napisanie procedury która utworzy na podstawie parametru wprowadzonego
przez użytkownika dowolne figury. Szablony dadzą efekt odwrotny.
Dalej. Uzytkownik wprawadza sobie ze chce miec klase "sevenmino" czyli figure z 7 kwadracikow. Ale takich figur moze byc bardzo duzo zatem konstruktor musi (w jakis ? - nieznany mi sposob) wygenerowac wszystkie rodzaje tego "sevenmina".
Ja bym chyba zrobił wektor wektorów. W każdym wektorze bym trzymał figury jednego rozmiaru. Do tego bym zrobił procedurę która
generuje wszystkie figury danego rozmiaru na podstawie parametry. Coś mniej/więcej tak:
void build( &vector , board, start_x, start_y, size , depth ) {
if( depth == size ) {
appendIfNotExists( vector , board );
return;
}
for( i=-1 ; i<2 ; i++ ) {
for( j=-1 ; j<2 ; j++ ) {
if( board[start_x+i][start_y+j] == exists )
continue;
board[start_x+i][start_y+j] = exists;
build( vector , board , start_x+i, start_y+j, size , depth+1 );
board[start_x+i][start_y+j] = not_exists;
}}
}
board[0][0] = exists;
build( vector , board , 0 , 0 , 7 , 1 );
mariotti pisales o rekurencji - i ten pomysl wydaje mi sie byc najfajnieszy, skoro uzytkownik chce figury zlozone z 7 kwadracikow to tworze sobie tablice 7x7 i teraz wychodze ze srodkowego kwadracika. to srodkowe pole to moja pierwsza para wspolrzednych -druga moge "przylepic" gdziekolwiek obok, na trzecia mam juz dwie mozliwosci itd... tutaj mi ewidentnie wyglada na rekurencje z nawrotami z tym ze nie za bardzo wiem jak to zakodzic... kolejna sprawa to przechowywanie tych rozwiazan... hash table ?
Będziesz miał masę powtarzających się figur, różniących się tylko offsete, albo obrotem. Trzeba napisać funkcję hash, która z dużym
prawdopodobieństwem przypisze inną liczbę innym figurom. Dzięki temu bardzo szybko wyszukasz powtarzające się figury i nie
dodasz dwa razy tej samej.
- jakos tego nie czuje moze po prostu nie zrozumialem... mi sie wydaje ze tu moznaby zastosowac liste struktur, ktrore przechowywałyby wspolrzedne - co o tym myslicie ? No i teraz gwozdz programu. Zalozmy ze mam juz wszystkie te rodzaje "sevenmina" - teraz uzytkownik wymysla sobie tablice 4 x 8 i teraz jak spradzac czy te wyszukane przeze mnie rodzaje danej figury (przechowywane jako jakies pary wspolrzednych) da sie ulozyc w nowej - innej tablicy ? Pomozcie! od kilku dni ten problem spedza mi sen z oczu :(
Tak jak pisałem kilka postów wyżej. Też rekurencja z nawrotami.