finalne_zadanie
This commit is contained in:
parent
2f49f56335
commit
def9f04a3f
54
final/.gitignore
vendored
Normal file
54
final/.gitignore
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
game
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
29
final/LICENSE
Normal file
29
final/LICENSE
Normal file
@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2019, Daniel Hládek
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
14
final/Makefile
Normal file
14
final/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
CFLAGS=-std=c99 -Wall -g
|
||||
|
||||
all: game
|
||||
|
||||
%.o: %.c
|
||||
gcc $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm *.o
|
||||
rm hra
|
||||
|
||||
game: main.o game.o world.o
|
||||
gcc main.o game.o world.o -lcurses -lm -o hra
|
||||
|
78
final/README.md
Normal file
78
final/README.md
Normal file
@ -0,0 +1,78 @@
|
||||
# Piškvorky - hra
|
||||
|
||||
## Obsah
|
||||
|
||||
- Predstavenie hry
|
||||
- Kompilácia a spustenie hry
|
||||
- Priebeh hry a jej koniec
|
||||
- Štruktúry a funkcie hry
|
||||
- Zdroje
|
||||
|
||||
## Predstavenie hry
|
||||
|
||||
Počítačová verzia hry piškvorky je určená pre dvoch hráčov. Títo hráči sa počas hrania hry pri počítači striedajú. Cieľom hry je vytvoriť piškvorku. Hráč, ktorý vytvorí piškvorku, vyhráva. Po vytvorení piškvorky sa hra ukončí a oznámi výherného hráča. Hra je naprogramovaná v jazyku C.
|
||||
|
||||
## Kompilácia a spustenie hry
|
||||
|
||||
Pre kompiláciu hry je potrebné použiť pripravený Makefile, ktorý sa nachádza v rovnakom priečinku, ako zdrojové kódy programu. Pre kompiláciu programu je potrebné mať nainštalovanú knižnicu ncurses.
|
||||
|
||||
Hru skompilujeme pomocou nasledujúceho príkazu:
|
||||
|
||||
make all
|
||||
|
||||
A následne ju spustíme pomocou príkazu:
|
||||
|
||||
./hra
|
||||
|
||||
## Priebeh hry
|
||||
|
||||
Po spustení hry sa na obrazovku vykreslí herný plán a pod ním sa zobrazia oznamy o aktuálnom stave hry.
|
||||
|
||||
Herný plán tvorí sieť, ktorej veľkosť sa mení v závislosti od veľkosti výstupnej obrazovky. Každé políčko v tejto sieti je má svoje číslo, ktoré hráč zadáva ako vstup do programu počas hrania hry.
|
||||
|
||||
Ako už bolo vyššie spomenuté, tak táto verzia hry je určená pre dvoch hráčov. Hráči sa počas hrania striedajú pri počítači. Hráč zadá do programu číslo políčka, ktoré chce obsadiť. Následne sa na danom políčku namiesto čísla vyobrazí znak hráča. Ak hráč zadá číslo políčka, ktoré je obsadené, príp. číslo mimo rozsah, alebo iný znak, tak prichádza o pokus a nasleduje další hráč. Hru vyhráva hráč, ktorý ako prvý úspešne zostaví piškvorku.
|
||||
|
||||
Na hernej obrazovke sa následne objaví oznam o skončení hry a potom v termináli OS aj oznam oznamujúci, ktorý hráč vyhral.
|
||||
|
||||
## Štruktúry a funkcie hry
|
||||
|
||||
Hra je naprogramovaná pre použitie knižnicou world.h.
|
||||
|
||||
Obsahuje základnú riadiacu štruktúru celej hry. Teraz si podrobnejšie popíšeme jej jednotlivé premenné. Pri premenných, pri ktroých je z popisu jasné, na čo sú určené, nebudeme popis uvádzať:
|
||||
|
||||
int vyskaPolicka
|
||||
int sirkaPolicka
|
||||
|
||||
int poslednePolickoX //premenná uchováva súradnicu X posledného políčka
|
||||
int poslednePolickoY //rovnako ako predchádzajúca premenná, ale súradnicu Y
|
||||
|
||||
int pocetPolicokX //počet políčok v 1 riadku
|
||||
int pocetPolicokY //počet políčok v 1 stĺpci
|
||||
int celkovyPocetPolicok
|
||||
|
||||
int** hernePole //v dvojrozmernom poli je uložený aktuálny herný plán
|
||||
|
||||
char hrac1
|
||||
char hrac2
|
||||
char aktualnyHrac
|
||||
char nasledujuciHrac
|
||||
|
||||
Teraz si stručne popíšeme jednotlivé funkcie hry:
|
||||
|
||||
- **void*** inicializaciaHry(): každá hra, ktorá využíva knižnicu world, musí obsahovať funkciu, ktorá na začiatku nainicializuje hru; v tomto prípade táto funkcia nainicializuje riadiacu štruktúru hry, jednotlivé položky štruktúry a herný plán
|
||||
- **void** vykreslenieHry(struct hra* hra): funkcia vykreslí aktuálny stav hry na základe herného a vypíše informačné hlásenia
|
||||
- **int** hernaSlucka(struct event* udalost, void* hra): okrem inicializačnej funkcie musí každá hra naprogramovaná v knižnici world obsahovať aj riadiacu funkciu, táto funkcia riadi stav celej hry, štruktúra event obsahuje vstup z knižnice world
|
||||
- **int**** dvojrozmernePole(int prvyRozmer, int druhyRozmer): funkcia nainicializuje dvojrizmerné pole typu int
|
||||
- **void** stavPolicka(struct hra* hra, int vstup): funkcia skontroluje, či zadaný vstup je platný a či je políčko v hernom poli je obsadené
|
||||
- **void** zmenaHraca(struct hra* hra): funkcia zmení aktuálneho hráča po vykonaní jednej hernej slučky
|
||||
- **void** vertikalneVytvoreniePiskvorky(struct hra* hra): hra skontroluje vytvorenie piškvorky vo vertikálnom smere
|
||||
- **void** horizontalneVytvoreniePiskvorky(struct hra* hra): skontroluje vytvorenie piškvorky vo horizontálnom smere
|
||||
- **void** krizoveVytvoreniePiskvorkyZlava(struct hra* hra): skontroluje vytvorenie šikmej piškvorky z ľavej strany
|
||||
- **void** krizoveVytvoreniePiskvorkySprava(struct hra* hra): skontroluje vytvorenie šikmej piškvorky spravej strany
|
||||
- **void** koniecHry(char* sprava): funkcia obsahuje príkazy potrebné pre ukončenie hry, funkcia musí po ukončení hry vypísať informáciu (ľubovoľnú)
|
||||
|
||||
Kvôli výskytu dvojciferných čísel sme museli upraviť aj spôsob načítavania čísel do pamäte, keďže pôvodná verzia dokázala načítať iba jeden znak. Po úprave dokáže knižnica world načítať trojciferné číslo a pred potvrdením ho je možné aj editovať.
|
||||
|
||||
## Zdroje
|
||||
|
||||
[How to clear a specific line with NCurses?] (https://stackoverflow.com/questions/5072881/how-to-clear-a-specific-line-with-ncurses)
|
BIN
final/README.pdf
Normal file
BIN
final/README.pdf
Normal file
Binary file not shown.
199
final/game.c
Normal file
199
final/game.c
Normal file
@ -0,0 +1,199 @@
|
||||
#include <curses.h> //pripojím potrebné knižnice
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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
|
||||
}
|
39
final/game.h
Normal file
39
final/game.h
Normal file
@ -0,0 +1,39 @@
|
||||
#include "world.h"
|
||||
|
||||
struct hra { //vytvorím štruktúru riadiacu celú hru
|
||||
int vyskaPolicka;
|
||||
int sirkaPolicka;
|
||||
|
||||
int poslednePolickoX;
|
||||
int poslednePolickoY;
|
||||
|
||||
int pocetPolicokX;
|
||||
int pocetPolicokY;
|
||||
int celkovyPocetPolicok;
|
||||
|
||||
int** hraciePole;
|
||||
|
||||
char hrac1;
|
||||
char hrac2;
|
||||
char aktualnyHrac;
|
||||
char nasledujuciHrac;
|
||||
};
|
||||
|
||||
//funkcia pre inicializáciu hry
|
||||
void* inicializaciaHry();
|
||||
|
||||
int hra(struct event* udalost, void* hra);
|
||||
void vykreslenieHry(struct hra* hra);
|
||||
int hernaSlucka(struct event* udalost, void* hra);
|
||||
|
||||
int** dvojrozmernePole(int prvyRozmer, int druhyRozmer);
|
||||
|
||||
void stavPolicka(struct hra* hra, int vstup);
|
||||
void zmenaHraca(struct hra* hra);
|
||||
|
||||
void vertikalneVytvoreniePiskvorky(struct hra* hra);
|
||||
void horizontalneVytvoreniePiskvorky(struct hra* hra);
|
||||
void krizoveVytvoreniePiskvorkyZlava(struct hra* hra);
|
||||
void krizoveVytvoreniePiskvorkySprava(struct hra* hra);
|
||||
|
||||
void koniecHry(char* sprava);
|
7
final/main.c
Normal file
7
final/main.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "game.h"
|
||||
#include "world.h"
|
||||
|
||||
int main(int argc, char** argv){
|
||||
start_world(inicializaciaHry,hernaSlucka,free);
|
||||
return 0;
|
||||
}
|
182
final/world.c
Normal file
182
final/world.c
Normal file
@ -0,0 +1,182 @@
|
||||
#include "world.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
int TIMEOUT;
|
||||
|
||||
void abort_game(const char* message){
|
||||
endwin();
|
||||
puts(message);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void check_bounds(const char* source,int x, int y){
|
||||
char msg[200];
|
||||
if (x < 0 || x >= COLS){
|
||||
sprintf(msg,"%s:: width %d is out of bounds (0,%d)",source,x,COLS);
|
||||
abort_game(msg);
|
||||
}
|
||||
if (y < 0 || y >= LINES){
|
||||
sprintf(msg,"%s:: height %d is out of bounds (0,%d)",source,y,LINES);
|
||||
abort_game(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void clear_screen(){
|
||||
// Clear screen
|
||||
mvaddch(0,0,' ');
|
||||
int screenchars = LINES*COLS;
|
||||
for (int j = 1; j < screenchars;j++ ){
|
||||
addch(' ');
|
||||
}
|
||||
}
|
||||
|
||||
void game_speed(int value){
|
||||
if (value < 0){
|
||||
abort_game("world_seed:: cannot be negative\n");
|
||||
}
|
||||
TIMEOUT =value;
|
||||
}
|
||||
|
||||
void set_message(const char* message,int x,int y) {
|
||||
int l = strlen(message);
|
||||
for (int i = 0; i < l; i++){
|
||||
check_bounds("set_message",x+i,y);
|
||||
set_cell(message[i],x+i,y);
|
||||
}
|
||||
}
|
||||
|
||||
void assert_message(int event,const char* message){
|
||||
if (event == 0){
|
||||
abort_game(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_cell(int character,int x,int y) {
|
||||
check_bounds("set_cell",x,y);
|
||||
set_color_cell(character,x,y,COLOR_WHITE,COLOR_BLACK);
|
||||
}
|
||||
|
||||
void set_color_cell(int character,int x,int y,short front_color,short back_color){
|
||||
check_bounds("set_color_cell",x,y);
|
||||
if (has_colors()){
|
||||
int pair = COLOR_COUNT * front_color + back_color;
|
||||
attron(COLOR_PAIR(pair));
|
||||
mvaddch(y,x,character);
|
||||
attroff(COLOR_PAIR(pair));
|
||||
}
|
||||
else{
|
||||
mvaddch(y,x,character);
|
||||
}
|
||||
}
|
||||
|
||||
int start_world(void* (*init_game)(),int (*world_event)(struct event* event,void* game),void (*destroy_game)(void*)){
|
||||
srand(time(NULL));
|
||||
int r = 1;
|
||||
// Speed global variable
|
||||
TIMEOUT = 100;
|
||||
if (initscr() == NULL){
|
||||
// TODO Which Error?
|
||||
puts("Curses Error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curs_set(FALSE); // Neviditeľný kurzor
|
||||
if (has_colors()){ // Zistenie či terminál podporuje farby
|
||||
start_color();
|
||||
for (int i = 0; i < COLOR_COUNT;i++){
|
||||
for (int j = 0; j < COLOR_COUNT;j++){
|
||||
init_pair(i * COLOR_COUNT + j, i,j);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
puts("No colors!\n");
|
||||
}
|
||||
void* game = NULL;
|
||||
if (init_game != NULL){
|
||||
game = init_game();
|
||||
assert_message(game != NULL,"init_game:: should return non null pointer");
|
||||
}
|
||||
timeout(TIMEOUT);
|
||||
// Initial step
|
||||
struct event event;
|
||||
memset(&event,0,sizeof(struct event));
|
||||
event.height = LINES;
|
||||
event.width = COLS;
|
||||
event.type = EVENT_START;
|
||||
clock_t start_time = clock();
|
||||
clock_t last_timeout = start_time;
|
||||
clock_t next_timeout = last_timeout + TIMEOUT;
|
||||
event.time_ms = start_time;
|
||||
// Start event
|
||||
r = world_event(&event,game);
|
||||
refresh();
|
||||
while (!r) {
|
||||
memset(&event,0,sizeof(struct event));
|
||||
event.height = LINES;
|
||||
event.width = COLS;
|
||||
|
||||
//začiatok upravenej časti programu
|
||||
//upravená časť programu načítava číselný vstup od používateľa
|
||||
char buff[4];
|
||||
const int VELKOST_BUFF = 4;
|
||||
memset(buff, '\0', VELKOST_BUFF);
|
||||
int i = 0;
|
||||
|
||||
while (true) {
|
||||
int buff_char = (char) getchar();
|
||||
|
||||
//zadaný vstup vyobrazujem
|
||||
if (i > 0 && buff_char == 127) {
|
||||
buff[i - 1] = '\0';
|
||||
i -= 2;
|
||||
mvprintw(LINES - (2 * (LINES / 10)) + 1, 10 + 1 + strlen("Zadajte cislo neobsadeneho policka: "), " ");
|
||||
mvprintw(LINES - (2 * (LINES / 10)) + 1, 10 + 1 + strlen("Zadajte cislo neobsadeneho policka: "), "%s", buff); //po zmazaní znaku sa odstráni aj z obrazovky
|
||||
}
|
||||
else if (buff_char >= '0' && buff_char <= '9') {
|
||||
buff[i] = buff_char;
|
||||
mvprintw(LINES - (2 * (LINES / 10)) + 1, 10 + 1 + strlen("Zadajte cislo neobsadeneho policka: "), "%s", buff);
|
||||
}
|
||||
i++;
|
||||
refresh();
|
||||
|
||||
if (i == VELKOST_BUFF) break;
|
||||
else if (buff_char == '\r') break;
|
||||
}
|
||||
|
||||
event.key = atoi(buff);
|
||||
//začiatok upravenej časti programu
|
||||
|
||||
// Draw new world
|
||||
event.time_ms = clock();
|
||||
r = world_event(&event,game);
|
||||
refresh();
|
||||
event.time_ms = clock();
|
||||
// set new timeout
|
||||
int nt = next_timeout - event.time_ms;
|
||||
//printf("%d\n",nt);
|
||||
if (nt > 0){
|
||||
timeout(nt);
|
||||
}
|
||||
else {
|
||||
timeout(TIMEOUT);
|
||||
next_timeout = event.time_ms + TIMEOUT;
|
||||
}
|
||||
}
|
||||
memset(&event,0,sizeof(struct event));
|
||||
event.height = LINES;
|
||||
event.width = COLS;
|
||||
event.type = EVENT_END;
|
||||
event.time_ms = clock();
|
||||
world_event(&event,game);
|
||||
if (destroy_game != NULL){
|
||||
destroy_game(game);
|
||||
}
|
||||
endwin();
|
||||
return r;
|
||||
};
|
123
final/world.h
Normal file
123
final/world.h
Normal file
@ -0,0 +1,123 @@
|
||||
#ifndef _WORLD_H_
|
||||
#define _WORLD_H_
|
||||
|
||||
#include <curses.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* World represented as a rectangular matrix of colorful characters.
|
||||
*
|
||||
* Point [0,0] is displayed the upper left corner of the screen.
|
||||
*
|
||||
*/
|
||||
|
||||
enum event_type {
|
||||
EVENT_START,
|
||||
EVENT_TIMEOUT,
|
||||
EVENT_KEY,
|
||||
EVENT_MOUSE,
|
||||
EVENT_RESIZE,
|
||||
EVENT_ESC,
|
||||
EVENT_END,
|
||||
};
|
||||
|
||||
struct event {
|
||||
/**
|
||||
* Last width of the screen.
|
||||
*/
|
||||
int width;
|
||||
/**
|
||||
* Last height of the screen.
|
||||
*/
|
||||
int height;
|
||||
/**
|
||||
* Last pressed key or Curses event.
|
||||
*
|
||||
* Special event values:
|
||||
* ERR if timeout,
|
||||
* KEY_RESIZE if screen resize
|
||||
* KEY_EVENT, other event,
|
||||
* KEY_MOUSE, mouse clicked
|
||||
*
|
||||
* Key values:
|
||||
*
|
||||
* ' ' Space
|
||||
* KEY_DOWN Arrow down
|
||||
* KEY_UP Arrow up
|
||||
* KEY_LEFT Arrow left
|
||||
* KEY_RIGHT Arrow right
|
||||
* KEY_A1 Upper left of keypad
|
||||
* KEY_A3 Upper right of keypad
|
||||
* KEY_B2 Center of keypad
|
||||
* KEY_C1 Lower left of keypad
|
||||
* KEY_C3 Lower right of keypad
|
||||
*
|
||||
* KEY_ENTER
|
||||
* KEY_BACKSPACE
|
||||
*/
|
||||
int key;
|
||||
int alt_key;
|
||||
enum event_type type;
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
int mouse_left;
|
||||
int mouse_right;
|
||||
int mouse_middle;
|
||||
long int time_ms;
|
||||
};
|
||||
|
||||
void abort_game(const char* message);
|
||||
|
||||
/**
|
||||
* Sets cell to a state.
|
||||
* @param event
|
||||
* @param x coordinate of cell
|
||||
* @param y coordinate of cell
|
||||
* @param new state of the cell
|
||||
*/
|
||||
void set_cell(int character,int x,int y);
|
||||
|
||||
/**
|
||||
* COLOR_BLACK 0
|
||||
* COLOR_RED 1
|
||||
* COLOR_GREEN 2
|
||||
* COLOR_YELLOW 3
|
||||
* COLOR_BLUE 4
|
||||
* COLOR_MAGENTA 5
|
||||
* COLOR_CYAN 6
|
||||
* COLOR_WHITE 7
|
||||
*/
|
||||
|
||||
#define COLOR_COUNT 8
|
||||
|
||||
void set_color_cell(int character,int x,int y,short front_color,short back_color);
|
||||
void check_bounds(const char* source,int x, int y);
|
||||
void game_speed(int value);
|
||||
void set_message(const char* message,int x,int y);
|
||||
void assert_message(int event,const char* message);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param event
|
||||
* @param number of commandline arguments
|
||||
* @param init_world
|
||||
* @param destroy_world
|
||||
*
|
||||
* void init_world(struct event* w);
|
||||
* Initializes user state.
|
||||
* Free user state.
|
||||
* @param event
|
||||
*/
|
||||
|
||||
int start_world(void* (*init_game)(),int (*world_event)(struct event* event,void* game),void (*destroy_game)(void* game));
|
||||
|
||||
void game_speed(int value);
|
||||
|
||||
void set_message(const char* message,int x,int y);
|
||||
void clear_screen();
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user