Student: Prowadzący: Michał W--------.@wp.pl dr inż. Piotr Wąsiewicz Podstawy Programowania (PRM) projekt Specyfikacja strukturalna (techniczna) Temat: Napisać grę Piętnastka Algorytm rozwiązania zadania: 1. Przesuwanie elementów i sprawdzenie. Głównym algorytmem w grze jest funkcja przesuwania elementów na wolne pole: w kierunku zarówno poziomym jak i pionowym. Jeśli nie jest możliwe przesunięcie elementu na wolne pole funkcja wypisuje komunikat o tym, że nie można wykonać tego ruchu, lub gdy zostanie wciśnięty nieprawidłowy klawisz, funkcja wypisuje komunikat o tym, żeby wcisnąć któryś z odpowiednich klawiszy. Gra rozgrywa się w pętli nieskończonej, do której program wchodzi po wybraniu opcji gry. Po każdorazowym wykonaniu się pętli program sprawdza warunki zakończenia i jeśli warunek jest spełniony to wypisuje komunikat o wygranej. Gra dodatkowo zlicza ruchy wykonane przez gracza. Struktury danych: Program posługuje się tablicą 4x4 jako odzwierciedleniem planszy. Na początku plansza jest wypełniona wartościami od 0 do 15. Liczby te są uporządkowane rosnąca od lewej do prawej, przy czym numeracja zaczyna się od 1 a 0 (pole puste) jest ostatnim elementem tablicy ([3] [3]). Komórka tablicy [x][y] odpowiada polu na ekranie i współrzędnych y=y+1,x=x+1.
Podział na funkcje: void szukacz(); Funkcja wyszukuje w tabeli pole o wartosci 0 i oblicza jego współrzędne for(j=0;j<4;j++) // przeszukuje wszystkie elementy tablicy // If (tab[i][j]==0) // jeśli znajduje element o wartości 0, i jego współrzędne to [i][j] // y=i; // to wartość i jest przypisywane do zmiennej y x=j; //a wartość j jest przypisywana do zmiennej x. // // void gra(); Funkcja rozpoczynajaca i wykonująca własciwa grę, poprzez wykonanie odpowiednich void ów w odpowiedniej kolejności przypisanie(); mieszacz(); n=0; while(sprawdzenie()) plansza(); szukacz(); wybor(); ; wzorzec(); getchar(); void gora(); Funkcja przesuwa element w gore na wolne pole (z wartoscia '0'). tab[y][x]=bufor; // zapisuje element o wsp. x y w pamięci podręcznej tab[y][x]=tab[y][x-1];// następnie przypisuje temu elementowi wartość tab[y][x-1]=bufor; // elementu znajdującego się poniżej, a temu n++; // elementowi przypisuje wartość przechowywaną w // buforze. n++ zwiększa o 1 liczbę ruchów // wykonanych przez gracza. analogicznie działają: void dol(); void lewa();void prawa();
void plansza(); Funkcja rysująca plansze do gry. printf("\t\t\t"); printf("\t\t\t"); for(j=0;j<4;j++) printf("* %2.d ",tab[i][j]); printf("*"); printf("\n\t\t\t\t\t\t\t Wykonano ruchow: %d \n\n",n); void przypisanie(); Funkcja przypisująca poczatkowe wartości komorkom tabeli for(j=0;j<4;j++) licznik++; tab[i][j]=licznik%16;
void wybor(); Funkcja przesuwajaca element na wolne pole, według wskazania gracza. Funkcja na początku pobiera znak podany przez gracza, nastepnie za pomocą swicth i if są wykonywane odpowiednie warunki. Np. jeśli gracz poda znak w to fukcja przesunie element w góre na miejsce wolnego pola, pod warunkiem że aktualna współrzędna y wolnego pola będzie różna od 3. W przypadku gdy y będzie równy 3 funkcja wyświetli komunikat: NIE MA ELEMENTU KTORY MOZNA PRZESUNAC NA WOLNE POLE!!! char c, c2; c=getchar(); c2 = getchar(); if (c2!= '\n' ) ungetc(c2, stdin); switch (c) case 'w':if(y!=3)gora();else printf("\t\t NIE MA ELEMENTU KTORY MOZNA PRZESUNAC NA WOLNE POLE!!! \n\n\n") ;break; case 'a':if(x!=3)lewa();else printf("\t\t NIE MA ELEMENTU KTORY MOZNA PRZESUNAC NA WOLNE POLE!!! \n\n\n");break; case 's':if(y!=0)dol();else printf("\t\t NIE MA ELEMENTU KTORY MOZNA PRZESUNAC NA WOLNE POLE!!! \n\n\n");break; case 'd':if(x!=0)prawa();else printf("\t\t NIE MA ELEMENTU KTORY MOZNA PRZESUNAC NA WOLNE POLE!!! \n\n\n");break; default: printf ("\n\n\t\t\t Musisz podac ktoras z liter : w,s,a,d!!!\n\n\n ");break; void mieszacz(); Funkcja mieszająca plansze int l; srand(time(0)); // for(l=0;l<1000;l++) // // funkcja losuje 1000 razy szukacz(); // switch(rand()%4) // cyfre od 0 do 3. Jeśli wylosowana liczba case 0:gora();break; // to 0 to element jest przesuwany w gore case 1:dol();break; // na puste pole. Analogicznie jest w case 2:lewa();break; // przypadku wylosowania 1,2 i 3. case 3:prawa();break; // default :break; //
void naglowek(); Funkcja rysując nagłówek powitania gry; oparta jest na zwykłych printfach printf ("\t\t\t -------------------------\n"); printf ("\t\t\t ----------------------- \n"); printf ("\t\t\t Gra Pietnastka \n"); printf ("\t\t\t \n"); printf ("\t\t\t Michal Wasniewski \n"); printf ("\t\t\t ----------------------- \n"); printf ("\t\t\t -------------------------\n\n\n"); printf ("\t\t\t\t 1 55555 \n"); printf ("\t\t\t\t 1 1 5 \n"); printf ("\t\t\t\t 1 1 5 \n"); printf ("\t\t\t\t 1 55555 \n"); printf ("\t\t\t\t 1 5 \n"); printf ("\t\t\t\t 1 5 \n"); printf ("\t\t\t\t 1 55555 \n\n\n"); int sprawdzenie(); Procedura sprawdzająca czy plansza do gry jest juz prawidłowo ułożona. Procedura przeszukuje każde pole tablicy i sprawdza czy jego wartość jest równa wartości odpowiadającej wzorcowemu ułożeniu planszy. Jeśli dany element znajduje się n właściwym miejscu procedura zwiększa sumę o 1. Po przeszukaniu wszystkich elementów funkcja sprawdza czy suma jest równa 16. Jeśli tak to wyświetla komunikat o wygranej, w przeciwnym wypadku pętla z grą jest wykonywana dalej. int suma; suma=0; for(j=0;j<4;j++) licznik++; if(tab[i][j]==licznik%16) suma++; if (suma==16) printf ("\n\n\n\t\t\t\ Gratulacje WYGRALES!!\n\n"); printf ("\t\tudalo ci sie ulozyc plansze w %d ruchach\n\n\n",n); return 0;
void menu(); Funkcja rysujaca i obslugujaca menu gry. Funkcja za pomocą printfów rysuje menu gry. Następnie sczytuje znak podany przez gracza. Jeśli jest to 1 funkcja przechodzi do void gra i rozpoczyna się właściwa gra. Jeśli jest to 2 funkcja wyświetla instrukcje gry i prawidłowo rozwiązaną plansze. Jeśli natomiast jest to 3 to gra zostaje zamknięta. W przypadku wciśnięcia innej cyfry lub litery menu jest rysowane ponownie. int a; printf ("\t\t\t Witam w grze logicznej Pietnastka\n\n\n"); do printf ("Wybierz co chcesz teraz zrobic\n"); printf ("1. Nowa gra\n"); printf ("2. Instrukcja gry\n"); printf ("3. Wyjscie\n"); scanf ("%d",&a); getchar(); if (a==1) printf("\n\n\t Przesuwanie elementow na wolne pole za pomoca w,s,a,d!\n\n\n "); gra(); if (a ==2) printf ("\n Oryginal zbudowany jest w ksztalcie kwadratu, wewnatrz ktorego miesci\n" "sie 15 przesuwnych segmentow.na segmentach nadrukowane sa kolejne liczby \n" "od 1 do 15.Jedno pole zawsze jest puste i mozna na nie przesunac sasiedni \n" "segment.1 musi znalezc sie w lewym gornym rogu, natomiast wolne pole w prawym\n" "dolnym rogu.steruje sie za pomoca klawiszy w,s,a,d.\n\n"); printf ("Tak wyglada prawidlowo rozwiazana plansza gry\n\n\n"); wzorzec(); getchar(); if (a==3) printf ("\t\t\t Zapraszam ponownie!!!"); while(a!=3);
void wzorzec(); Funkcja rysuje prawidłowo rozwiązaną plansze do gry-wzorzec. int o,p; for (o=0;o<4;o++) for (p=0;p<4;p++) licznik++; tab[o][p]=licznik%16; for(o=0;o<4;o++) printf("\t\t\t"); printf("\t\t\t"); for(p=0;p<4;p++) printf("* %2.d ",tab[o][p]); printf("*"); Literatura: Klasyka informatyki, Język Ansi C- Brian W. Kerninghan, Denis M. Ritchie.