diff --git a/du8/Makefile b/du8/Makefile new file mode 100644 index 0000000..662004c --- /dev/null +++ b/du8/Makefile @@ -0,0 +1,15 @@ +CC=gcc +CFLAGS=-Wall -Wextra -std=c99 +LDFLAGS=-lncurses + +SRC=main.c game.c world.c +OBJ=$(SRC:.c=.o) +EXEC=tictactoe + +all: $(EXEC) + +$(EXEC): $(OBJ) + $(CC) -o $@ $^ $(LDFLAGS) + +clean: + rm -f $(EXEC) $(OBJ) diff --git a/du8/game.c b/du8/game.c new file mode 100644 index 0000000..3ba2e65 --- /dev/null +++ b/du8/game.c @@ -0,0 +1,117 @@ +#include +#include "game.h" +#include "world.h" // * + +int select_game_mode() { + world_clear(); // * + world_print("Zvol si herny rezim:\n1. PvP\n2. PvE\n3. AI vs Human\n"); // * + char c = world_read_key(); // * + return c - '0'; +} +void init_game(GameState *game, int mode) { + game->mode = mode; + game->current_player = 0; + game->moves_made = 0; + + char default_symbols[MAX_PLAYERS] = {'X', 'O', 'A', 'B'}; + for (int i = 0; i < MAX_PLAYERS; i++) { + game->symbols[i] = default_symbols[i]; + } + + if (mode == 1) { + game->board_size = 4; + game->num_players = 3; + } else if (mode == 2) { + game->board_size = 2; // začne s 2x2, rastie do 4x4 + game->num_players = 2; + } else { + game->board_size = 3; + game->num_players = 2; + } + + for (int y = 0; y < MAX_BOARD_SIZE; y++) { + for (int x = 0; x < MAX_BOARD_SIZE; x++) { + game->board[y][x] = ' '; + } + } +} +void draw_game(GameState *game) { + for (int y = 0; y < game->board_size; y++) { + for (int x = 0; x < game->board_size; x++) { + world_set_cursor(x * 4 + 1, y * 2 + 1); // * + world_print("%c", game->board[y][x]); // * + } + } + world_set_cursor(0, game->board_size * 2 + 2); // * + world_print("Na rade je hrac: %c\n", game->symbols[game->current_player]); // * +} +void handle_input(GameState *game) { + int x = 0, y = 0; + while (1) { + world_set_cursor(x * 4 + 1, y * 2 + 1); // * + char key = world_read_key(); // * + if (key == 'w' && y > 0) y--; + else if (key == 's' && y < game->board_size - 1) y++; + else if (key == 'a' && x > 0) x--; + else if (key == 'd' && x < game->board_size - 1) x++; + else if (key == ' ') { + if (game->board[y][x] == ' ') { + game->board[y][x] = game->symbols[game->current_player]; + game->moves_made++; + break; + } + } + } +} +void computer_move(GameState *game) { + for (int y = 0; y < game->board_size; y++) { + for (int x = 0; x < game->board_size; x++) { + if (game->board[y][x] == ' ') { + game->board[y][x] = game->symbols[game->current_player]; + game->moves_made++; + return; + } + } + } +} + +int check_winner(GameState *game) { + int max_line = 0; + int size = game->board_size; + + for (int p = 0; p < game->num_players; p++) { + char sym = game->symbols[p]; + int longest = 0; + + // Kontrola horizontálne, vertikálne a diagonálne + for (int y = 0; y < size; y++) { + int row = 0, col = 0; + for (int x = 0; x < size; x++) { + row = (game->board[y][x] == sym) ? row + 1 : 0; + col = (game->board[x][y] == sym) ? col + 1 : 0; + if (row > longest) longest = row; + if (col > longest) longest = col; + } + } + + int diag1 = 0, diag2 = 0; + for (int i = 0; i < size; i++) { + diag1 = (game->board[i][i] == sym) ? diag1 + 1 : 0; + diag2 = (game->board[i][size - 1 - i] == sym) ? diag2 + 1 : 0; + if (diag1 > longest) longest = diag1; + if (diag2 > longest) longest = diag2; + } + + if (longest >= 3) { + game->current_player = p; + return 1; + } + + if (longest > max_line) { + max_line = longest; + } + } + + return 0; +} + diff --git a/du8/game.h b/du8/game.h new file mode 100644 index 0000000..8f86f19 --- /dev/null +++ b/du8/game.h @@ -0,0 +1,23 @@ +#ifndef GAME_H +#define GAME_H + +#define MAX_PLAYERS 4 +#define MAX_BOARD_SIZE 10 + +typedef struct { + int board_size; + int num_players; + int mode; // 1 = PvP, 2 = PvE, 3 = AI vs Human + int current_player; + int moves_made; + char board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; + char symbols[MAX_PLAYERS]; +} GameState; + +int select_game_mode(); +void init_game(GameState *game, int mode); +void draw_game(GameState *game); +void handle_input(GameState *game); +void computer_move(GameState *game); +int check_winner(GameState *game); +#endif diff --git a/du8/game.o b/du8/game.o new file mode 100644 index 0000000..c0435cb Binary files /dev/null and b/du8/game.o differ diff --git a/du8/main.c b/du8/main.c new file mode 100644 index 0000000..a774d64 --- /dev/null +++ b/du8/main.c @@ -0,0 +1,37 @@ +#include +#include "game.h" +#include "world.h" // * + +int main() { + world_init(); // * inicializácia world + + GameState game; + int mode = select_game_mode(); + init_game(&game, mode); + + while (1) { + world_clear(); // * vyčistenie obrazovky + draw_game(&game); // * vykreslenie hracieho poľa + + if (check_winner(&game)) { + world_print("\nVyhral hrac %c!\n", game.symbols[game.current_player]); // * výpis + break; + } else if (game.moves_made >= game.board_size * game.board_size) { + world_print("\nRemiza!\n"); // * výpis + break; + } + + if (game.mode == 3 && game.current_player == 1) { + computer_move(&game); + } else { + handle_input(&game); // * ovládanie + } + + game.current_player = (game.current_player + 1) % game.num_players; + } + + world_print("Stlač akúkoľvek klávesu pre ukončenie...\n"); // * výpis + world_read_key(); // * caka na vstup + world_end(); // * + return 0; +} diff --git a/du8/main.o b/du8/main.o new file mode 100644 index 0000000..b6eec83 Binary files /dev/null and b/du8/main.o differ diff --git a/du8/tictactoe b/du8/tictactoe new file mode 100755 index 0000000..6d23194 Binary files /dev/null and b/du8/tictactoe differ diff --git a/du8/world.c b/du8/world.c new file mode 100644 index 0000000..bec49ec --- /dev/null +++ b/du8/world.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "world.h" + +void world_init() { + initscr(); // inicializácia ncurses + raw(); // vypne linkový režim (bez enter) + keypad(stdscr, TRUE); // povolí šípky + noecho(); // nevypisuje znaky + curs_set(1); // viditeľný kurzor +} + +void world_end() { + endwin(); // ukončí ncurses +} + +void world_clear() { + clear(); // vyčistí obrazovku + refresh(); // prekreslí +} + +void world_print(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vw_printw(stdscr, fmt, args); + va_end(args); + refresh(); +} + +void world_set_cursor(int x, int y) { + move(y, x); + refresh(); +} + +char world_read_key() { + return getch(); // načítanie jedného znaku +} + diff --git a/du8/world.h b/du8/world.h new file mode 100644 index 0000000..f17adb6 --- /dev/null +++ b/du8/world.h @@ -0,0 +1,23 @@ +#ifndef WORLD_H +#define WORLD_H + +// Inicializuje (ncurses). +void world_init(); + +// Ukončí ncurses +void world_end(); + +// Vymaže obrazovku. +void world_clear(); + +// Vypíše ynak pozíciu kurzora. +void world_print(const char *fmt, ...); + +// Presunie kurzor na (x, y). +void world_set_cursor(int x, int y); + +// Prečíta jeden ynak +char world_read_key(); + +#endif + diff --git a/du8/world.o b/du8/world.o new file mode 100644 index 0000000..e315a73 Binary files /dev/null and b/du8/world.o differ