#include //pripojím potrebné knižnice #include #include #include "world.h" #include "game.h" #define DLZKA_HLASENIA 500 //zadefinujem maximálnu dĺžku hlásenia void* inicializaciaHry() { //vytvorím funkciu pre prvotnú inicializáciu hry struct hra* hra = (struct hra*) malloc(sizeof(struct hra)); //nainicializujem riadiacu štruktúru pre celú hru hra->vyskaPolicka = (LINES / 10); //nainicializujem jednotlivé prvky štruktúry hra->sirkaPolicka = (COLS / 10); hra->pocetPolicokX = 4; hra->pocetPolicokY = 6; hra->poslednePolickoX = (COLS / 10) * hra->pocetPolicokX; //vypočítam koncové súradnice hracieho poľa v osi X a Y hra->poslednePolickoY = (LINES / 10) * hra->pocetPolicokY; hra->celkovyPocetPolicok = hra->pocetPolicokX * hra->pocetPolicokY; hra->hraciePole = dvojrozmernePole(hra->pocetPolicokY, hra->pocetPolicokX); hra->hrac1 = 'X'; hra->hrac2 = 'O'; hra->aktualnyHrac = hra->hrac1; hra->nasledujuciHrac = hra->hrac2; int cisloPolicka = 1, i, j; for (i = 0; i < hra->pocetPolicokY; i++) { for (j = 0; j < hra->pocetPolicokX; j++) { hra->hraciePole[i][j] = cisloPolicka; //nainicializujem hracie poli pozičnými číslami cisloPolicka++; } } return hra; } void vykreslenieHry(struct hra* hra) { //funkcia vykreslí aktuálny stav hry int i, j; clear(); //vyčistím predchádzajúci plán hry for (i = 0; i < hra->poslednePolickoY + hra->vyskaPolicka; i += hra->vyskaPolicka) { for (j = 0; j < hra->poslednePolickoX; j++) set_cell('-', j, i); //nakreslím hranice plánu na osi X } for (i = 0; i < hra->poslednePolickoX + hra->sirkaPolicka; i += hra->sirkaPolicka) { for (j = 0; j < hra->poslednePolickoY; j++) set_cell('|', i, j); //nakreslím hranice plánu na osi Y } int k, l; //zadeklarujem premenné pre riadenie výpisu z herného poľa for (j = 0, l = 0; j < hra->poslednePolickoY; j += hra->vyskaPolicka, l++) { //v rámci herného plánu je potrebné posúvať sa aj v rámci osi Y, začiatok je v prvej polovici políčka a posúva sa o jedno políčko for (i = 0, k = 0; i < hra->poslednePolickoX; i += hra->sirkaPolicka, k++) { // počiatok vykresľovania je v polovici prvého políčka herného plánu v osi X, plán sa posúva o jedno políčko /*index prvého hráča: -5 index druhého hráča: -6*/ if (hra->hraciePole[l][k] == -5) mvprintw(j + hra->vyskaPolicka / 2, i + hra->sirkaPolicka / 2, "%c", hra->hrac1); //ak sa namiesto písla políčka nachádza na príslušnej pozícii index prvého hráča, tak na jeho miesto vykreslím znak prvého hráča else if (hra->hraciePole[l][k] == -6) mvprintw(j + hra->vyskaPolicka / 2, i + hra->sirkaPolicka / 2, "%c", hra->hrac2); //ak sa namiesto písla políčka nachádza na príslušnej pozícii index druhého hráča, tak na jeho miesto vykreslím znak druhého hráča else mvprintw(j + hra->vyskaPolicka / 2, i + hra->sirkaPolicka / 2, "%d", hra->hraciePole[l][k]); } } mvprintw(LINES - (2 * (LINES / 10)), 10, "Aktualny hrac: %c", hra->aktualnyHrac); //zobrazím aktuálneho hráča mvprintw(LINES - (2 * (LINES / 10)) + 1, 10, "Zadajte cislo neobsadeneho policka: "); //hláškou vyzvem hráča na zadanie čísla políčka refresh(); //vyobrazím novovygenerovaný plán hry } int hernaSlucka(struct event* udalost, void* hra) { //funkcia je riadiaca štruktúra pre knižnicu world struct hra* vstupneData = (struct hra*) hra; //vstupnú štruktúru pre hru prevediem na príslušný dátový typ stavPolicka(vstupneData, udalost->key); //zmením stav herného plánu zmenaHraca(vstupneData); //zmením hráča vykreslenieHry(vstupneData); //a nakoniec vykreslím aktuálny stav hry vertikalneVytvoreniePiskvorky(hra); //skontrolujem, či je piškvorka vytvorená horizontalneVytvoreniePiskvorky(hra); krizoveVytvoreniePiskvorkyZlava(hra); krizoveVytvoreniePiskvorkySprava(hra); return 0; } int** dvojrozmernePole(int prvyRozmer, int druhyRozmer) { //funkcia vytvorí dvojrozmerné pole typu int int i; int **pole = (int**) malloc(prvyRozmer * sizeof(int*)); //nainicializujem prvý rozmer poľa for (i = 0; i < prvyRozmer; i++) pole[i] = (int*) malloc(druhyRozmer * sizeof(int)); //nainicializujem druhý rozmer poľa return pole; } void stavPolicka(struct hra* hra, int vstup) { //funkcia skontroluje, či bolo zadané platné číslo políčka, priradí ho príslušnému hráčovi a príslušne zmení herný plán int i, j; for (i = 0; i < hra->pocetPolicokY; i++) { //postupne prejdem celé pole for (j = 0; j < hra->pocetPolicokX; j++) { if (hra->hraciePole[i][j] <= 0 && hra->hraciePole[i][j] > hra->celkovyPocetPolicok) break; //ak hráč zadal neplatné číslo políčka, tak sa v hernom pláne nevykoná žiadna zmena if (hra->hraciePole[i][j] == vstup) { //ak sa zadané číslo zhoduje s kontrolovaným číslom, tak zmením herný plán if (hra->aktualnyHrac == hra->hrac1) hra->hraciePole[i][j] = -5; //zmením číslo políčka na príslušný index else hra->hraciePole[i][j] = -6; } } } } void zmenaHraca(struct hra* hra) { //funkcia zmení hráča po vykonaní jednej hernej slučky if (hra->aktualnyHrac == hra->hrac1) { //zmena z 1. hráča na druhého hra->aktualnyHrac = hra->nasledujuciHrac; hra->nasledujuciHrac = hra->hrac1; } else { //a naopak hra->aktualnyHrac = hra->nasledujuciHrac; hra->nasledujuciHrac = hra->hrac2; } } /*nasledujúce funkcie kontrolujú vytvorenie piškvorky (jednotlivé funkcie sa líšia matematickými výpočtami pre určenie, či sa piškvorka vytvorila), komentáre budú uvedené len pri prvej funkcii a na začiatku každej funkcie*/ void vertikalneVytvoreniePiskvorky(struct hra* hra) { //funkcia kontroluje vytvorenie piškvorky vo vertikálnom smere int i, j; char sprava[DLZKA_HLASENIA]; //v správe oznámim hráča, ktorý vyhral for (i = 0; i < hra->pocetPolicokX; i++) { for (j = 0; j + 2 < hra->pocetPolicokY; j++) { if ((hra->hraciePole[j][i] == -5 && hra->hraciePole[j + 1][i] == -5 && hra->hraciePole[j + 2][i] == -5)) { //kontrolujem, či vyhral hráč č. 1 sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac1); koniecHry(sprava); //hru ukončím } else if (hra->hraciePole[j][i] == -6 && hra->hraciePole[j + 1][i] == -6 && hra->hraciePole[j + 2][i] == -6) { //kontrolujem, či vyhral hráč č. 1 sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac2); koniecHry(sprava); //hru ukončím } } } } void horizontalneVytvoreniePiskvorky(struct hra* hra) { //funkcia kontroluje vytvorenie piškvorky vo horizontálnom smere int i, j; char sprava[DLZKA_HLASENIA]; for (i = 0; i < hra->pocetPolicokY; i++) { for (j = 0; j + 2 < hra->pocetPolicokX; j++) { if ((hra->hraciePole[i][j] == -5 && hra->hraciePole[i][j + 1] == -5 && hra->hraciePole[i][j + 2] == -5)) { sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac1); koniecHry(sprava); } else if (hra->hraciePole[i][j] == -6 && hra->hraciePole[i][j + 1] == -6 && hra->hraciePole[i][j + 2] == -6) { sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac2); koniecHry(sprava); } } } } void krizoveVytvoreniePiskvorkyZlava(struct hra* hra) { //funkcia kontroluje vytvorenie piškvorky krížom z ľavej strany int i, j; char sprava[DLZKA_HLASENIA]; for (i = 0; i < hra->pocetPolicokX; i++) { for (j = 0; j < hra->pocetPolicokY; j++) { if ((hra->hraciePole[i][j] == -5 && hra->hraciePole[i + 1][j + 1] == -5 && hra->hraciePole[i + 2][j + 2] == -5)) { sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac1); koniecHry(sprava); } else if (hra->hraciePole[i][j] == -6 && hra->hraciePole[i + 1][j + 1] == -6 && hra->hraciePole[i + 2][j + 2] == -6) { sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac2); koniecHry(sprava); } } } } void krizoveVytvoreniePiskvorkySprava(struct hra* hra) { //funkcia kontroluje vytvorenie piškvorky krížom spravej strany int i, j; char sprava[DLZKA_HLASENIA]; for (i = 0; i < hra->pocetPolicokX; i++) { for (j = hra->pocetPolicokY - 1; j - 2 >= 0; j--) { if ((hra->hraciePole[i + 2][j - 2] == -5 && hra->hraciePole[i + 1][j - 1] == -5 && hra->hraciePole[i][j] == -5)) { sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac1); koniecHry(sprava); } else if (hra->hraciePole[i + 2][j - 2] == -6 && hra->hraciePole[i + 1][j - 1] == -6 && hra->hraciePole[i][j] == -6) { sprintf(sprava, "Hru vyhral hrac %c.\n", hra->hrac2); koniecHry(sprava); } } } } //tu končia funkcie kontrolujúce vytvorenie piškvorky void koniecHry(char* sprava) { //funkcia vykoná príkazy potrebné pre ukončenie hry //zmažem riadiace hlášky move(LINES - (2 * (LINES / 10)), 0); //nastavím kurzor na príslušný riadok clrtoeol(); //a zmažem ho move(LINES - (2 * (LINES / 10)) + 1, 0); //rovnako aj tu clrtoeol(); mvprintw(LINES - (2 * (LINES / 10)), 10, "Koniec hry."); //hráčom oznámim koniec hry refresh(); //vyobrazím hru napms(2000); //zobrazím koncový stav hry abort_game(sprava); //a hru ukončím }