Тест-водитель • Обсуждение задачи • Отправить Авантюрист
Несколько конкурирующих искателей приключений совершают набеги на руины за сокровищами, но они могут нести только столько за раз и имеют свои пределы выносливости. Они хотят получить самое ценное сокровище и уйти, прежде чем они станут слишком уставшими, чтобы продолжать. Они пытаются стать настолько богатыми, насколько это возможно от их грабежей махинаций.
Игровой процесс
Каждый искатель приключений начинается в первой комнате подземелья с 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
получает один аргумент a 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
Это нормально даже при использовании порядка итераций для решений, поскольку порядок гарантированно согласован с Python 3.6.
- Вы не можете обойти тестовый драйвер с помощью
ctypes
хаков илиinspect
стека вуду (или любого другого метода). Есть несколько поразительно страшных вещей, которые вы можете сделать с этими модулями. Пожалуйста, не надо.- Каждый бот достаточно хорошо изолирован в песочнице с помощью защитных копий и естественной неизменности
namedtuple
s, но есть некоторые неуязвимые лазейки / эксплойты. - Другие функциональные возможности
inspect
иctypes
могут использоваться, если ни один из них не используется для обхода функциональности контроллера. - Любой метод захвата экземпляров других ботов в вашей текущей игре не допускается.
- Каждый бот достаточно хорошо изолирован в песочнице с помощью защитных копий и естественной неизменности
- Боты должны работать в одиночку и не могут никоим образом координировать свои действия с любыми другими ботами. Это включает в себя создание двух ботов с разными целями, так что один жертвует собой ради успеха другого. Если у вас более 10 соперников, вам не гарантируется наличие двух ботов в одной и той же игре, а имена авантюристов не дают никаких указаний на класс ботов, поэтому эти типы стратегий в любом случае ограничены.
- В настоящее время нет жестких ограничений по времени выполнения, однако я оставляю за собой право жестко ограничить его в будущем, если турниры начнутся слишком долго. Будьте разумны и старайтесь обрабатывать ходы менее 100 мс , так как я не ожидаю необходимости ограничивать его ниже этого порога. (Турниры начнутся примерно через 2 часа, если на всех ботов потребуется около 100 мс за ход.)
- Ваш класс ботов должен быть назван однозначно среди всех представленных.
- Вы можете не помнить ничего между играми. (Тем не менее, вы можете помнить вещи между поворотами )
- Не редактируйте sys.modules. Все, что находится за пределами переменных экземпляра, должно рассматриваться как константа.
- Вы не можете изменять код любого бота программно, включая ваш собственный.
- Это включает в себя удаление и восстановление вашего кода. Это должно сделать отладку и турниры более упорядоченными.
- Любой код, вызывающий сбой контроллера, будет немедленно дисквалифицирован. В то время как большинство исключений будут обнаружены, некоторые могут проскользнуть, а ошибки могут быть не обнаружены. (Да, вы можете segfault в Python благодаря
ctypes
)
Материалы
Чтобы упростить проверку ответов, укажите имя вашего бота в верхней части ответа с помощью символа a #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 без установленной даты окончания.
Leaderboard
С пробега 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 за полное уничтожение Backwards. Поздравляем!
pip
установили и включили PATH
(что по умолчанию для более новых установок AFAIK), то из окон вы можете запустить pip install modulename
в командной строке. Для других обстоятельств (о которых я не знаю), перейдите в pip , найдите нужный модуль и выберите опцию.