hra
This commit is contained in:
parent
419d8ead1f
commit
f560dd6060
15
du8/Makefile
Normal file
15
du8/Makefile
Normal file
@ -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)
|
117
du8/game.c
Normal file
117
du8/game.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
||||
|
23
du8/game.h
Normal file
23
du8/game.h
Normal file
@ -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
|
BIN
du8/game.o
Normal file
BIN
du8/game.o
Normal file
Binary file not shown.
37
du8/main.c
Normal file
37
du8/main.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
BIN
du8/main.o
Normal file
BIN
du8/main.o
Normal file
Binary file not shown.
BIN
du8/tictactoe
Executable file
BIN
du8/tictactoe
Executable file
Binary file not shown.
39
du8/world.c
Normal file
39
du8/world.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <ncurses.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#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
|
||||
}
|
||||
|
23
du8/world.h
Normal file
23
du8/world.h
Normal file
@ -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
|
||||
|
BIN
du8/world.o
Normal file
BIN
du8/world.o
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user