Mines/main.c

1592 lines
38 KiB
C
Raw Normal View History

2014-11-12 23:07:56 +01:00
/*
* Míny
*
* Vytvoril Juraj Oravec ako semestrálnu prácu.
*
*/
/*
* Vloženie potrebných knižníc / hlavičkových súborov
*/
#include <curses.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#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é 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 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 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 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é 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 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í 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);
}
}