/* * Míny * * Vytvoril Juraj Oravec ako semestrálnu prácu. * */ /* * Vloženie potrebných knižníc / hlavičkových súborov */ #include #include #include #include #include #include #ifndef NAZOV # define NAZOV "Miny 0.7" #endif #ifndef COLOR_DEFAULT # define COLOR_DEFAULT -1 #endif /* definýcia štruktúry a špeciálneho typu pre konfiguračné hodnoty */ typedef struct config_min { short bulanek; /* vykresliť bulánka alebo len smajlíka */ short bulanek_usmev; /* spôso vykreslenia smutného smajlíka */ short miny; /* počet mín v hracom poli (max 99) */ short cisty_start; /* začať na prázdnom alebo akomkoľvek poli */ short nulovy_start; /* začat na nule, funguje s voľbou cisty_start */ short info_poloha; /* zobrazovať alebo nezobrazovať aktuálnu polohu kurzoru */ short vyvojar; /* sprístupní vývojárske funkcie */ short vycentruj; /* vycentruje hru na obrazovke / nechá ju na ľavej strane hore */ } m_config; /* * Definovania globálnych premenných */ int row, col; int hra = 1; int **min_pole; int **uhadol; int **pole_hodnot; m_config miny_config; /* * Definovanie použitúch funkcií */ WINDOW *create_newwin (int height, int width, int starty, int startx); void destroy_win (WINDOW *local_win); void vyber_min (WINDOW *local_win, int width, int height, int x, int y, int old_x, int old_y); int mini_rozhadz (int min, int sirka, int vyska, int min_max); int min_okolo (int poloha_x, int poloha_y, int width, int height); void vyber_dopln (int poloha_x, int poloha_y, int width, int height, WINDOW *my_win); int str_to_int(char *s); char * trim (char * s); void config_init (void); void config_parse (void); void mini_zobraz (WINDOW *local_win, int width, int height); void smajlik_init (WINDOW *smyle_win); void smajlik (WINDOW *local_win, int ako); void restart_prepare (WINDOW *my_win, WINDOW *info_win, WINDOW *smyle_win, int sirka, int vyska); void miny_vypis (WINDOW *local_win, int x, int y, int bg); int dokoncil (int sirka, int vyska); void vypis_oznacene (WINDOW *local_win, int oznacil, int min); int pridel_pamet (int sirka, int vyska); void uvolni_pamet (int sirka); /* * Hlavná funkcia programu */ int main (void) { /* * Defimovanie lokálnych premenných funkcie */ WINDOW *my_win, *info_win, *smyle_win; int startx, starty, w_width, w_height; int width, height; int poloha_x, poloha_y; int old_x, old_y; int oznacil; short zacal; int min; int ch; char *dopln; int i, j, u, z; //long start_time, end_time; /* Inicializovanie/zapnutie curses módu */ initscr(); /* inicializácie konfigurácie */ config_init(); /* Kontrola či terminál podporuje farby */ if (has_colors() == FALSE) { endwin(); printf("Vas terminal nepodporuje farby!\n"); exit(1); } /* * Aktivácia pomocných funkcií pre curses mód * * raw - vypnutie bufferovania riadkov (disable line buffering) * * noecho - po stlačení kláves sa nebudú vypisovať * curs_set - vypnutie kurzoru (schovanie) * start_color - zapnutie podpory farieb * keypad - aktivácia F kláves (F1, F2...) */ raw(); cbreak(); noecho(); //nodelay(stdscr, true); curs_set(0); use_default_colors(); start_color(); keypad(stdscr, TRUE); /* Inicializovanie generátoru náhodných čísel */ srand(time(0)); /* * Inicializovanie párov farieb * * 0 - základný systémový/všeobecný * 1 - zvýraznenie vybraného políčka * 2 - farba neuhádnutej míny * 3 - farba uhádnutej míny * 4 - farba zle označenej míny * * 5 - farba čísla 1 * 6 - farba čísla 2 * 7 - farba čísla 3 * 8 - farba čísla 4 * 9 - farba čísla 5 * 10 - farba čísla 6 * 11 - farba čísla 7 * 12 - farba čísla 8 */ init_pair(1, COLOR_WHITE, COLOR_RED); init_pair(2, COLOR_YELLOW, COLOR_DEFAULT); init_pair(3, COLOR_GREEN, COLOR_DEFAULT); init_pair(4, COLOR_RED, COLOR_DEFAULT); init_pair(5, COLOR_BLUE, COLOR_DEFAULT); init_pair(6, COLOR_GREEN, COLOR_DEFAULT); init_pair(7, COLOR_RED, COLOR_DEFAULT); init_pair(8, COLOR_CYAN, COLOR_DEFAULT); init_pair(9, COLOR_MAGENTA, COLOR_DEFAULT); init_pair(10, COLOR_YELLOW, COLOR_DEFAULT); init_pair(11, COLOR_BLACK, COLOR_DEFAULT); init_pair(12, COLOR_WHITE, COLOR_DEFAULT); /* definícia menovky restart, sem sa presunieme pomocou goto pre reštart hry */ restart: /* Zistí rozmery terminálu */ getmaxyx(stdscr, row, col); /* Priradenie hodnôt premenným */ min = miny_config.miny; width = 30; height = 16; w_height = height + 2; w_width = width + 2; oznacil = 0; poloha_x = 1; poloha_y = 1; zacal = 0; //start_time = time(NULL); //end_time = 0; /* Pridelenie pamate podľa konfigurácie */ pridel_pamet(width, height); /* Vynulovanie hodnôt v poliach... */ for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { min_pole[i][j] = 0; uhadol[i][j] = 0; pole_hodnot[i][j] = 0; } } /* vycentruje hru na obrazovke */ if (miny_config.vycentruj == 1) { starty = (row - w_height) / 2; startx = (col - (w_width * 2 + 2)) / 2; } else { /* položí na ľavú stranu a mierne odsadí od okrajov */ starty = 1; startx = 2; } /* Vypísať na reálnu obrazovku (Print to real screen) */ refresh(); printw("Copyright © 2013 Juraj Oravec\n"); /* Vytvorenie curses "okien" */ my_win = create_newwin(w_height, w_width, starty, startx); info_win = create_newwin(w_height, w_width, starty, startx + 34); smyle_win = create_newwin(6, 10, starty + 11, startx + 34 + 12); /* "odstránenie" rámiku okolo okna so smajlíkom */ wborder(smyle_win, ' ', ' ', ' ',' ',' ',' ',' ',' '); wrefresh(smyle_win); /* Výpis do informačného okna */ mvwprintw(info_win, 1, (w_width - strlen(NAZOV)) / 2, NAZOV); mvwprintw(info_win, 3, 2, "Pocet min: %d", min); wattron(info_win, A_BOLD); mvwprintw(info_win, 3, 25, " 0/%d", min); wattroff(info_win, A_BOLD); mvwprintw(info_win, 4, 2, "Minove pole: %d x %d", width, height); /* vypísať polohu kurzoru len ak je to povolené v konfigurácii */ if (miny_config.info_poloha == 1) mvwprintw(info_win, 5, 2, "Poloha kurzoru: X: %d, Y: %d", poloha_x, poloha_y); /* Refresh/Obnova informačného okna, aby sa zobrazilo čo sme vypoísali */ wrefresh(info_win); /* Zobrazenie smajlíka */ smajlik_init(smyle_win); /* * vyber_min -> Základná poloha kurzoru v ľavom hornom rohu * mini_rozhadz -> Náhodne rozmiestni míny po hracom poli */ vyber_min(my_win, width, height, poloha_x, poloha_y, 0, 0); mini_rozhadz(0, width, height, min); /* * Nekonečný cyklus pre zisťovanie stlačenia kláves * Program sa ukonćí funkciou exit() po stlačení 'q' */ while ( ( ch = getch() ) ) { /* Uloženie starej polohy kurzoru pre ďalśie spracovanie */ old_x = poloha_x; old_y = poloha_y; /* * switch/prepínač pre "kontrolu" stlačených kláves * a podľa toho vykoná nejakú akciu... */ switch (ch) { /* * Stlačenie šípky vľavo, * nasleduje posun kurzoru vľavo, ak je to možné */ case KEY_LEFT: if (hra == 1) { if (poloha_x > 1) poloha_x--; } break; /* * Stlačenie šípky vpravo, * nasleduje posun kurzoru vpravo, ak je to možné */ case KEY_RIGHT: if (hra == 1) { if (poloha_x < width) poloha_x++; } break; /* * Stlačenie šípky hore, * nasleduje posun kurzoru hore, ak je to možné */ case KEY_UP: if (hra == 1) { if (poloha_y > 1) poloha_y--; } break; /* * Stlačenie šípky dole, * nasleduje posun kurzoru dole, ak je to možné */ case KEY_DOWN: if (hra == 1) { if (poloha_y < height) poloha_y++; } break; case 'a': /* * Nástroj pre programátora, testera... * označí všetky prázdne polia v hre */ if (miny_config.vyvojar == 1) { for (u = 0; u < width; u++) for (z = 0; z < height; z++) { if (min_pole[u][z] == 0) vyber_dopln((u + 1), (z + 1), width, height, my_win); } wrefresh(my_win); } break; /* Označenie míny */ case 'm': if (hra == 1) { /* Kontrola neoznaćeného políčka */ if (uhadol[(poloha_x - 1)][(poloha_y - 1)] != 1 && uhadol[(poloha_x - 1)][(poloha_y - 1)] != 2) { /* Vypísanie označenia míny, refresh hracieho poľa, uloženie označenia */ mvwprintw(my_win, poloha_y, poloha_x, "*"); wrefresh(my_win); uhadol[(poloha_x - 1)][(poloha_y - 1)] = 2; oznacil++; vypis_oznacene(info_win, oznacil, min); } else if (uhadol[(poloha_x - 1)][(poloha_y - 1)] == 2) { /* Ak je mína už označená tak bude označenie zrušené */ mvwprintw(my_win, poloha_y, poloha_x, " "); wrefresh(my_win); uhadol[(poloha_x - 1)][(poloha_y - 1)] = 0; oznacil--; vypis_oznacene(info_win, oznacil, min); } } break; /* Ukončenie programu s kódom 0 - správne ukončenie */ case 'q': endwin(); exit(0); break; /* reštartovanie hry */ case 'r': if (miny_config.vyvojar == 1) { /* príprava na reštart... */ restart_prepare (my_win, info_win, smyle_win, width, height); /* prestavenie identifikátoru stavu hry na play/hrať/1/OK... */ hra = 1; /* preskočenie na menovku restart */ goto restart; } break; /* Medzera - Výber políčka na hracom poli */ case ' ': if (hra == 1) { /* * Pokiaľ je aktívna voľba cisty_start tak sa bude mínové pole generovař pokiaľ * na daných súradniciach bude mína, keď nebude, tak prestane. */ if (miny_config.cisty_start == 1 && zacal == 0) { if (miny_config.nulovy_start == 1) { while (TRUE) { for (u = 0; u < width; u++) { for (z = 0; z < height; z++) { /* Vymazanie mín z hracieho poľa */ min_pole[u][z] = 0; } } mini_rozhadz(0, width, height, min); if (min_okolo(poloha_x, poloha_y, width, height) == 0 && min_pole[(poloha_x - 1)][(poloha_y - 1)] == 0) break; } } else if (min_pole[(poloha_x - 1)][(poloha_y - 1)] == 1) { while (TRUE) { for (u = 0; u < width; u++) { for (z = 0; z < height; z++) { /* Vymazanie mín z hracieho poľa */ min_pole[u][z] = 0; } } mini_rozhadz(0, width, height, min); if (min_pole[(poloha_x - 1)][(poloha_y - 1)] == 0) break; } } zacal = 1; } /* Ak trafil na mínu */ if (min_pole[(poloha_x - 1)][(poloha_y - 1)] == 1) { if (uhadol[(poloha_x - 1)][(poloha_y - 1)] == 0) { /* zobrazí všetky míny, vypíše zásah */ mini_zobraz(my_win, width, height); /* Zobrazí smutného smajlíka */ smajlik (smyle_win, 2); /* zastaví hru, teda zmení stav na koniec/stop/KO/... */ hra = 0; } } else { /* * Ak trafil na prázdne pole * vypíše koľko mín sa nachádza v okolí toho poľa */ vyber_dopln(poloha_x, poloha_y, width, height, my_win); /* Refresh okien */ /*wrefresh(info_win);*/ wrefresh(my_win); /* kontrola dokončenia hry */ if (dokoncil(width, height) == 1) { /* ak boli označené všetky "prázdne polia" vypíše všetky míny na zeleno, správne vyplnenie.. */ mini_zobraz(my_win, width, height); oznacil = min; vypis_oznacene(info_win, oznacil, min); //end_time = time(NULL); hra = 0; } } } else if (hra == 0) { /* príprava na reštart... */ restart_prepare (my_win, info_win, smyle_win, width, height); /* prestavenie identifikátoru stavu hry na play/hrať/1/OK... */ hra = 1; zacal = 0; /* preskočenie na menovku restart */ goto restart; } break; } /* Posunutie kurzora, ak sa zmenila jeho poloha */ if (poloha_x != old_x || poloha_y != old_y) vyber_min(my_win, width, height, poloha_x, poloha_y, old_x, old_y); /* pokiaľ je aktívne vypisovanie polohy... */ if (miny_config.info_poloha == 1) { /* Doplnenie prázdneho miesta za súradnice kurzoru */ if (poloha_x < 10 && poloha_y < 10) dopln = " "; else if (poloha_x < 10 || poloha_y < 10) dopln = " "; /* Výpis polohy kurzoru */ mvwprintw(info_win, 5, 2, "Poloha kurzoru: X: %d, Y: %d%s", poloha_x, poloha_y, dopln); } /* refreš info okna */ wrefresh(info_win); } /* Ukončenie curses modu */ endwin(); /* Ukončenie programu */ return 0; } /* * Vytvorenie okna, podľa zadanej výšky, šírky a polohy y,x * Tieź vytvorí jednoduchý rámik okolo okna * * * Parametre: * height - výška vytvoreného okna * width - šírka vytvoreného okna * starty - číslo riadku na ktorom začať "kresliť" * startx - číslo stĺpca na ktorom začať "kresliť" */ WINDOW *create_newwin (int height, int width, int starty, int startx) { /* pomocná premenná */ WINDOW *local_win; /* vytvorenie okna */ local_win = newwin(height, width, starty, startx); /* Zobrazí/Vykreslí jednoduchý rámik */ box(local_win, 0 , 0); wrefresh(local_win); return local_win; } /* * Zrušenie vytvoreného okna a zrušenie jeho rámiku * * * Parametre: * localwin - identifikátor okna */ void destroy_win(WINDOW *local_win) { /*zruší rámik, zmení ho na medzery, prázdne znaky*/ wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' '); /* obnový okno */ wrefresh(local_win); /* vymaže okno */ delwin(local_win); } /* * Posun kurzoru po hracom poli * * * Parametre: * local_win - identifikátor okna * width - šírka hracieho poľa * výška - výška hracieho poľa * x - číslo stĺpca novej polohy kurzoru * y - číslo riadku novej polohy kurzoru * old_x - číslo stĺpca starej polohy kurzoru * old_y - číslo riadku starej polohy kurzoru */ void vyber_min(WINDOW *local_win, int width, int height, int x, int y, int old_x, int old_y) { /* použitie daného farebného páru v danom okne */ wattron(local_win, COLOR_PAIR(1)); /* pokiaľ je už dané pole "uhádnuté" vypíše ćísto */ if (uhadol[(x - 1)][(y - 1)] == 1) miny_vypis(local_win, x, y, 0); /*mvwprintw(local_win, y, x, "%d", pole_hodnot[(x - 1)][(y - 1)]);*/ /* alebo označenie míny */ else if (uhadol[(x - 1)][(y - 1)] == 2) mvwprintw(local_win, y, x, "*"); /* a ak nie je tak vypíše prázdny znak */ else mvwprintw(local_win, y, x, "%s", " "); wattroff(local_win, COLOR_PAIR(1)); /* ukončenie použitia farebného páru */ if (old_x != 0 && old_y != 0) { if (uhadol[(old_x - 1)][(old_y - 1)] == 1) miny_vypis(local_win, old_x, old_y, 1); /*mvwprintw(local_win, old_y, old_x, "%d", pole_hodnot[(old_x - 1)][(old_y - 1)]);*/ else { wattron(local_win, COLOR_PAIR(0)); if (uhadol[(old_x - 1)][(old_y - 1)] == 2) mvwprintw(local_win, old_y, old_x, "*"); else mvwprintw(local_win, old_y, old_x, "%s", " "); wattroff(local_win, COLOR_PAIR(0)); } } /* Obnovenie hracieho poľa */ wrefresh(local_win); } /* * Rozhádzanie mín po hracom poli * * * Parametre: * min - počet mín, ktoré sú už v hracom poli * sirka - šírka hracieho poľa * vyska - výška hracieho poľa * min_max - konečné/maximálny počet mín */ int mini_rozhadz (int min, int sirka, int vyska, int min_max) { /* Definovanie pomocných premenných */ int i, j; int x, y; /* * Cyklicky prejde "všetky prvky poľa" * tedda zopakuje sa toľko-krát koľko je v hracom poli políčok */ for (i = 0; i < sirka; i++) { for (j = 0; j < vyska; j++) { /* Náhodné x, y */ x = rand() % sirka; y = rand() % vyska; /* * Zapísanie míny do mínového poľa * Pripočíta 1 k pridaným mínam */ if (min_pole[x][y] != 1) { min_pole[x][y] = 1; min++; } /* Pokiaľ je už dosť mín ukonči funkciu */ if (min == min_max) return 1; } } /* Pokiaĺ sme pridali málo mín zopakuje funkciu */ if (min < min_max) { mini_rozhadz(min, sirka, vyska, min_max); } /* Vráti 2 pre mini debugging (pre istotu) */ return 2; } /* * Funkcie vráti počet mín ktoré sa nachádzajú okolo daného bodu / políčka... * * * Parametre: * poloha_x - poloha kurzoru v stĺpci hracieho okna * poloha_y - poloha kurzoru v riadku hracieho okna * width - šírka hracieho poľa * height - výška hracieho poľa */ int min_okolo (int poloha_x, int poloha_y, int width, int height) { /* Definovanie lokálnych premenných */ int pomocka[4]; int min = 0; /* Priradenie/vypočítanie pomocných hodnôt */ pomocka[0] = poloha_x - 2; pomocka[1] = poloha_y - 2; pomocka[2] = poloha_y; pomocka[3] = poloha_x; /* Ľavý stĺpec okolo bodu */ if (pomocka[0] >= 0) { /* Prvý riadok */ if (pomocka[1] >= 0) min += min_pole[(poloha_x - 2)][(poloha_y - 2)] == 1 ? 1 : 0; /* Posledný riadok */ if (pomocka[2] < height) min += min_pole[(poloha_x - 2)][(poloha_y)] == 1 ? 1 : 0; /* Stredný riadok */ min += min_pole[(poloha_x - 2)][(poloha_y - 1)] == 1 ? 1 : 0; } /* Vrchný riadok okolo bodu (čo ostalo) */ if (pomocka[1] >= 0) { /* Posledný stĺpec */ if (pomocka[3] < width) min += min_pole[(poloha_x)][(poloha_y - 2)] == 1 ? 1 : 0; /* Stredný stĺpec */ min += min_pole[(poloha_x - 1)][(poloha_y - 2)] == 1 ? 1 : 0; } /* Pravý stĺpec stredný riadok */ if (pomocka[3] < width) min += min_pole[(poloha_x)][(poloha_y - 1)] == 1 ? 1 : 0; /* Pravý dolný roh... */ if (pomocka[2] < height && pomocka[3] < width) min += min_pole[(poloha_x)][(poloha_y)] == 1 ? 1 : 0; /* Spodný riadok stredný stĺpec */ if(pomocka[2] < height) min += min_pole[(poloha_x - 1)][(poloha_y)] == 1 ? 1 : 0; return min; } /* * Automatické doplnenie vybratých políčok pokiaľ sa v okolí nenachádzajú míny * * * Parametre: * poloha_x - súradnica stĺpca kurzoru v hracom poli * poloha_y - súradnica riadku kurzoru v hracom poli * width - šírka hracieho poľa * height - výška hracieho poľa * my_win - identifikátor okna hracieho poľa */ void vyber_dopln (int poloha_x, int poloha_y, int width, int height, WINDOW *my_win) { /* Definovanie lokálnych premenných */ int pomocka[4]; int min_o = 0; /* pokiaľ je políčko na doplnenie nevybraté tak ho doplní */ if (uhadol[(poloha_x - 1)][(poloha_y - 1)] != 1 && uhadol[(poloha_x - 1)][(poloha_y - 1)] != 2) { uhadol[(poloha_x - 1)][(poloha_y - 1)] = 1; /* Zistenie počtu mín okolo poľa */ min_o = min_okolo(poloha_x, poloha_y, width, height); /* Zapísanie počtu mín do poľa hodnôt */ pole_hodnot[(poloha_x - 1)][(poloha_y - 1)] = min_o; /* Vypísanie počtu mín do hracieho poľa */ miny_vypis(my_win, poloha_x, poloha_y, 1); /*mvwprintw(my_win, poloha_y, poloha_x, "%d", min_o);*/ /*mvwprintw(info_win, 8, 2, "Cisto");*/ /* * Pokiaľ sa v okolí nenachádajú míny tak doplní * tak vyplní polia okolo až kým nenarazí na míny... */ if (min_o == 0) { /* pomocné premenné */ pomocka[0] = poloha_x - 1; pomocka[1] = poloha_y - 1; pomocka[2] = poloha_y + 1; pomocka[3] = poloha_x + 1; /* Kontrola počtu mín v prvom riadku */ if (pomocka[0] > 0) { /* prvý stĺpec */ if (pomocka[1] > 0) vyber_dopln((poloha_x - 1), (poloha_y - 1), width, height, my_win); /* druhý stĺpec */ vyber_dopln((poloha_x - 1), (poloha_y), width, height, my_win); /* tretí stĺpec */ if (pomocka[2] <= height) vyber_dopln((poloha_x - 1), (poloha_y + 1), width, height, my_win); } /* v treťom riadku */ if (pomocka[3] <= width) { /* prvý stĺpec */ if (pomocka[1] > 0) vyber_dopln((poloha_x + 1), (poloha_y - 1), width, height, my_win); /* druhý stĺpec */ vyber_dopln((poloha_x + 1), (poloha_y), width, height, my_win); /* tretí stĺpec*/ if (pomocka[2] <= height) vyber_dopln((poloha_x + 1), (poloha_y + 1), width, height, my_win); } /* v druhom riadku */ /* prvý stĺpec */ if (pomocka[1] > 0) vyber_dopln((poloha_x), (poloha_y - 1), width, height, my_win); /* tretí stĺpec */ if (pomocka[2] <= height) vyber_dopln((poloha_x), (poloha_y + 1), width, height, my_win); } } } /* * Prevod textu na číslo * Funkcia predpokladá že v reťazci sa nachádzajú len znaky čísel (číslice) * ak sa v reťazci vyskytnú aj iné znaky funkcia pre istotu vráti len 0 * * * Parametre: * s - textový reťazec číselných znakov */ int str_to_int(char *s) { /* Definícia lokálnych premenných */ int pocet = strlen(s); int tmp[pocet]; int v = 0; int i; /* cyklicky prejde všetky znaky reťazca */ for (i = 0; i < pocet; i++) { /* ak je daný znak číslo prehodí ho na číslo podľa ostávajúcich znakov */ if(s[i] >= '0' && s[i] <= '9') { tmp[i] = (s[i] - '0') * pow(10, (pocet - (i + 1))); v += tmp[i]; } else return 0; } return v; } /* * Odstránenie medzier na začiatku a na konci reťazca * * * Parametra: * s - textový reťazec */ char * trim (char * s) { /* Inicializácia... */ char *s1 = s, *s2 = &s[strlen (s) - 1]; /* Vyčistenie pravej strany */ while ( (isspace (*s2)) && (s2 >= s1) ) s2--; /* posledný znak sa vynuluje */ *(s2+1) = '\0'; /* Vyčistenie ľavej strany */ while ( (isspace (*s1)) && (s1 < s2) ) s1++; /* Skopíruje výsledný reťazec */ strcpy (s, s1); return s; } /* * Inicializácia základnej konfigurácie * * po inicializácií sa zavolá funkcia config_parse(), ktorá načíta konfiguráciu zo súboru * * bližšie informácie o hodnotách sú uvedené vo funkcii config_parse(); */ void config_init (void) { /* * Priradenie základných hodnôt */ miny_config.bulanek = 1; miny_config.bulanek_usmev = 1; miny_config.miny = 99; miny_config.cisty_start = 0; miny_config.nulovy_start = 0; miny_config.info_poloha = 0; miny_config.vyvojar = 0; miny_config.vycentruj = 1; /* načítanie dát z konfiguračného súboru */ config_parse (); } /* * Načítanie dát z konfiguračného súboru, ak existuje */ void config_parse (void) { /* Definovanie lokálnych premenných */ char *s, buff[256]; int maxlen = 50; FILE *fp; char name[maxlen], value[maxlen]; /* Otvorenie súboru config len na čítanie */ fp = fopen("config", "r"); /* pokiaľ sa súbor nepodarilo otvoriť ukončí funkciu */ if (fp == NULL) return; /* Postupne číta súbor po riadkoch */ while ((s = fgets(buff, sizeof buff, fp)) != NULL) { /* Ak je riadok prázdny alebo komentovaný (začína na znak #) preskočí riadok */ if (buff[0] == '\n' || buff[0] == '#') continue; /* * rozdelí textový reťazec po znak "=" z premennej buff a priradí ho premennej s */ s = strtok(buff, "="); /* ak sa znak "=" v premennej buff nevyskytuje, preskočí sa na ďalší riadok */ if (s == NULL) continue; /* skopítuje reťazec do premennej name */ else strncpy(name, s, maxlen); /* priradí premennej s reťazec po znaku "=" z premennej buff */ s = strtok(NULL, "="); /* ak sa znak "=" v premennej buff nevyskytuje, preskočí sa na ďalší riadok */ if (s == NULL) continue; /* skopítuje reťazec do premennej value */ else strncpy(value, s, maxlen); /* odstráni medzery z názvu a hodnoty (premenné name, value) */ trim(name); trim(value); /* * porovnávanie názvu parametrov s platnými hodnotami/názvamy */ if (strcmp(name, "bulanek") == 0) { /* * 1 - vykresliť bulánka * 0 - vykresliť len smajlíka * * v prípade inej hodnoty sa použije preddefinovaná voľba */ if (strcmp(value, "1") == 0) { miny_config.bulanek = 1; } else if (strcmp(value, "0") == 0) { miny_config.bulanek = 0; } } else if (strcmp(name, "bulanek_usmev") == 0) { /* * bulanek_usmev = 1 * * 1 : zobrazí sa špecialny znak, vyzerá krajšie ale nemusí byť 100% podporované * 0 : vykreslí sa klasické podtržítko, funguje to všade ale vyzerá to trochu horšie... */ if (strcmp(value, "1") == 0) { miny_config.bulanek_usmev = 1; } else if (strcmp(value, "0") == 0) { miny_config.bulanek_usmev = 0; } } else if (strcmp(name, "miny") == 0) { /* * nimy = 99 * * priradí zadanaé číslo ako počet mín v hracom poli */ if (str_to_int(value) > 0 && str_to_int(value) <= 99) miny_config.miny = str_to_int(value); } else if (strcmp(name, "cisty_start") == 0) { /* * 1 - čistý štart aktývny (prvé pole nebude mína) * 0 - prvá bole bude akékoľvek... * * v prípade inej hodnoty sa použije preddefinovaná voľba */ if (strcmp(value, "1") == 0) { miny_config.cisty_start = 1; } else if (strcmp(value, "0") == 0) { miny_config.cisty_start = 0; } } else if (strcmp(name, "nulovy_start") == 0) { /* * 1 - čistý štart aktývny (prvé pole nebude mína) * 0 - prvá bole bude akékoľvek... * * v prípade inej hodnoty sa použije preddefinovaná voľba */ if (strcmp(value, "1") == 0) { miny_config.nulovy_start = 1; } else if (strcmp(value, "0") == 0) { miny_config.nulovy_start = 0; } } else if (strcmp(name, "info_poloha") == 0) { /* * 1 - súradnice polohy sa zobrazia * 0 - súradnice sa nezobrazia * * v prípade inej hodnoty sa použije preddefinovaná voľba */ if (strcmp(value, "1") == 0) { miny_config.info_poloha = 1; } else if (strcmp(value, "0") == 0) { miny_config.info_poloha = 0; } } else if (strcmp(name, "vyvojar") == 0) { /* * 1 - vývojárske nástroje sú aktívne * 0 - normálna hra, bez vývojárskych možností... * * v prípade inej hodnoty sa použije preddefinovaná voľba */ if (strcmp(value, "1") == 0) { miny_config.vyvojar = 1; } else if (strcmp(value, "0") == 0) { miny_config.vyvojar = 0; } } else if (strcmp(name, "vycentruj") == 0) { /* * 1 - vycentruje hru na obrazovke * 0 - položí hru na ľavú stranu a mierne odsadí od okrajov * * v prípade inej hodnoty sa použije preddefinovaná voľba */ if (strcmp(value, "1") == 0) { miny_config.vycentruj = 1; } else if (strcmp(value, "0") == 0) { miny_config.vycentruj = 0; } } } /* zatvorenie súboru */ fclose(fp); } /* * Zobrazí všetky míny na hracom poli a ofarbý ich podľa toho či boli označené... * * * Parametre: * local_win - identifikátor okna hracieho poľa * width - šírka hracieho poľa * height - výška hracieho poľa */ void mini_zobraz (WINDOW *local_win, int width, int height) { /* Pomocné premenné */ int i, j; /* postupne prejde celé hracie pole, každý prvok/políčko */ for (i = 1; i <= height; i++) { for (j = 1; j <= width; j++) { if (min_pole[(j - 1)][(i - 1)] == 1) { /* ak mínu neuhádol, zonbrazí ju a farebne označí */ if (uhadol[(j - 1)][(i - 1)] == 0) { wattron(local_win, COLOR_PAIR(2)); mvwprintw(local_win, i, j, "%s", "*"); wattroff(local_win, COLOR_PAIR(2)); } /* ak mínu uhádol, zonbrazí ju a farebne označí */ else if (uhadol[(j - 1)][(i - 1)] == 2) { wattron(local_win, COLOR_PAIR(3)); mvwprintw(local_win, i, j, "%s", "*"); wattroff(local_win, COLOR_PAIR(3)); } } /* ak zle označil mínu, zonbrazí ju ako chybnú farebne označí */ else if (uhadol[(j - 1)][(i - 1)] == 2) { wattron(local_win, COLOR_PAIR(4)); mvwprintw(local_win, i, j, "%s", "*"); wattroff(local_win, COLOR_PAIR(4)); } } } /* Obnovenie hracieho poľa */ wrefresh(local_win); } /* * Zobrazenie smajlíka * * * Parametre: * smyle_win - identifikátor okna so smajlíkom */ void smajlik_init (WINDOW *smyle_win) { /* zobrazenie bulánka alebo smajlíka */ if (miny_config.bulanek == 1) { /* Vykreslenie bulánka */ mvwprintw(smyle_win, 0, 0, "_________"); mvwprintw(smyle_win, 1, 0, "\\/ \\/"); mvwprintw(smyle_win, 2, 0, " | |"); mvwprintw(smyle_win, 3, 0, " | |"); /* zapnutie tučného textu */ wattron(smyle_win, A_BOLD); mvwaddch(smyle_win, 2, 3, ACS_DEGREE); mvwaddch(smyle_win, 2, 5, ACS_DEGREE); //mvwprintw(smyle_win, 2, 3, "° °"); mvwprintw(smyle_win, 3, 3, "\\_/"); wattroff(smyle_win, A_BOLD); mvwprintw(smyle_win, 4, 0, "/\\ /\\"); /* vykreslenie spodnej čiary bulánka, môže vypísať bludy v menej podporovanom OS (dalo by sa to vypísať aj pomocou cyklu ale takto to lepšie vidím...) */ mvwaddch(smyle_win, 5, 0, ACS_S1); mvwaddch(smyle_win, 5, 1, ACS_S1); mvwaddch(smyle_win, 5, 2, ACS_S1); mvwaddch(smyle_win, 5, 3, ACS_S1); mvwaddch(smyle_win, 5, 4, ACS_S1); mvwaddch(smyle_win, 5, 5, ACS_S1); mvwaddch(smyle_win, 5, 6, ACS_S1); mvwaddch(smyle_win, 5, 7, ACS_S1); mvwaddch(smyle_win, 5, 8, ACS_S1); } else { /* * Zobrazenie obyčajného smajlíka */ mvwprintw(smyle_win, 1, 2, "_____"); mvwprintw(smyle_win, 2, 0, " / \\"); mvwprintw(smyle_win, 3, 0, " | |"); /* zapnutie tučného textu */ wattron(smyle_win, A_BOLD); mvwaddch(smyle_win, 2, 3, ACS_DEGREE); mvwaddch(smyle_win, 2, 5, ACS_DEGREE); //mvwprintw(smyle_win, 2, 3, "° °"); mvwprintw(smyle_win, 3, 3, "\\_/"); wattroff(smyle_win, A_BOLD); mvwprintw(smyle_win, 4, 0, " \\_____/"); } /* refreš okna so smajlíkom */ wrefresh(smyle_win); } /* * Ústa smajlíka/bulánka * * * Parametre: * local_win - identifikátor okna so smajlíkom * ako - ako sa vykreslí úsmev (smutný / štastný) */ void smajlik (WINDOW *local_win, int ako) { /* zapnutie tučného textu */ wattron(local_win, A_BOLD); /* zobrazí úsmev */ if (ako == 1) { mvwprintw(local_win, 3, 3, "\\_/"); } else { /* zobrazí smútok */ mvwprintw(local_win, 3, 3, "/ \\"); /* * bulanek_usem = 1 * 1 : zobrazí sa špecialny znak, vyzeá to krajšie ale nemusí byť 100% podporované * 0 : vykreslí sa klasické podtržítko, funguje to všade ale vyzerá to trochu horšie... */ if (miny_config.bulanek_usmev == 1) mvwaddch(local_win, 3, 4, ACS_S1); else mvwprintw(local_win, 2, 4, "_"); } /* vypnutie tučného textu */ wattroff(local_win, A_BOLD); /* refresh okna so smajlíkov */ wrefresh(local_win); } /* * Príprava na reštart hry * vymaže okná, míny, označenia... * * * Parametre: * my_win - identifikátor okna hracieho poľa * info_win - identifikátor informačného okna * smyle_win - identifikátor okna so smajlíkom * sirka - šírka hracieho poľa * vyska - výśka hracieho poľa */ void restart_prepare (WINDOW *my_win, WINDOW *info_win, WINDOW *smyle_win, int sirka, int vyska) { /* Lokálne premenné */ int i, j; /* postupne prejde všetky políčka hracieho poľa a všetko vynuluje */ for (i = 0; i < sirka; i++) { for (j = 0; j < vyska; j++) { /* Vymazanie mín z hracieho poľa */ min_pole[i][j] = 0; /* Vymazanie označenia políčok */ uhadol[i][j] = 0; /* Vymazanie vypočítaných mín okolo políčka */ pole_hodnot[i][j] = 0; } } /* Uvoľnenie pridelenej amäte */ uvolni_pamet(sirka); /* Zrušenie vytvorených okien */ destroy_win(my_win); destroy_win(info_win); destroy_win(smyle_win); /* Vymazanie hlavného okna, refresh hlavného okna */ clear(); refresh(); } /* * vypísanie počtu mínu okolo daného bodu * * * Parametre: * localwin - idendifikátor okna hracieho poľa * x - súradnica stĺpcu v hracom poli * y - sýradnica riadku v hracom poli * bg - spôsob práce s pozadím / spôsob zvýraznenia, kvôli kurzoru */ void miny_vypis (WINDOW *local_win, int x, int y, int bg) { /* načítanie počtu mín okolo bodu do premennej "min" */ int min = pole_hodnot[(x - 1)][(y - 1)]; /* ak je okolo daného bude nejaká mína.... */ if (min > 0) { /* podľa parametru bg (pozadie) sa vypíše alebo nevypíše počet mín farebne */ if (bg == 1) { wattron(local_win, COLOR_PAIR((4 + min)) | A_BOLD); mvwprintw(local_win, y, x, "%d", min); wattroff(local_win, COLOR_PAIR((4 + min)) | A_BOLD); } /* pokiaľ pozadie nemá byť farebné (použije sa pred tým definované) */ else { mvwprintw(local_win, y, x, "%d", min); } } /* vypísanie nuly, pozadie nieje určené */ else if (uhadol[(x - 1)][(y - 1)] == 1 && bg == 0) { mvwprintw(local_win, y, x, "%s", "0"); } /* vyppíše špeciálny znak pre "prázdne miesto" */ else { wattron(local_win, COLOR_PAIR(11) | A_BOLD | A_REVERSE); mvwaddch(local_win, y, x, ACS_CKBOARD); wattroff(local_win, COLOR_PAIR(11) | A_BOLD | A_REVERSE); } } /* * Kontrola či bolo vyplnené celé mínové pole * vráti 0 ak nedokončil * vráti 1 ak dokončil * * * Parametre: * sirka - śírka hracieho poľa * vyska - výška hracieho poľa */ int dokoncil (int sirka, int vyska) { int i, j; /* cyklicky prejde všetky polia v hre a skontroluje či je mína označená */ for (i = 0; i < sirka; i++) { for (j = 0; j < vyska; j++) { if (min_pole[i][j] == 0 && (uhadol[i][j] == 0 || uhadol[i][j] == 2)) /* vráti 0 */ return 0; } } /* označí všetky neoznačené míny */ for (i = 0; i < sirka; i++) { for (j = 0; j < vyska; j++) { /* Vymazanie mín z hracieho poľa */ if (min_pole[i][j] == 1) uhadol[i][j] = 2; } } /* vráti 1 */ return 1; } /* * Vypíše počet označených min v informačnom okne, * podľa zadaných parametrov * * * Parametre: * local_win - identifikátor okna * oznacil - počet mín ktoré sú už označené * min - počet mín v hre */ void vypis_oznacene(WINDOW *local_win, int oznacil, int min) { /* aktivuje tučný text a farbu podľa podmienky v termálnom operátore */ wattron(local_win, COLOR_PAIR((oznacil <= min ? 0 : 4)) | A_BOLD); /* pokiaľ je označených menej ako 10 min vypíše aj medzeru (pre dodržanie istého formátu, pretože po 10 ostane "mŕtvy znak" 1) */ if (oznacil < 10) mvwprintw(local_win, 3, 25, " %d/%d", oznacil, min); /* pokiaľ je mín viac prepis teoreticky "mŕtveho znaku nie je potrebný" */ else mvwprintw(local_win, 3, 25, "%d/%d", oznacil, min); /* vypnutie formátovania */ wattroff(local_win, COLOR_PAIR((oznacil <= min ? 0 : 4)) | A_BOLD); } /* * Pokúsi sa prideliť pamäť pre polia * Pokiaľ sa pamäť nepodarí prideliť vráti 0 inak vracia 1 * * * Parametre: * sirka - šírka hracieho poľa * vyska - výška hracieho poľa */ int pridel_pamet (int sirka, int vyska) { int i, j; /* pridelenie pamäte.... */ uhadol = (int **) malloc((sirka) * sizeof(int *)); /* * Postupná kontrola a pridelovanie pamäte */ /* ak sa pamä nepodarilo prideli vráti nulu */ if (uhadol == NULL) { return 0; } else { /* * Postupne sa pokúsi získať/prideliť pamäť * ak sa nepodarí získať urćené množstvo pamäte tak získanú pamäť naspäť uvoľní * * pre správne zaobchádzanie s pamäťou sa bude uź alokovaná pamäť pri neúspechu uvoľňovať... */ for (i = 0; i < sirka; i++) { uhadol[i] = (int *) malloc((vyska) * sizeof(int)); if (uhadol[i] == NULL) { /* uvoľní pamäť */ for (j = i; j >= 0; j--) free(uhadol[j]); free(uhadol); /* vymaže premennú */ uhadol = NULL; return 0; } } } /* pridelenie pamäte.... */ min_pole = (int **) malloc((sirka) * sizeof(int *)); /* kontrola pridelenia pamäte */ if (min_pole == NULL) { /* uvoľnenie získanej pamäte pre premennú uhadol ... */ for (j = (sirka - 1); j >= 0; j--) free(uhadol[j]); free(uhadol); /* vymaze premennú */ uhadol = NULL; return 0; } else { /* * alokuje pamäť pre min_pole * ak sa to nepodarí tak uvoľní už alokovanú pamäť */ for (i = 0; i < sirka; i++) { min_pole[i] = (int *) malloc((vyska) * sizeof(int)); if (min_pole[i] == NULL) { /* uvoľní získanú pamäť */ for (j = i; j >= 0; j--) free(min_pole[j]); for (j = (sirka - 1); j >= 0; j--) free(uhadol[j]); /* uvoľnenie pamäte */ free(min_pole); free(uhadol); /* vymaže premenné */ min_pole = NULL; uhadol = NULL; return 0; } } } /* alokovanie pamäte... */ pole_hodnot = (int **) malloc((sirka) * sizeof(int *)); /* kontrola... */ if (pole_hodnot == NULL) { /* uvoľní predelenú pamäť */ for (j = (sirka - 1); j >= 0; j--) { free(uhadol[j]); free(min_pole[j]); } /* uvoňí pamäť */ free(uhadol); free(min_pole); /* vymaže premenné */ uhadol = NULL; min_pole = NULL; return 0; } else { for (i = 0; i < sirka; i++) { pole_hodnot[i] = (int *) malloc((vyska) * sizeof(int)); if (pole_hodnot[i] == NULL) { /* postupne uvoľní pridelenú pamäť */ for (j = i; j >= 0; j--) free(pole_hodnot[j]); for (j = (sirka - 1); j >= 0; j--) { free(min_pole[j]); free(uhadol[j]); } /* uvoľnenie hlavného riadku... */ free(min_pole); free(uhadol); free(pole_hodnot); /* vymazanie premenných */ min_pole = NULL; uhadol = NULL; pole_hodnot = NULL; return 0; } } } return 1; } /* * Celkové uvoľnenie pamäte pre premenné... * * * Parametre: * sirka - šírka hracieho poľa */ void uvolni_pamet (int sirka) { int j; /* postupne uvoľní "riadky" hracieho poľa... */ for (j = (sirka - 1); j >= 0; j--) { free(pole_hodnot[j]); free(min_pole[j]); free(uhadol[j]); } /* "uvoľní havné premenné..." */ free(min_pole); free(uhadol); free(pole_hodnot); /* pre istotu vymaže obsah premenných */ min_pole = NULL; uhadol = NULL; pole_hodnot = NULL; } /* * Uloženie mena a času do skóre tabulky... */ void score_uloz (char meno[], int cas) { FILE *subor; int i; /* otvorenie súboru... */ subor = fopen("score", "a"); /* kontrola otvorenia súboru */ if (subor != NULL) { while (1) { if (meno[i] == ' ') meno[i] = '_'; if (meno[i] == 0) break; i++; } /* zápis do súboru */ fprintf(subor, "%s - %d", meno, cas); /* zatvorenie súboru.. */ fclose(subor); } }