Тест-драйвер • Обговорення викликів • Надіслати авантюриста
Кілька суперників-суперників шукають руїни за скарбами, але вони можуть носити стільки за один раз і мати свої межі витривалості. Вони хочуть дістати найцінніший скарб і вийти, перш ніж стати занадто втомленим, щоб продовжувати. Вони намагаються стати максимально багатими від своїх грабежних шенагіганів.
Ігровий процес
Кожен авантюрист починає в першій кімнаті підземелля з 1000 очками витривалості та 50 кг місця у своєму рюкзаку.
Гра діє по черзі, і всі гравці вирішують свої повороти одночасно. Кожен поворот можна виконати одну з наступних дій:
- Перехід до сусідньої кімнати.
- Переїзд до попередньої кімнати.
- Пропонуйте витримати взяти скарб.
- Киньте скарб.
Переміщення між кімнатами вимагає 10 витривалості, плюс 1 на кожні 5 кг, які зараз знаходяться у вашому рюкзаку, закругленими вгору. Наприклад, авантюрист, який перевозить 3 кг скарбів, потребує 11 витривалості для переміщення, а одному, який перевозить 47 кг, потрібно 20 витривалості для руху.
Для викидання скарбу потрібна 1 витримка незалежно від скинутого скарбу.
Після виходу з руїн гравець більше не обійдеться.
Якщо гравець не може вчинити жодної з цих дій (через дефіцит витривалості чи відсутність скарбів), їхній авантюрист помирає від виснаження, перекидаючи свій затриманий скарб у зайняту зараз кімнату. Аналогічно, якщо гравець намагається здійснити недійсну дію, їх авантюрист буде вбитий замість пастки, що призведе до того ж розсипання скарбів.
Торги
Мінімальна ставка на скарб - 1 витримка на 1 кг, яку важить скарб. Ви також можете запропонувати додаткові бали на витривалість, щоб швидше отримати скарб. Витривалість, яка була запропонована, витрачається незалежно від результату.
У випадку, якщо кілька гравців подають заявку на отримання одного і того ж скарбу, гравець, який зробив ставку найвищий, отримує скарб. Якщо більшість гравців зробили найвищу ставку, жоден із них не отримає скарб.
Умова виграшу
Гравець з найбільшою загальною вартістю скарбів є переможцем. У випадку навряд чи краватки, краватки йдуть до найменшої загальної ваги, потім до найменшої кількості скарбів, потім до вартості найціннішого скарбу, другого найціннішого, третього ... до тих пір, поки краватка не буде розірвана. У майже неможливому випадку, коли в цій точці все ще є нічия, тестовий драйвер каже "накрутити", і переможець тим самим визначається довільно.
У контексті турніру гравці посідають перше місце, отримуючи 10 балів, друге місце з 9 очками, третє місце з 8 балами тощо тощо, а мертві гравці та авантюристи без скарбів набирають 0 балів.
Про Руїни
- Кожна кімната спочатку містить між іскарбів. (Деномер номера)
- Є довільно багато кімнат, обмежених лише витривалістю авантюристів та готовністю досліджувати.
- Кожен скарб матиме грошову вартість (у цілому $) та вагу (у цілому кг).
- Скарби, як правило, є більш цінними та багатими, коли ви заглиблюєтесь у руїни.
- Конкретні формули для отримання скарбів такі: (використовуючи позначення для рулонів з кістки)
- Вага формується спочатку за допомогою формули (мінімум 1)
- Значення скарбу тоді генерується через (де - номер приміщення, а - вага)
Інформація, доступна для гравців
На кожному кроці гравці отримують таку інформацію:
- Кількість номерів, в яких вони зараз перебувають. Це 1-індексований, тому концептуально вихід є в "кімнаті 0"
- Список скарбів, які зараз знаходяться в кімнаті
- Список інших гравців, які також зараз перебувають у номері.
- Ваш поточний інвентар скарбів
- Ваш поточний рівень витривалості
Кодування
Тестовий драйвер можна знайти тут .
Ви повинні реалізувати підклас цього Adventurer
класу:
class Adventurer:
def __init__(self, name, random):
self.name = name
self.random = random
def get_action(self, state):
raise NotImplementedError()
def enter_ruins(self):
pass
Вам потрібно лише перекрити get_action
метод. enter_ruins
проводиться до початку гри, і це ваш шанс підготувати все, що ви хочете, щоб було готове до гри. Вам не потрібно переосмислювати __init__
, і ви насправді не повинні . Якщо ваш __init__
збій, ви будете дискваліфіковані.
get_action
отримує єдиний аргумент, який представляє собою namedtuple
такі поля (у такому порядку, якщо ви віддаєте перевагу деструктуризації):
room
: номер кімнати, в якій ви зараз перебуваєтеtreasures
: список скарбів у кімнатіplayers
: список інших гравців в кімнаті. Ви отримуєте лише ім'я гравця таким чином, тож ви не знаєте, який бот контролює їх чи їхній інвентар / витривалість.inventory
: список скарбів у вашому рюкзакуstamina
: ваш поточний рівень витривалості
Цей об'єкт додатково надає два корисні властивості:
carry_weight
: загальна вага всіх скарбів, які ви носитеtotal_value
: загальна вартість усіх скарбів, які ви носите
В treasures
і inventory
списки містять namedtuple
S з цими атрибутами:
name
: назва скарбу (для косметичних цілей)value
: грошова вартість скарбу в $.weight
: вага скарбу в кг
get_action
повинен повернути одне з наступних значень / моделей:
'next'
або'previous'
перейти до наступної / попередньої кімнати'take', <treasure index>, <bid>
(так, як кортеж, хоча будь-яка послідовність також буде технічно спрацьовувати), щоб подати заявку на скарб за вказаним індексом у списку скарбів кімнати. Обидва аргументи повинні бути цілими числами. Поплавці будуть округлені вниз.'drop', <inventory index>
відкинути віднесений скарб, знайдений за заданим покажчиком. Індекс повинен (природно) бути цілим числом.
Інші обмеження
- Ви можете використовувати лише випадковий екземпляр, наданий вам під час ініціалізації для псевдовипадковості.
- Інше, що могло б ввести недетермінізм поведінки, не дозволяється. Завдання полягає в тому, щоб змусити ботів поводитися однаково, коли їм дають одне і те ж насіння, щоб допомогти у тестуванні нових ботів (та потенційних помилок у драйвері тесту). Тільки космічне випромінювання повинно викликати будь-які відхилення / недетермінізми.
- Майте на увазі, що хеш-коди рандомізовані в Python 3, тому використання
hash
для будь-якого прийняття рішень заборонено.dict
s добре, навіть якщо використовується порядок ітерації для прийняття рішень, оскільки порядок гарантується послідовним з Python 3.6.
- Ви не можете обійти тестовий драйвер, використовуючи
ctypes
хаки абоinspect
стек вуду (або будь-який інший метод). Є кілька вражаючих страшних речей, які ви можете зробити з цими модулями. Будь ласка, не варто.- Кожен бот розміщений з піском у захисних копіях та природній незмінності
namedtuple
s, але є деякі незмінні лазівки / подвиги. - Інша функціональність від
inspect
іctypes
може використовуватися до тих пір, поки жодна з них не використовується для обходу функцій контролера. - Будь-який метод захоплення екземплярів інших ботів у вашій поточній грі не дозволений.
- Кожен бот розміщений з піском у захисних копіях та природній незмінності
- Боти повинні діяти соло і не можуть жодним чином координуватись з будь-якими іншими ботами. Це включає створення двох ботів з різними цілями, так що одна жертвує собою заради успіху іншої. Коли буде більше 10 конкурентів, ви фактично не будете гарантовано мати двох ботів в одній грі, а назви авантюристів не вказують на клас бота, тому такі стратегії все одно обмежені.
- В даний час немає жорсткого обмеження часу виконання, однак я залишаю за собою право жорстко обмежити його в майбутньому, якщо турніри почнуть тривати занадто довго. Будьте розумні і намагайтеся тримати обробку повороту менше 100 мс , оскільки я не передбачаю, що потрібно обмежувати її нижче цього порогового значення. (Турніри триватимуть приблизно через 2 години, якщо всі боти займають близько 100 мс на обороту.)
- Ваш клас бота повинен бути названий однозначно серед усіх матеріалів.
- Ви можете нічого не пам’ятати між іграми. (Однак ви можете запам'ятати речі між поворотами )
- Не редагуйте sys.modules. Все, що знаходиться за межами змінних екземплярів, слід розглядати як константу.
- Ви не можете змінювати код будь-якого бота програмно, включаючи свій власний.
- Сюди входить видалення та відновлення коду. Це робить налагодження та турніри більш спрощеними.
- Будь-який код, який викликає збій контролера, буде негайно дискваліфікований. Незважаючи на те, що буде вилучено більшість винятків, деякі можуть проскочити, і segfault не можна побачити. (Так, ви можете сегментувати в Python завдяки
ctypes
)
Подання
Для того, щоб допомогти зібрати відповіді, вкажіть ім’я вашого бота вгорі відповіді з а #Header1
та переконайтеся, що ваша відповідь містить принаймні один блок коду (буде використовуватися лише перший у вашій відповіді). Вам не потрібно включати жодних імпортів або документів, оскільки вони будуть додані скребком автоматично.
Я буду більше схильний приймати відповіді з детальними та зрозумілими поясненнями. Інші, ймовірно, поводяться так само.
Грубо кажучи, ваша відповідь має бути відформатована приблизно так:
# Name of Bot
Optional blurb
#imports go here
class BotName(Adventurer):
#implementation
Explanation of bot algorithm, credits, etc...
(надано як)
Ім'я Бота
Необов’язкове розмиття
#imports go here class BotName(Adventurer): #implementation
Пояснення алгоритму бота, кредитів тощо ...
Запуск тест-драйвера локально
Вам знадобиться Python 3.7+ і я рекомендую також встановити tabulate
через pip. Скреблінг цієї сторінки для подання додатково вимагає lxml
і requests
. Для найкращих результатів слід також використовувати термінал з підтримкою кольорових кольорів ANSI. Інформацію про те, як налаштувати це в Windows 10, можна знайти тут .
Додайте бота до файлу у підкаталозі у тому самому каталозі, що і ruins.py
( ruins_bots
за замовчуванням) та обов’язково додайте from __main__ import Adventurer
у верхній частині модуля. Це додається до модулів, коли скрепер завантажує вашу заявку, і хоча це, безумовно, хакі, це найпростіший спосіб переконатися, що ваш бот має належний доступ доAdventurer
.
Усі боти в цьому каталозі будуть завантажуватися динамічно під час виконання, тому подальших змін не потрібно.
Турнір
Кінцевий переможець визначатиметься в серії ігор з до 10 ботів у кожній грі. Якщо подано більше 10 заявок, то 10 найпопулярніших ботів визначатимуться систематичним розподілом їх на групи по 10, поки кожен бот не зіграв (рівно) 20 ігор. 10 кращих ботів будуть обрані з цієї групи з результатами перезавантаження та будуть грати в ігри, поки бот на першому місці не досягне 50-кратного переваги над ботом на другому місці або до того часу, поки не буде проведено 500 ігор.
Поки не буде щонайменше 10 заявок, порожні слоти заповнюватимуться "П’яниці", які блукають навмання руїнами та беруть (а іноді і скидають) випадкові скарби, поки не вичерпається витримка і не доведеться до виходу.
Турніри будуть повторюватися щотижня, якщо з’являться нові подання. Це відкрите завдання KOTH без встановленої дати закінчення.
Таблиця лідерів
З запуску 4 травня 2019 року о 16:25 MDT: (2019-05-04 4:25 -6: 00)
Seed: K48XMESC
Bot Class | Score | Mean Score
--------------+---------+--------------
BountyHunter | 898 | 7.301
Scoundrel | 847 | 6.886
Accountant | 773 | 6.285
Ponderer | 730 | 5.935
Artyventurer | 707 | 5.748
PlanAhead | 698 | 5.675
Sprinter | 683 | 5.553
Accomodator | 661 | 5.374
Memorizer | 459 | 3.732
Backwards | 296 | 2.407
Оновлення - 15 квіт.: Пара оновлення / уточнення правила
Оновлення - 17 квітня: заборона декількох помітних крайових випадків таких негідних дій, як зміна коду інших ботів.
Оновлення - 4 травня: Баунті присуджений Sleafar за те, що він абсолютно знищив назад. Вітаємо!
pip
встановили і ввімкнено PATH
(що за замовчуванням для нових установок AFAIK), тоді з Windows ви можете запустити pip install modulename
командний рядок. Для інших обставин (про які я не знаю), перейдіть на піп , шукайте потрібний модуль і виберіть варіант.