Skip to content

An example of multiplayer client-server tic-tac-toe game

Notifications You must be signed in to change notification settings

fromanywhere/tic-tac-toe

Repository files navigation

<!doctype html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Документация по игре «Крестики-нолики»</title>
  <style type="text/css">
    code {
        display: block;
        white-space: pre-wrap;
        font-family: monospace;
        border: 1px #aaa solid;
        border-radius: 2px;
        background-color: #f0f0f0;
        padding: 8px;
    }
  </style>
</head>
<body>
    <h1>Цель</h1>
    <p>Написать клиентскую часть приложения «Крестики-нолики» с использованием предоставленного серверного API (<a href="https://ru.wikipedia.org/wiki/API#Web_API">application programming interface</a>)</p>

    <p>Клиент должен реализовывать возможности </p>
    <ol>
        <li>войти в систему</li>
        <li>выйти из системы</li>
        <li>получить список существующих игр, находящихся в состоянии ожидания старта</li>
        <li>создать новую игру с заданными параметрами</li>
        <li>подключиться к существующей игре, находящейся в состоянии ожидания старта</li>
        <li>делать ход на игровом поле</li>
        <li>получать текущий игровой статус</li>
    </ol>

    <h2>Общие принципы и соглашения</h2>
    <p>
    Для реализации описанных возможностей следует использовать предоставленные серверные методы.
    Методы обладают различными параметрами, описанными ниже, используют разные типы запросов и протоколов.
    В случае корректного использования методы возвращают данные, согласно описанной для них документации, иначе возвращают сообщение об ошибке и закрывают соединение.
    </p>

    <p>
    Кодировкой сообщений принимается utf-8.
    Формат данных, используемых для взаимодействия — JSON.
    Данные следует сериализовать в этот формат при отправке запросов на сервер (HTTP-POST, WebSocket). Получаемые с сервера данные также являются корректным JSON, доступным к десериализации.
    </p>

    <p>
    HTTP-запросы имеют следующий фиксированный формат ответа:
    status — может быть успешным (success) или неуспешным (fail)
    В случае, если запрос успешен, кроме поля status возвращается объект data, содержимое которого зависит от запроса и документируется ниже.
    В случае, если запрос неуспешен, кроме поля status возвращается поле message, содержащее описание причины неудачи в текстовом виде.
    </p>

    <p>WebSocket-запросы всегда должны обладать полем command, документированным ниже.</p>

    <p>Точкой входа является http://welovehtml.ru:3000.</p>

    <h2>Протокол взаимодействия</h2>

    <p>При открытии страницы пользователь должен иметь возможность просмотреть существующие на сервере игры, находящиеся в ожидании старта, а также возможность войти в систему под некоторыми учетными данными.
    Весь игровой функционал должен быть доступен только пользователю, осуществившему вход.</p>

    <h3>Вход, сессия и продление сессии</h3>
    <p>Для входа в систему пользователь должен указать желаемое имя, под которым он будет известен другим игрокам.
    В результате отправки желаемого имени на сервер пользователь получает реальное имя (может отличаться от желаемого), а также уникальный идентификатор пользователя, необходимый при последующем взаимодействии с сервером.
    В момент входа пользователя для него создается сессия, в течение которой он имеет право совершать игровые операции. Продолжительность сессии — 3 минуты.
    После завершения сессии пользователь принудительно удаляется из системы, все созданные им игры удаляются, а игры, в которых он принимал участие, завершаются с оповещением других игроков.
    Пользователь имеет возможность продлить сессию, отправив своё текущее реальное имя и идентификатор, еще на 3 минуты. Количество продлений не ограничено.</p>

<code>URL: /login
Протокол: HTTP
Метод запроса: POST
Данные запроса:
login: желаемое имя
[playerId]: идентификатор, опционально
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась
result.data.id: идентификатор пользователя
result.data.name: реальное имя пользователя
result.data.loginTimeout: время, через которое сессия будет завершена, в миллисекундах (3 минуты)</code>

    <h3>Выход</h3>
    <p>Пользователь, обладающий активной игровой сессией, должен иметь возможность её завершить.
    В результате завершения сессии все созданные им игры будут удалены, а игры, в которых он принимал участие, будут завершены с оповещением других игроков.
    Для завершения игровой сессии следует отправить свой идентификатор.</p>

<code>URL: /logout
Протокол: HTTP
Метод запроса: POST
Данные запроса:
playerId: идентификатор пользователя
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась</code>

    <h3>Получение списка игр, находящихся в ожидании старта</h3>
    <p>Пользователь должен иметь возможность получать список игр, как обладая активной игровой сессией, так и в её отсутствие.
    Пользователь, обладающий активной игровой сессией, не должен получать игр, в которые он уже играет или создал.
    Для получения списка игр отправляется запрос без параметров; для получения отфильтрованного списка игр следует передать идентификатор пользователя.</p>

