Полнофункциональная многопользовательская игра "Морской бой" с современным веб-интерфейсом и высокопроизводительным backend сервером.
- Описание
- Технологический стек
- Архитектура
- Быстрый старт
- Разработка
- WebSocket API
- Правила игры
- Структура проекта
Морской бой - это классическая настольная игра, реализованная как многопользовательское веб-приложение. Игроки могут создавать игровые комнаты, присоединяться к ним и играть в реальном времени через WebSocket соединение.
- ✅ Создание и присоединение к игровым сессиям
- ✅ Интерактивная расстановка кораблей с валидацией
- ✅ Игровой процесс в реальном времени
- ✅ Отображение статистики игры
- ✅ Адаптивный пользовательский интерфейс
- React 19 - UI библиотека
- TypeScript - типизированный JavaScript
- Vite - быстрый сборщик и dev-сервер
- Lucide React - современные иконки
- CSS Modules - модульные стили
- C++17 - высокопроизводительный язык
- Crow - легковесный веб-фреймворк
- WebSocket - двусторонняя связь в реальном времени
- JSON - формат обмена данными
- Docker - контейнеризация
- Docker Compose - оркестрация сервисов
- Nginx - reverse proxy и статический сервер
┌─────────────┐
│ Browser │
│ (React) │
└──────┬──────┘
│ HTTP/WS
▼
┌─────────────┐
│ Nginx │
│ (Port 80) │
└──────┬──────┘
│
├──────────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Backend │ │ Static │
│ (Crow) │ │ Files │
│ (Port 18080)│ │ (Frontend) │
└─────────────┘ └─────────────┘
-
Frontend (React)
- Управление состоянием через Context API
- WebSocket клиент для связи с сервером
- Компоненты для всех этапов игры
-
Backend (Crow)
- Менеджер игровых сессий
- Игровой движок с валидацией
- WebSocket обработчики
- JSON сериализация
-
Nginx
- Reverse proxy для backend
- Статический сервер для frontend
- WebSocket upgrade проксирование
- Docker (версия 20.10+)
- Docker Compose (версия 2.0+)
- Git (для клонирования репозитория)
# Клонирование репозитория
git clone https://github.com/Jenison4ik/Sea_Battle
cd ./Sea_Battle
# Запуск всех сервисов
docker-compose up --build
# Или в фоновом режиме
docker-compose up -d --buildПосле запуска приложение будет доступно по адресу: http://localhost
docker-compose down# Логи всех сервисов
docker-compose logs -f
# Логи только backend
docker-compose logs -f backend
# Логи только nginx
docker-compose logs -f nginxcd frontend
# Установка зависимостей
npm install
# Запуск dev-сервера (http://localhost:5173)
npm run dev
# Сборка для production
npm run build
# Линтинг
npm run lintsudo apt-get update
sudo apt-get install -y build-essential cmake git libboost-all-devcd /tmp
git clone https://github.com/CrowCpp/Crow.git
cd Crow
mkdir build && cd build
cmake .. -DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF
cmake --build .
sudo cmake --install . --prefix /usr/localcd backend
mkdir build && cd build
cmake ..
cmake --build .
# Запуск
./SeaBattleBackendBackend запускается на порту 18080 по умолчанию. Для изменения порта отредактируйте docker-compose.yml и nginx.conf.
ws://localhost/ws
Все сообщения передаются в формате JSON.
Клиент → Сервер:
{
"type": "CREATE_SESSION"
}Сервер → Клиент:
{
"type": "SESSION_CREATED",
"roomCode": "A7F3Q2"
}Клиент → Сервер:
{
"type": "JOIN_SESSION",
"roomCode": "A7F3Q2"
}Сервер → Обоим игрокам:
{
"type": "GAME_START",
"firstTurn": "player1"
}Клиент → Сервер:
{
"type": "PLACE_SHIPS",
"ships": [
[
[1, 1],
[1, 2],
[1, 3],
[1, 4]
], // 4-палубный
[
[3, 1],
[3, 2],
[3, 3]
], // 3-палубный
[
[3, 5],
[3, 6]
], // 2-палубный
[[5, 1]] // 1-палубный
// ... всего 10 кораблей: 1x4, 2x3, 3x2, 4x1
]
}Сервер → Клиент:
{
"type": "SHIPS_PLACED"
}Клиент → Сервер:
{
"type": "SHOT",
"x": 1,
"y": 2
}Сервер → Текущий игрок (MY_SHOT):
{
"type": "STATE",
"mode": "MY_SHOT",
"data": {
"ships": [
{
"heated_cords": [
[1, 2],
[1, 3]
],
"isKilled": false
}
],
"shooted_cords": [
[1, 2],
[1, 3],
[5, 6]
]
}
}Сервер → Противник (ENEMY_SHOT):
{
"type": "STATE",
"mode": "ENEMY_SHOT",
"data": {
"ships": [
{
"first_cord": [1, 2],
"sec_cord": [1, 5],
"heated_cords": [
[1, 2],
[1, 3]
],
"isKilled": false
}
],
"shooted_cords": [
[1, 2],
[1, 3],
[5, 6]
]
}
}Сервер → Обоим игрокам:
{
"type": "GAME_OVER",
"winner": "player1",
"stats": {
"shots": 34,
"hits": 10,
"misses": 24,
"accuracy": 29.4,
"sunkShips": 3
}
}Сервер → Клиент:
{
"type": "ERROR",
"message": "Описание ошибки"
}Клиент → Сервер:
{
"type": "PING"
}Сервер → Клиент:
{
"type": "PONG"
}Подробные примеры использования API можно найти в файле API_EXAMPLES.md.
- 1 корабль на 4 клетки
- 2 корабля на 3 клетки
- 3 корабля на 2 клетки
- 4 корабля на 1 клетку
- Корабли не должны соприкасаться (включая диагонали)
- Корабли должны быть непрерывными (горизонтально или вертикально)
- При промахе (MISS) ход переходит к противнику
- При попадании (HIT) ход остается у текущего игрока
- При убийстве корабля (KILL) ход остается у текущего игрока
- При победе (WIN) игра заканчивается
Игрок побеждает, когда все корабли противника уничтожены.
Sea_Battle/
├── backend/ # Backend сервер (C++)
│ ├── include/ # Заголовочные файлы
│ │ ├── types.h # Структуры данных
│ │ ├── session_manager.h # Менеджер сессий
│ │ ├── game_engine.h # Игровой движок
│ │ ├── json_serializer.h # JSON сериализация
│ │ └── crow/ # Crow framework
│ ├── src/ # Исходные файлы
│ │ └── types.cpp # Реализация Board
│ ├── main.cpp # Точка входа
│ ├── CMakeLists.txt # Конфигурация сборки
│ └── Dockerfile # Docker образ
│
├── frontend/ # Frontend приложение (React)
│ ├── src/
│ │ ├── components/ # React компоненты
│ │ │ └── GameBoard.tsx
│ │ ├── contexts/ # Context API
│ │ │ └── AppContext.tsx
│ │ ├── pages/ # Страницы приложения
│ │ │ ├── CreateGame.tsx
│ │ │ ├── JoinGame.tsx
│ │ │ ├── BuildShip.tsx
│ │ │ └── GamePage.tsx
│ │ ├── service/ # WebSocket сервис
│ │ │ └── GameWebSocket.ts
│ │ ├── types/ # TypeScript типы
│ │ │ └── serverMessages.ts
│ │ └── utils/ # Утилиты
│ │ └── shipUtils.ts
│ ├── package.json # Зависимости
│ └── vite.config.ts # Конфигурация Vite
│
├── nginx/ # Nginx конфигурация
│ ├── nginx.conf # Основной конфиг
│ └── Dockerfile # Docker образ
│
├── docker-compose.yml # Оркестрация сервисов
├── README.md # Этот файл
└── API_EXAMPLES.md # Примеры API
- Каждая
GameSessionзащищена мьютексом - Безопасный доступ к общим ресурсам из разных потоков
- Сессии автоматически удаляются после 30 минут неактивности
- Heartbeat (Ping/Pong) для поддержания соединения
- Поддержка горизонтального масштабирования через sticky-sessions в Nginx
- Каждая сессия независима и может быть распределена между серверами
Проверка работоспособности сервера:
curl http://localhost/healthДолжен вернуть: OK
# Backend контейнер
docker exec -it battleship-backend bash
# Nginx контейнер
docker exec -it battleship-nginx bash# Все логи в реальном времени
docker-compose logs -f
# Только ошибки
docker-compose logs | grep -i errorMIT License
Приятной игры! 🎯⚓