Skip to content

DDmitiy/amt_games_test

Repository files navigation

Test assignment for AMT games

Задание

В качестве тестового задания необходимо реализовать процесс Турнира между игроками:

Входные данные:
  • 200 игроков:
    • id = uuid4()
    • name = any
    • power = random.randint(1, 1000)
    • medals = 1000
    • money = 0
  • Турнир
    • Продолжительность турнира 2 минуты
    • Максимальное количество игроков в турнирной группе: 50
    • Игроки формируются в группы по параметру 'power'
Процесс турнира:
  • Все игроки делятся на группы по 50 человек (сортируем пользователей по параметру power и объединяем в группы)
  • Между пользователями происходит соревнование кто больше всего соберет медалей за турнир
  • Игроки выигрывают медали нападая на других игроков
    • результат нападения высчитывается по формуле random.randint(-10, 10)
    • если результат отрицательный нападающий отдает это количество оппоненту
    • если результат положительный нападающий забирает медали у оппонента
  • Требования
    • игрок может нападать на любых игроков
    • игрок должен сделать хотя бы одно нападение за турнир
    • победитель определяется по количеству медалей на конец турнира
  • Ограничения
    • игрок не может нападать чаще чем раз в 5 секунды
    • 2 игрока не могут напасть одновременно на одного игрока
    • 1 пользователь не может напасть дважды на одного и того же игрока
    • игрок не может нападать сам на себя
  • По завершении турнира победителям начисляются награды в зависимости от их места в группе
    • 1 место 300 money
    • 2 место 200 money
    • 3 место 100 money
Backend должен предоставлять API (Может быть дополнено или изменено по вашему усмотрению):
Admin:
  • POST player (name, power, medals, money) - добавляет пользователя
  • GET player (id) - возвращает данные игрока
  • POST tournament (start_timestamp) - начинает турнир
  • GET tournament (id) - возвращает состояние турнирных групп
Game:
  • GET opponent(player_id) - находит пользователя для нападения
  • POST attack(from_player_id, to_player_id) - атака
В результате должно быть:
  • скрипт backend.py
    • Запускает сервер турнира
  • скрипт tournament.py (должен запускаться локально, работает с backend.py)
    • генерирует 200 игроков
    • начинает турнир
    • совершает атаки
    • по завершении турнира выводит список турнирных групп и победителей

Решение

  • В качестве фреймворка для этой задачи был взят aiohttp (пишу на нем в полуторный раз).
  • Для хранения данных, частый доступ к которым не нужен, выбран PostgreSQL.
  • Для кэширования данных турнира и таймеров -- Redis.

Слежение за тем, что турнир идет происходит через while True вотчер за переменной в Redis, у которой указано время жизни. Через такие же переменные реализованы таймеры на тайм-аут нападений (5 секунд). Чтобы два игрока не напали на одновременно на одного и того же создан контекстный менеджер, который при входе создает специальную переменную в Redis, а при выходе -- удаляет. Перед входом в менеджер эта переменная проверяется. Валидные для нападения игроки генерируются списками для каждого игрока и кладутся в Redis по принципу -- все, кто есть в группе, кроме самого себя. При каждои нападении из этого списка удаляется id игрока, на которого оно было совершено, чтобы не напасть на него дважды.

Запуск

Подготовка и запуск основного бэкенда

pipenv install
cp .env_example .env
cp config/config_example config/config

Теперь надо посмотерть и поправить config и .env. Затем следующее:

pipenv run alembic upgrade head
pipenv run python app.py

Теперь можно запустить скрипт, который сымитирует запросы пользователей.

pipenv run python tournament.py

Пример вывода результатов работы tournament.py:

Tournament ended
       RESULTS
Place | Group | Name
  1   |   0   | player-103 | Medals: 1018 | Money: 300
  2   |   0   | player-107 | Medals: 1018 | Money: 200
  3   |   0   | player-151 | Medals: 1013 | Money: 100
  1   |   1   | player-185 | Medals: 1031 | Money: 300
  2   |   1   | player-179 | Medals: 1019 | Money: 200
  3   |   1   | player-148 | Medals: 1017 | Money: 100
  1   |   2   | player-45 | Medals: 1023 | Money: 300
  2   |   2   | player-78 | Medals: 1022 | Money: 200
  3   |   2   | player-29 | Medals: 1018 | Money: 100
  1   |   3   | player-94 | Medals: 1016 | Money: 300
  2   |   3   | player-100 | Medals: 1014 | Money: 200
  3   |   3   | player-186 | Medals: 1014 | Money: 100

About

Test assignment for AMT games

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published