diff --git a/include/client.hpp b/include/client.hpp index a3e66be..50c8cc2 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -1,5 +1,5 @@ -#ifndef CLIENT -#define CLIENT +#ifndef CLIENT_HPP +#define CLIENT_HPP #include #include @@ -7,14 +7,17 @@ #include #include #include + class Client{ private: int sock; public: Client(); - void run(const std::string& h = "localhost", const unsigned short p = 1024u); - int ping(struct sockaddr_in); + + void run(const std::string&, const unsigned short); void game(); + + int ping(struct sockaddr_in); }; #endif \ No newline at end of file diff --git a/include/maze.hpp b/include/maze.hpp index 392cf71..2c21bd9 100644 --- a/include/maze.hpp +++ b/include/maze.hpp @@ -11,24 +11,24 @@ const int MAZE_SIZE = 9; const int DIRECTIONS = 4; const int MIN_WALLS = 3; const int MAX_WALLS = 5; -const int DEFAULT_MOVES = 10; class Maze{ - private: - std::unordered_map> graph; - int moves_left; - bool is_path_exists(int, int); +private: + std::unordered_map> graph; + int moves_left; + bool is_path_exists(int start, int end); - struct Edge { - int node1, dir1; - int node2, dir2; - }; - public: - Maze(bool); - bool test_mode; - int get_moves_left() const; - bool is_wall(int, int) const; + struct Edge { + int node1, dir1; + int node2, dir2; + }; +public: + bool test_mode; - void set_moves_left(int); + Maze(bool flag, int steps); + int get_moves_left() const; + bool is_wall(int node, int direction) const; + + void set_moves_left(int _steps); }; #endif diff --git a/include/server.hpp b/include/server.hpp index 8e3cb16..cad8636 100644 --- a/include/server.hpp +++ b/include/server.hpp @@ -12,16 +12,18 @@ #include const int MAX_CLIENTS = 512; +const int BUFFER_SIZE = 1024; class Server { private: bool service_mode; - int server_fd; - void handle_client(int client_socket, bool _mode); // Принимает клиентский сокет + int server_socket; + + void handle_client(int socket, bool flag, int steps); bool check_status(Maze& maze); public: - Server(const std::string& h = "localhost", const unsigned short p = 1024u, bool service_mode = false); - void start(); // Запуск сервера + Server(const std::string& host, const unsigned short port, bool service_flag); + void start(int steps = 10); }; #endif \ No newline at end of file diff --git a/src/client/client.cpp b/src/client/client.cpp index 696d951..4ccada0 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1,14 +1,14 @@ #include "client.hpp" -void print_instructions() { - std::cout << "Доступные команды:\n"; - std::cout << " - вперёд\n"; - std::cout << " - направо\n"; - std::cout << " - налево\n"; - std::cout << " - назад\n"; - std::cout << " - сдаюсь\n"; - std::cout << "Введите команду для хода.\n"; -} +// void print_instructions() { +// std::cout << "Доступные команды:" << std::endl; +// std::cout << " - вперёд" << std::endl; +// std::cout << " - направо" << std::endl; +// std::cout << " - налево" << std::endl; +// std::cout << " - назад" << std::endl; +// std::cout << " - сдаюсь" << std::endl; +// std::cout << "Введите команду для хода" << std::endl; +// } int Client::ping(struct sockaddr_in address){ return connect(sock, (struct sockaddr*)&address, sizeof(address)) != 0; @@ -53,8 +53,8 @@ void Client::run(const std::string& h, const unsigned short p) { } void Client::game(){ - std::cout << "Игра началась!\n"; - print_instructions(); + std::cout << "Игра началась!" << std::endl; + //print_instructions(); char buffer[1024] = {0}; while (true) { diff --git a/src/server/maze.cpp b/src/server/maze.cpp index 7225f6c..1ac2db1 100644 --- a/src/server/maze.cpp +++ b/src/server/maze.cpp @@ -1,14 +1,14 @@ #include "maze.hpp" #include -Maze::Maze(bool _test_mode){ +Maze::Maze(bool _test_mode, int _steps){ std::vector edges = { {0, 1, 1, 3}, {0, 0, 3, 2}, {1, 1, 2, 3}, {1, 0, 4, 2}, {2, 0, 5, 2}, {3, 1, 4, 3}, {3, 0, 6, 2}, {4, 1, 5, 3}, {4, 0, 7, 2}, {5, 0, 8, 2}, {6, 1, 7, 3}, {7, 1, 8, 3} }; test_mode = _test_mode; - moves_left = test_mode ? INT_MAX : DEFAULT_MOVES; + moves_left = test_mode ? INT_MAX : _steps; for (int i = 0; i < MAZE_SIZE; ++i) { graph[i] = std::vector(DIRECTIONS, true); diff --git a/src/server/server.cpp b/src/server/server.cpp index 1eebd45..bd7074d 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -1,13 +1,21 @@ #include "server.hpp" -Server::Server(const std::string& h, const unsigned short p, bool service_mode){ - // Создание сокета. - server_fd = socket(AF_INET, SOCK_STREAM, 0); - if (server_fd < 0) { +bool Server::check_status(Maze &maze) { + return (!maze.test_mode && maze.get_moves_left() > 0); +} + +Server::Server(const std::string& h, const unsigned short p, bool _service){ + service_mode = _service; + if (service_mode) { + std::cout << "Service mode is ON" << std::endl; + } + + sockaddr_in server_address; + + if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { throw std::runtime_error("Error in create socket"); } - // Подготовка сетевого адреса для связывания. - sockaddr_in server_address; + memset(reinterpret_cast(&server_address), '\0', sizeof(server_address)); server_address.sin_family = AF_INET; hostent* host_name; @@ -15,36 +23,32 @@ Server::Server(const std::string& h, const unsigned short p, bool service_mode){ if (host_name == nullptr) { throw std::runtime_error("Error in getting hostname"); } + server_address.sin_port = htons(p); memcpy(&server_address.sin_addr.s_addr, host_name->h_addr, host_name->h_length); - if (bind(server_fd, reinterpret_cast(&server_address), sizeof(server_address)) != 0) { + if (bind(server_socket, reinterpret_cast(&server_address), sizeof(server_address)) != 0) { throw std::runtime_error("Error in bind part"); } std::cout << "Сервер запущен на хосте " << h << " на порту " << p << std::endl; } -bool Server::check_status(Maze &maze) { - return (!maze.test_mode && maze.get_moves_left() > 0); -} - -void Server::handle_client(int client_socket, bool mode) { - Maze maze(mode); // Создаем экземпляр лабиринта для клиента - int current_position = 0; // Начальная позиция игрока +void Server::handle_client(int client_socket, bool mode, int steps) { + Maze maze(mode, steps); + int current_position = 0; std::string player_name; - char buffer[1024] = {0}; + char buffer[BUFFER_SIZE] = {0}; std::string response; - // Получение имени игрока int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0); if (bytes_received <= 0) { - std::cout << "Ошибка получения имени игрока.\n"; + std::cout << "Error in getting player name"; close(client_socket); return; } player_name = std::string(buffer); - std::cout << "Новый игрок: " << player_name << "\n"; + std::cout << "Новый игрок: " << player_name << std::endl; while (true) { int moves_left = maze.get_moves_left(); @@ -56,7 +60,7 @@ void Server::handle_client(int client_socket, bool mode) { } std::string command(buffer); - std::cout << "Получена команда от игрока " << player_name << ": " << command << "\n"; + std::cout << "Получена команда от игрока " << player_name << ": " << command << std::endl; int direction = -1; int new_position = current_position; @@ -109,10 +113,13 @@ void Server::handle_client(int client_socket, bool mode) { break; } + maze.set_moves_left(moves_left - 1); + if (!check_status(maze)) + break; + int x = current_position % 3; int y = current_position / 3; std::string text("(" + std::to_string(x) + ", " + std::to_string(y) + ")\n"); - maze.set_moves_left(moves_left - 1); response = "успешно, осталось " + std::to_string(maze.get_moves_left()) + " ходов. Вы находитесь в " + text; send(client_socket, response.c_str(), response.size(), 0); } @@ -124,25 +131,24 @@ void Server::handle_client(int client_socket, bool mode) { } close(client_socket); - std::cout << "Игрок " << player_name << " отключился.\n"; + std::cout << "Игрок " << player_name << " отключился" << std::endl; } -void Server::start() { +void Server::start(int steps) { int new_socket; - if (listen(server_fd, MAX_CLIENTS) < 0) { + if (listen(server_socket, MAX_CLIENTS) < 0) { throw std::runtime_error("Error in listen"); } sockaddr address; - int addrlen = sizeof(address); socklen_t address_size = sizeof(address); while (true) { - if ((new_socket = accept(server_fd, (struct sockaddr*)&address, &address_size)) < 0) { + if ((new_socket = accept(server_socket, (struct sockaddr*)&address, &address_size)) < 0) { throw std::runtime_error("Error in accept"); } - std::cout << "Новое соединение установлено.\n"; - std::thread(&Server::handle_client, this, new_socket, true).detach(); + std::cout << "Новое соединение установлено" << std::endl; + std::thread(&Server::handle_client, this, new_socket, service_mode, steps).detach(); } } \ No newline at end of file diff --git a/src/server/server_main.cpp b/src/server/server_main.cpp index dc79331..e751b97 100644 --- a/src/server/server_main.cpp +++ b/src/server/server_main.cpp @@ -3,10 +3,11 @@ int main(int argc, char **argv) { int opt; std::string host = "localhost"; + int steps = 10; bool service_mode = false; short unsigned port = 1024u; - while ((opt = getopt(argc, argv, "h:p:s:")) != -1) { + while ((opt = getopt(argc, argv, "h:p:sn:")) != -1) { switch (opt) { case 'h': host = optarg; @@ -14,8 +15,16 @@ int main(int argc, char **argv) { case 'p': port = static_cast(atoi(optarg)); break; + case 'n': + steps = atoi(optarg); + if(steps <= 0) { + std::cerr << "Invalid steps" << std::endl; + return 1; + } + break; case 's': service_mode = true; + break; default: break; } @@ -23,7 +32,7 @@ int main(int argc, char **argv) { try { Server server(host, port, service_mode); - server.start(); + server.start(steps); } catch (const std::runtime_error& e){ std::cerr << "Server application error: " << e.what() << std::endl; return 1;