From cc41164e8321c3ca2eda604312ddeddf04dd5676 Mon Sep 17 00:00:00 2001 From: SGOrava Date: Wed, 12 Nov 2014 23:07:56 +0100 Subject: [PATCH] Add main code --- main.c | 1591 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1591 insertions(+) create mode 100644 main.c diff --git a/main.c b/main.c new file mode 100644 index 0000000..43dec83 --- /dev/null +++ b/main.c @@ -0,0 +1,1591 @@ +/* + * 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); + } +}