<code>URL: /games
Протокол: HTTP
Метод запроса: GET
Данные запроса:
[playerId]: идентификатор, опционально
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась
result.data.games: список игр, находящихся в ожидании старта.

Каждая игра обладает следующей информацией (полями):
id: уникальный идентификатор игры
players: список игроков, находящихся в игре
maxPlayersCount: максимальное количество игроков
</code>

    <h3>Создание новой игры</h3>
    <p>Пользователь с активной игровой сессией имеет право создать новую игру с набором параметров. Параметры определяют размерность игровой доски и количество игроков.
    Невозможно создать игру без игровых параметров или с некорректными параметрами. Принимается, что размерность доски может быть от 3 до 9 включительно, а количество игроков может быть от 2х до 4х.
    Игра существует до тех пор, пока в ней находится ненулевое количество игроков, а также до тех пор, пока один из игроков не выйдет из игры.
    В случае выхода игрока как из игровой сессии, так и из игры, соединение с другими игроками автоматически обрывается.
    Предполагается, что игрок, создающий игру, должен присоединиться к ней сразу после создания. Автоматического присоединения не происходит. Игрок должен присоединиться к игре в течение не более 2х секунд после создания, иначе игра будет удалена.
    </p>

<code>URL: /create
Протокол: HTTP
Метод запроса: POST
Данные запроса:
playerId: идентификатор пользователя
boardSize: размерность доски
playersCount: количество игроков
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась
result.data.id: уникальный идентификатор игры
</code>

    <h3>Присоединение к существующей игре</h3>
    <p>Пользователь с активной игровой сессией имеет право присоединиться к существующей игре, если она находится в состоянии ожидания старта.
    Формально не запрещено входить в одну игру одним и тем же пользователем дважды, но работоспособность игры при этом не гарантируется, поэтому такого сценария лучше избегать.
    Присоединение к игре реализуется инициализацией WebSocket-соединения, которое остается открытым во время всей игры.
    Игровой процесс описывается передачей данных по этому соединению и реакцией на них. Данные обязаны содержать имя игровой команды и её параметры.
    </p>

    <h4>Данные, передаваемые сервером клиенту:</h4>

    <h5>Запрос хода</h5>
    <p>Сервер уведомляет клиент, что тот имеет право сделать ход, а сервер и остальные игроки будут его ожидать.
    Затем сделанный ход должен быть проверен сервером.</p>

<code>URL: /
Протокол: WebSocket
Данные:
command: MAKEMOVE
token: уникальный токен, обеспечивающий безопасность хода (ход может быть свершен не более одного раза)
board: текущее состояние доски в виде двумерного массива
</code>

    <h5>Уведомление</h5>
    <p>Сервер уведомляет клиент о каком-либо событии, которое клиент обязан показать пользователю</p>

<code>URL: /
Протокол: WebSocket
Данные:
command: NOTIFY
message: произвольная строка
board: текущее состояние доски в виде двумерного массива
</code>

    <h4>Данные, передаваемые клиентом серверу:</h4>

    <h5>Проверка хода</h5>
    <p>После того, как пользователь сделал ход, клиент просит сервер проверить корректность сделанного хода.</p>

<code>URL: /
Протокол: WebSocket
Данные:
command: CHECKMOVE
token: уникальный токен, который до этого был выдан клиенту
x: координаты клетки,
y: в которую ходит пользователь
</code>

    <h5>Проверка игрового статуса (опционально)</h5>
    <p>Клиент может запрашивать сервер дополнительно о текущем статусе игры
    </p>

<code>URL: /
Протокол: WebSocket
Данные:
command: GETSTATUS
</code>

    <h3>Завершение существующей игры</h3>
    <p>Завершение игрового процесса выполняется закрытием соединения. Соединение может быть закрыто как со стороны сервера, так и со стороны клиента. При закрытии соединения следует использовать и обрабатывать коды завершения соединения:
    A CloseEvent is sent to clients using WebSockets when the connection is closed.</p>

<code>1000 — Никто не виноват, закрываем соединение, потому что хотим отключиться (Normal closure; the connection successfully completed whatever purpose for which it was created).
1001 — Сервер решил удалить игру, и дополнительно сообщит причину (The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection).
1003 — Виноват клиент — некорректные параметры запроса (The connection is being terminated because the endpoint received data of a type it cannot accept).
1006 — Соединение оборвалось (кто-то обновил страницу / пропал интернет) (Used to indicate that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected).
</code></body>
</html>

About

An example of multiplayer client-server tic-tac-toe game

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published