P016 - Prosta gra logiczna - POLE MINOWE |
---|
Programy uruchomiono w środowisku Bloodshed Dev-C++ 4.9.9.2 |
Uwaga, program p016 wykorzystuje bibliotekę newconio, którą stworzyliśmy na wcześniejszych zajęciach koła. Do projektu należy dołączyć plik newconio.cpp oraz plik nagłówkowy newconio.h. Bez tych plików program nie uruchomi się.
// I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //-------------------------- // Koło informatyczne 2006/7 //-------------------------- // Program: P016-01 //-------------------------- #include "newconio.h" #include <iostream> using namespace std; const int MMAX = 300; // maksymalna liczba min const int PX = 80; // szerokość pola minowego const int PY = 49; // wysokość pola minowego char pole[PY][PX]; // pole minowe int sx,sy; // współrzędne sapera // Wyświetla ekran tytułowy gry //----------------------------- void ekran_tytulowy() { textattr(7); clrscr(); textcolor(15); center(10, _pl("KOŁO INFORMATYCZNE '2006")); textcolor(14); center(12, "I LO w Tarnowie"); textcolor(11); center(14, "P O L E M I N O W E"); textcolor(7); center(PY, _pl("--- Naciśnij dowolny klawisz ---")); while(!getch()) ; } // Generuje miny na polu minowym // oraz wyświetla planszę gry //------------------------------ void generuj_pole_minowe() { int i, j; // generujemy pole minowe for(i = 0; i < PX; i++) for(j = 0; j < PY; j++) pole[j][i] = ' '; for(i = 0; i < MMAX; i++) pole[1 + rand() % (PY - 2)][1 + rand() % (PX - 2)] = '*'; pole[1][78] = ' '; for(j = PY - 4; j < PY; j++) for(i = 1; i < 4; i++) pole[j][i] = ' '; // wyświetlamy planszę gry textattr(0x20); clrscr(); frame(FRAME_SOLID, 8, 0, 0, PX - 1, PY - 1); fillrectattr(0x70, 0, PY, PX - 1, PY); putxy('#', 0x29, PX - 2, 1); // wyjście z pola minowego } // Główna pętla zdarzeń gry //------------------------- void szukaj_min() { int i, j; char key; bool t; sx = 1; sy = PY - 2; // pozycja sapera while(true) { putxy('O', 0x2f, sx, sy); t = false; for(i = sx - 1; i <= sx + 1; i++) for(j = sy - 1; j <= sy + 1; j++) t = t || (pole[j][i] == '*'); if(t) { textattr(0x7c); center(PY, "*** UWAGA, MINY ***"); } else { textattr(0x71); center(PY, " --- PUSTO --- "); } if(kbhit()) { putxy(177, 0x20, sx, sy); while(!(key = getch())) ; switch(key) { case 72 : // strzałka w górę if(getchxy(sx, sy - 1) != char(219)) sy--; break; case 80 : // strzałka w dół if(getchxy(sx, sy + 1) != char(219)) sy++; break; case 75 : // strzałka w lewo if(getchxy(sx - 1, sy) != char(219)) sx--; break; case 77 : // strzałka w prawo if(getchxy(sx + 1, sy) != char(219)) sx++; break; } } if(pole[sy][sx] == '*') { for(j = 1; j < PY; j++) for(i = 1; i < PX; i++) if(pole[j][i] == '*') putxy('*', 0x24, i, j); putxy('+', 0x2f, sx, sy); textattr(0x80); center(PY - 1, _pl("+++ POLEGŁ NA POLU CHWAŁY +++")); break; } if(getchxy(sx, sy) == '#') { for(j = 1; j < PY; j++) for(i = 1; i < PX; i++) if(pole[j][i] == '*') putxy('*', 0x20, i, j); putxy('X', 0xe1, sx, sy); textattr(0x8f); center(PY - 1, _pl("*** WITAJ W KLUBIE SAPERÓW ***")); break; } } } // Funkcja sprawdza, czy gracz chce kontynuować rozgrywkę //------------------------------------------------------- bool dalsza_gra() { char key; textattr(0x70); center(PY, _pl("Jeśli chcesz zagrać jeszcze raz, naciśnij klawisz [T].")); while(!(key = getch())) ; return (key == 't') || (key == 'T'); } // Program główny //--------------- main() { _cinit(); srand((unsigned)time(NULL)); fullscreen(true); cursoroff(); ekran_tytulowy(); do { generuj_pole_minowe(); szukaj_min(); } while(dalsza_gra()); cursoron(); fullscreen(false); } |
Widok okienka konsoli
w uruchomionym programie
Gra Pole Minowe pochodzi z wczesnych lat 80-tych XX wieku. Zasady są bardzo proste. Jesteś saperem, który musi wytyczyć ścieżkę poprzez pole minowe. Zaczynasz w lewym dolnym rogu planszy i masz dojść do prawego górnego rogu, w którym widnieje znak '#'. Jeśli ci się to uda, wygrywasz grę. Jednakże problemem są miny rozmieszczone w sposób losowy po całym polu gry. Nie widzisz ich, jednakże posiadasz wykrywacz, który informuje cię, czy w polach przyległych bezpośrednio do twojej pozycji znajduje się mina lub miny. Wtedy na pasku wiadomości u spodu ekranu pojawia się odpowiedni napis. Jeśli jesteś nieuważny i wejdziesz na minę, gra się kończy jak na powyższym obrazku.
Gra jest bardzo prosta. Pole minowe zapamiętane jest w 2-wymiarowej tablicy pole[][]. Tablica ta dokładnie odwzorowuje planszę gry. Jeśli na ekranie gracz znajduje się na pozycji x,y, to w tablicy jest to pozycja pole[y[[x] - współrzędne są odwrotnie, ponieważ pierwszy wymiar oznacza ilość wierszy, a drugi wymiar ilość kolumn.
Główna pętla gry jest następująca:
void szukaj_min() { int i, j; char key; bool t; |
Na początku funkcji deklarujemy kilka zmiennych: i,j - liczniki pętli key - naciśnięty klawisz t - używane do testów na obecność min |
sx = 1; sy = PY - 2; // pozycja sapera |
Zmienne sx i sy przechowują pozycję sapera na planszy. Inicjujemy je na lewy dolny róg. |
while(true) { |
Rozpoczynamy pętlę zdarzeń gry. Jest to pętla nieskończona, którą przerwiemy w przypadku osiągnięcia prawego górnego narożnika pola gry lub wejścia na minę. |
putxy('O', 0x2f, sx, sy); |
Umieszczamy na planszy sapera. |
t = false; for(i = sx - 1; i <= sx + 1; i++) for(j = sy - 1; j <= sy + 1; j++) t = t || (pole[j][i] == '*'); |
Sprawdzamy, czy w polach otaczających pozycję sapera są jakieś miny. Jeśli tak, to zmienna t przyjmie wartość true. |
if(t) { textattr(0x7c); center(PY, "*** UWAGA, MINY ***"); } else { textattr(0x71); center(PY, " --- PUSTO --- "); } |
Jeśli wykryto miny, wypisujemy ostrzeżenie. W przypadku braku min wypisujemy tekst uspokajający. |
if(kbhit()) { putxy(177, 0x20, sx, sy); while(!(key = getch())) ; switch(key) { case 72 : // strzałka w górę if(getchxy(sx, sy - 1) != char(219)) sy--; break; case 80 : // strzałka w dół if(getchxy(sx, sy + 1) != char(219)) sy++; break; case 75 : // strzałka w lewo if(getchxy(sx - 1, sy) != char(219)) sx--; break; case 77 : // strzałka w prawo if(getchxy(sx + 1, sy) != char(219)) sx++; break; } } |
Jeśli naciśnięto klawisz, znak sapera zastępujemy znakiem ścieżki.
Odczytujemy kod klawisza do key. Reagujemy tylko na klawisze kursora
zmieniając odpowiednio współrzędne sapera, jeśli jest to możliwe
(np. gracz próbuje wejść na bandę). Uwaga: instrukcja break służy tutaj do wyjścia z instrukcji switch(). Nie przerywa ona działania pętli zdarzeń. |
if(pole[sy][sx] == '*') { for(j = 1; j < PY; j++) for(i = 1; i < PX; i++) if(pole[j][i] == '*') putxy('*', 0x24, i, j); putxy('+', 0x2f, sx, sy); textattr(0x80); center(PY - 1, _pl("+++ POLEGŁ NA POLU CHWAŁY +++")); break; } |
Po zmianie współrzędnych sapera (czyli po wykonaniu ruchu gracza) musimy
sprawdzić, czy saper nie wszedł na minę. Jeśli tak, wyświetlamy
wszystkie miny w kolorze czerwonym oraz tekst kondolencyjny. Pętlę
zdarzeń przerywamy. Przerwanie pętli zdarzeń skutkuje wyjściem z funkcji szukaj_min(), co kończy daną rozgrywkę. |
if(getchxy(sx, sy) == '#') { for(j = 1; j < PY; j++) for(i = 1; i < PX; i++) if(pole[j][i] == '*') putxy('*', 0x20, i, j); putxy('X', 0xe1, sx, sy); textattr(0x8f); center(PY - 1, _pl("*** WITAJ W KLUBIE SAPERÓW ***")); break; } } } |
Sprawdzamy, czy saper osiągnął punkt końcowy gry. Jeśli tak, również
wyświetlamy miny w kolorze czarnym. W miejsce znaku '#' wpisujemy znak
'X' oraz na pasku wiadomości wyświetlamy tekst gratulacyjny. Pętlę
zdarzeń przerywamy. Przerwanie pętli zdarzeń skutkuje wyjściem z funkcji szukaj_min(), co kończy daną rozgrywkę. |
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe