В качестве небольшого личного проекта я хочу создать «черновой» калькулятор для видеоигры, в которую я регулярно играю с друзьями (или, по крайней мере, играл, пока не поступил в учебный лагерь в школе Флэтайрон) под названием «Heroes of the Storm» от Blizzard Entertainment. .

Несмотря на то, что это абсурдно вызывающе, это ставит пару интересных проблем и соображений. Для тех, кто не знаком с этой игрой, скажем, что она принадлежит к жанру игр под названием «MOBA», многопользовательскому стилю игры на боевой арене. В режиме драфта каждая команда (состоящая из пяти игроков в каждой) выбирает из ограниченного набора персонажей — и, поскольку термин драфт подразумевает, что если ваша команда выбирает персонажа, то другая команда не может, и наоборот (гарантируя 10 уникальных выборов). ).

Причина создания калькулятора состоит в том, чтобы определить вероятность выигрыша на основе коэффициента выигрыша каждого персонажа в игре большого размера. У каждого персонажа есть определенный процент выигрыша, от 40% до 60%. Идеальная цель создания этого калькулятора состоит в том, чтобы он рекомендовал статистически выгодные выборы. Если вы смотрели фильм «Moneyball», это сродни созданию команды с использованием саберметрики (или подбору игроков и построению состава на основе статистического анализа), так что все, что я создаю здесь, может быть использовано в будущем для любых программ, которые мне интересны. адаптивные вероятности и статистика.

Немедленно; есть две основные проблемы:

  1. Мои навыки кодирования очень ограничены, и у меня пока нет инструментов для создания этого. Почти наверняка я буду заниматься этим проектом, пока учусь программировать — и это хорошо, это делает этот опыт обучающим.
  2. В дальнейшем придется много заниматься математикой. У каждого персонажа есть свой собственный процент выигрыша в вакууме, и легко просто сказать «выберите персонажа с самым высоким процентом выигрыша». Проблема в том, что по мере сокращения пула персонажей процентное соотношение меняется, потому что некоторые персонажи лучше работают либо с другими персонажами, либо против них. Это означает, что мне придется создать метод, который учитывает и обновляет ВСЕ проценты выигрышей в моей базе данных и таблицах по мере выполнения черновика. Есть популярная карточная игра Hearthstone (тоже от Blizzard), в которой есть статистический калькулятор драфта, так что я могу рассматривать его как модель.
  3. Последняя проблема, с которой я столкнулся на этих выходных, — это отсутствие легкодоступного API (интерфейса прикладного программирования), содержащего данные о выигрышах/проигрышах. Это, пожалуй, самое большое препятствие, поскольку собрать данные самостоятельно практически невозможно, а сортировку/создание моей базы данных придется выполнять каким-то другим способом. К счастью, веб-сайт HOTSLog отслеживает данные о выигрышах и проигрышах (и имеет API, который содержит данные о персонажах, но не содержит записи о выигрышах/проигрышах) и имеет респектабельный размер выборки — около 100 миллионов зарегистрированных игр. К сожалению, он хранится не как полный API, а как таблица HTML, что означает, что мне нужно будет очистить и попытаться проанализировать HTTP.

Однако мощный гем Nokogiri позволяет относительно легко очищать и затем анализировать данные. В моем случае проблема сводилась к изучению синтаксиса и команд, которые он может выполнять.

Итак, вот шаги, которые я предпринял, в основном тестирование для подтверждения концепции через IRB (интерактивную рубиновую оболочку):

  • Во-первых, установите гем nokogiri («установите гем нокогири») — пожалуй, самая простая часть всей этой задачи!
  • Затем нужно было сохранить информацию HTML, полученную с помощью драгоценного камня Nokogiri (используя драгоценный камень open-uri, поскольку это удаленный сайт), в переменную с помощью следующей команды:
require 'Nokogiri'
require 'open-uri' 
page = Nokogiri::HTML(open("https://www.hotslogs.com/Default"))
  • Мы получаем обратно следующее:

  • Да, мы вошли в Матрицу (.tm (?)). Это в принципе непригодно. НО! При ближайшем рассмотрении он работает так, как задумано, и нам просто нужно предпринять дополнительные шаги для анализа необработанного файла. Nokogiri имеет некоторые другие встроенные инструменты анализа, такие как метод .css (каскадная таблица стилей) (или использование метода .xml, расширяемый язык разметки), который позволяет мне получать более конкретные и определенные данные на основе аргумента. Давайте получим данные из тела веб-страниц, используя следующий скрипт:
body = page.css('body')
  • Стало лучше… но по-прежнему слишком много необработанных данных (я не буду публиковать изображение, достаточно сказать, что оно похоже на изображение выше). Нам нужны только данные из таблицы. Чтобы найти именно то, что мне нужно, я проверил веб-сайт в инспекторе, так как, по крайней мере, на данный момент, это быстрее для меня, чем поиск вручную в HTML.

  • Хорошо! Поэтому я ищу только информацию, разделенную (‹div›) под идентификатором «RadGridCharacterStatistics». Скрипт выглядит так:
table = body.css('div#RadGridCharacterStatistics')
  • Хороший! Это отлично работает и убирает все баннеры и постороннюю информацию, оставляя нам одну таблицу, которая нам нужна. Теперь, когда мы получили этот блок данных, мы можем разделить его все в пригодный для использования массив с помощью еще одного процесса:
rows = table.css('tr')

И понятно, что последний (и персонаж с самым низким винрейтом) — это наш последний элемент в массиве (бедный Медив).

Итак, пока эти данные еще не в пригодном для использования состоянии, это то, что я хочу! У нас есть массив HTML-скриптов, каждый из которых представляет собой строку из таблицы веб-сайта. Каждый элемент в строке таблицы также четко помечен (с индексами от 1 до 69), а с помощью инспектора HOTSlog, действующего как способ быстрой и графической интерпретации HTML, я могу продолжать анализировать, пока не получу то, что нужно. Я хочу и нуждаюсь. Как только я завершу этот процесс, я смогу урезать свой код, сделав его более эффективным.

В общем, это были веселые детские шажки к цели. Очевидно, что мои знания слишком ограничены, чтобы создать что-то полезное, но в качестве учебного опыта это было особенно плодотворным.