Compare commits

...

2 Commits

Author SHA1 Message Date
87eff11337 Update CMakeLists.txt 2025-04-30 19:36:26 +03:00
d905c1a3f9 Refactoring and updating
Fix bug, when steps = 0, but player didn't lose
2025-04-30 19:36:14 +03:00
8 changed files with 86 additions and 66 deletions

View File

@@ -3,7 +3,7 @@ project(maze LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++23")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++23 -Wall")
include_directories(
include

View File

@@ -1,5 +1,5 @@
#ifndef CLIENT
#define CLIENT
#ifndef CLIENT_HPP
#define CLIENT_HPP
#include <iostream>
#include <cstring>
@@ -7,14 +7,17 @@
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
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

View File

@@ -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<int, std::vector<bool>> graph;
int moves_left;
bool is_path_exists(int, int);
private:
std::unordered_map<int, std::vector<bool>> 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

View File

@@ -12,16 +12,18 @@
#include <cstring>
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

View File

@@ -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) {

View File

@@ -1,14 +1,14 @@
#include "maze.hpp"
#include <iostream>
Maze::Maze(bool _test_mode){
Maze::Maze(bool _test_mode, int _steps){
std::vector<Edge> 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<bool>(DIRECTIONS, true);

View File

@@ -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<char*>(&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<const sockaddr*>(&server_address), sizeof(server_address)) != 0) {
if (bind(server_socket, reinterpret_cast<const sockaddr*>(&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();
}
}

View File

@@ -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<unsigned short>(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;