Окончательные результаты доступны
Введение
После моего предыдущего KOTH с тяжелыми темами ( фэнтезийная война , всемирная пандемия ...) я вернулся с новой беззаботной игрой. На этот раз вы столкнулись с ситуацией, похожей на настольную игру. Куча перевернутых монет находится в центре действительно большого стола, и вы полны решимости получить свою долю в луте!
глоссарий
Монеты : жетоны, которые можно перевернуть или раскрутить.
Безразлично : монеты, размещенные на столе, их ценность направлена вниз. Это состояние монет по умолчанию.
Перевернутый : монеты, размещенные на столе, с указанием их значения вверх.
Местный : Относится к вашей куче монет.
Глобальный : относится к куче монет в центре.
Принцип
В начале игры каждый игрок начинает игру с 0 очками и 0 монетами (перевернутыми или не перевернутыми). Игра пошаговая. В течение своего хода игроки могут выполнять до 3 действий, взаимодействуя либо с кучей монет в центре стола, со своей кучей монет или с другими игроками.
Порядок игры определяется случайным образом в начале игры. Порядок игроков в списке аргументов представляет порядок хода, и он идет слева направо в этом списке. «Далее» и «Предыдущий» означают соответственно «справа в этом списке» и «слева в этом списке» с циклом, если вы последний из обеих сторон.
Игра длится 50 раундов или до тех пор, пока в конце хода игрока не останется 0 монет в центре (это означает, что вы закончите 3 действия, даже если после первого действия колода пуста, и вы можете положить монеты, чтобы игра продолжается). Стартовое число глобальных монет определяется случайным образом по следующей формуле:
(2 ^ nb_players) + (nb_players * 10) - random(1 + (nb_players ^ 2))`
Каждое действие принесет вам очки (или заставит вас потерять часть), и в конце игры каждая ваша монета будет добавлена к вашим очкам ( -1 для не вскрытого, +2 для подброшенного ). Игрок с наибольшим количеством очков побеждает.
Контроллер предоставляет вам ввод через аргументы команды, а ваша программа должна выводить через stdout.
Синтаксис
вход
Каждый раз, когда ваша программа вызывается, она будет получать аргументы в следующем формате:
Round;YourPlayerId;Coins;PlayerId_Points_Flipped_Unflipped;PlayerId_Points_Flipped_Unflipped;...
Раунды 1-индексированы.
Пример ввода
6;2;52;1_20_3_12;0_-2_0_1;2_12_1_0
Здесь вы видите, что это 6-й раунд, и вы являетесь игроком 2. В центральной стопке 52 монеты. У вас есть 12 очков, 1 перевернутая монета и 0 не перевернутая монета. Очки могут быть отрицательными.
Выход
Вы должны вывести три символа (без пробела, без разделителя), каждый из которых соответствует одному действию, которое вы выполните в этом ходу. Порядок символов определяет порядок действий. Вы можете выводить одни и те же действия несколько раз. Если для выполнения вашего действия недостаточно монет, он использует максимум доступных монет и подсчитывает баллы только за использованные монеты.
N
: Ничего не делать
1
: Возьмите 1 монету из центральной стопки [Эффекты: +1 локальная безразличная / -1 очко / -1 глобальная безразличная]
2
: Возьмите 2 монеты из центральной стопки [Эффекты: +2 локальная безразличная / -2 пункта / -2 глобальный расколотый]
3
: возьмите 3 монеты из центральной стопки [Эффекты: +3 локального расколота / -3 очка / -3 глобальный расколот]
A
: положите обратно одну монету из стопки [Эффекты: -1 локальный раскрепощен / +1 пункт / +1 глобально развернутый]
B
: положите обратно 2 монеты из своей стопки [Эффекты: -2 локальных не расклинили / +2 очка / +2 глобально развернутый]
C
: отложите 3 монеты из стопки [Эффекты: -3 локально развернуты / +3 балла / +3 глобальный развернутый]
X
: уберите 1 монету из вашей кучи[Эффекты: -1 местный безразличный / 0 очков]
Y
: убрать 2 монеты из своей кучи. [Эффекты: -2 локальных безразличных / 0 очков]
Z
: убрать 3 монеты из своей стопки. [Эффекты: -3 локальных безразличных / 0 очков]
R
: вращать монеты. к предыдущему игроку [Эффекты: -1 очко за полученный полученный переворот, +2 очка за полученный полученный перевернутый / применяется ко всем игрокам]
T
: Повернуть монеты следующему игроку [Эффекты: -1 очко за полученный полученный не перевернутый, +2 очка за полученный перевернутый / применяется к все игроки]
F
: перевернуть 1 монету [Эффекты: -1 местная раскрепощенная / +1 местная перевернутая / +2 очка]
U
: отразить 1 монетку [Эффекты: +1 местная раскрепощенная / -1 местная перевернутая / -2 очка]
Пример вывода
2FF
: Берет две монеты и подбрасывает две монеты, забив -2 + 2 + 2 = 2 points
Если ваш вывод неверен, контроллер примет NNN
.
контроллер
Вы можете найти контроллер на GitHub . Он также содержит два примера ботов, написанных на Java. Чтобы запустить его, проверьте проект и откройте его в вашей среде Java IDE. Точка входа в main
метод класса Game
. Java 8 требуется.
Чтобы добавить ботов, сначала вам потребуется либо скомпилированная версия для Java (файлы .class), либо исходные тексты для интерпретируемых языков. Поместите их в корневую папку проекта. Затем создайте новый класс Java в players
пакете (вы можете взять пример с уже существующими ботами). Этот класс должен быть реализован Player
для переопределения метода String getCmd()
. Возвращаемая строка - это команда оболочки для запуска ваших ботов. Например , вы можете сделать бот работу Ruby , с помощью этой команды: return "C:\Ruby\bin\ruby.exe MyBot.rb";
. Наконец, добавьте бота в массив игроков в верхней части Game
класса.
правила
- Боты не должны быть написаны, чтобы побеждать или поддерживать определенных других ботов.
- Запись в файлы разрешена. Пожалуйста, напишите «yoursubmissionname.txt», папка будет очищена перед началом игры. Другие внешние ресурсы запрещены.
- Ваше представление имеет 1 секунду, чтобы ответить.
- Предоставьте команды для компиляции и запуска ваших представлений.
Поддерживаемые Языки
Я постараюсь поддерживать каждый язык, но он должен быть доступен онлайн бесплатно. Пожалуйста, предоставьте инструкции по установке, если вы не используете основной язык.
На данный момент я могу работать: Java 6-7-8, PHP, Ruby, Perl, Python 2-3, Lua, R, node.js, Haskell, Kotlin, C ++ 11.
Окончательные результаты
Это результаты 100 игр (очки начисляются):
1. BirdInTheHand: 1017790
2. Balance: 851428
3. SecondBest: 802316
4. Crook: 739080
5. Jim: 723440
6. Flipper: 613290
7. Wheeler: 585516
8. Oracle: 574916
9. SimpleBot: 543665
10. TraderBot: 538160
11. EgoisticalBot: 529567
12. RememberMe: 497513
13. PassiveBot: 494441
14. TheJanitor: 474069
15. GreedyRotation: 447057
16. Devil: 79212
17. Saboteur: 62240
Индивидуальные результаты игр доступны здесь: http://pasted.co/63f1e924 (со стартовыми монетами и количеством раундов в игре).
Победителю присуждается награда в 50 репутаций: Bird In The Hand от Мартина Бюттнера .
Спасибо всем за участие, увидимся в следующем КОТ ~
источник
Ответы:
Птица в руке, Рубин
Если ни один из нас не имеет ошибки в своих программах, основной алгоритм этого, вероятно, очень похож на Oracle Матиаса. Исходя из предположения, что до финального раунда мы не можем знать, с какими монетами у нас получится, мы оцениваем текущий набор ходов исключительно на основе полученных немедленно очков, полностью игнорируя, какие монеты мы получим с. Поскольку существует только 14 3 = 2744 возможных наборов ходов, мы можем легко смоделировать их все, чтобы выяснить, сколько очков они принесут.
Однако, если набор ходов заканчивает игру (либо потому, что он уменьшает глобальный банк до нуля, либо потому, что это 50-й раунд, а мы последний ход), то он также учитывает монеты, принадлежавшие в конце набор перемещений для определения значения набора перемещений. Сначала я думал о прекращении игры, когда это возможно, но это привело бы к ужасному ходу,
333
когда в банке осталось всего 9 монет.Если есть несколько наборов ходов, дающих одинаковый результат, мы выбираем случайный. (Я мог бы изменить это на смещение в пользу наборов ходов, заканчивающих игру.)
источник
Oracle, Python 3
Обновление: изменен порядок различных попыток, чтобы предпочитать низкую кучу монет вместо вращений.
Пробует каждый возможный выход и сохраняет тот, который дает максимальное количество очков за этот ход.
источник
deepcopy
]) сложности, сохраняя только соответствующих соседей. Не уверен, как это повлияет на вещи, хотя.filter_neighbors
и изменил ее,invalid_move
чтобы учесть разъяснения в вопросе. Я не могу воспроизвести ошибку, хотя:$ python oracle.py '4;7;2040;8_-28_1_10;9_-43_0_9;2_-10_4_3;6_-24_6_3;0_6_2_12;1_48_3_0;10_21_4_8;5_6_5_1;4_-12_3_7;7_10_1_3;3_1_1_0'
печатаетTTR
Жадный Вращение, Рубин
Это очень похоже на подход ArtOfCode, за исключением того, что он проверяет, от какого соседа мы можем получить больше очков, и он выбирает
C
вместо того,F
чтобы в результате мы получили 3 или более монет после поворота.Написав это, я почти уверен, что лучшим подходом было бы просто жадно выбирать лучший из всех ходов каждый раз, перед вращением, если это возможно, взять (вместо того, чтобы придерживаться фиксированного значения) «отсоединить, повернуть, избавиться» несвязанного "рисунка").
Это также не учитывает неявные баллы, представленные фактически принадлежащими монетами (исходя из предположения, что игра продлится достаточно раундов, и я, скорее всего, не останусь в моих монетах).
источник
Флиппер, Питон 2
Флиппер собирает монеты и пытается превратиться в перевернутый. Флиппер не умный игрок, но пытается играть позитивную роль в игре.
Флипперу просто нужно
python flipper.py <arg>
бежать.источник
SimpleBot, Python 3
SimpleBot, ну, просто. Он разработал одну стратегию, и он собирается придерживаться ее.
Бежать:
где содержимое
main.py
файла:источник
Баланс, Луа
Баланс будет пытаться сохранить баланс в его маркер, сводя к минимуму потери в случае кто - то использует
R
иT
действия против него. Он считает, что этот стиль жизни является истинным и должен применяться к любому, кто не соблюдает баланс подброшенных / раскрепощенных монет, поэтому все близкие к нему будут наказаны, как только они могут потерять очки.Ему нужна следующая команда для запуска:
Где файл balance.lua содержит следующий фрагмент кода:
источник
Дворник, Питон 3
Он пытается убрать беспорядок со всеми этими монетами и положить их обратно в бассейн.
Он пытается вернуть все свои не раскрепленные монеты, если у него есть несколько застрявших перевернутых монет, он их раскроет, и если он избавится от всех своих монет, он получит чью-то еще.
источник
Крук, Р
Бежать:
Rscript Crook.R
По сути, он обменивает свои монеты со своими соседями, только если обмен идет неровно в его пользу. Если никакой выгодный обмен невозможен, то он обменивает монеты с глобальной стопкой таким образом, чтобы сохранить его соотношение без изменений, но генерировать некоторые очки.
Редактировать: я добавил немного глубины к этому боту, заставив его проверять стеки следующего и предыдущего 2 и 3 игроков, а не только следующий, и проверять, в общем, полезно ли вращать это много раз.
2-е редактирование : следуя идее @ MartinBüttner, бот теперь выполняет «RT» или «TR», если это будет выгодно для него больше, чем для его соседей (если я не ошибаюсь в его реализации :)).
источник
RTR
так, чтобы вы дважды получали счет от его монет.Джим, Руби
на основе жадного вращения Мартина Бюттнера .
будет вращаться так или иначе, в зависимости от того, что даст ему наибольшее количество очков по сравнению с лучшим другим игроком. Затем он бросает на быстрые деньги.
источник
TraderBot
Этот бот пытается вращаться всякий раз, когда он получает наибольшее количество очков в этом действии. Если он не может вращаться, то пытается избавиться от незагнутых монет или еще несколько, чтобы изменить их в следующих действиях.
import java.util.List;
открытый класс TraderBot {
Для запуска: просто добавьте его в ту же папку, что и боты по умолчанию, а затем создайте следующий класс
Затем добавьте этот класс в
Player[] players
массив.источник
Wheeler
Уилер рассчитал для него наилучший ход при вращении монет.
источник
Диверсант, Питон 2
Случайность означает, что он, вероятно, не будет саботировать очень хорошо, но позже я думаю, что мне придется подождать, пока «конец» (сколько ходов / монет осталось) и ТОГДА повернутся, после того как я посмотрю на ближайших игроков, которые могут украсть ... на самом деле выполнение только одного поворота кажется действительно плохим, учитывая, что другие люди также могут использовать повороты. Я не думаю, что это будет работать очень хорошо ...
источник
SecondBest, Python 3
Эта программа пройдет через все возможные комбинации из 3 ходов и выберет вторую лучшую.
Потому что, если у вас есть идеальный ход, это, вероятно, ловушка.
Изменить: удаленный закомментированный ввод
Изменить: код печатал случайный законный ход. Теперь он должен возвращать второй лучший результат.
источник
Дьявольский бот
Хотя его продукция составляет только половину числа дьявола, результаты должны быть довольно катастрофическими. Принимая 9 монет за ход, это в конечном итоге истощает кучу монет. Поскольку этот бот никогда не подбрасывает ни одной из монет, которые он берет, это очень плохо для всех, кто сидит рядом с ним, когда происходит вращение (-9 очков за каждый ход, предпринятый этим ботом).
Команда:
python3 devil.py
Я надеюсь сделать несколько настоящих ботов позже.
источник
Помни Меня, Питон 3
Эта программа содержит значительное количество встроенных данных из теста с фиксированным ботом SecondBest.
Он должен узнать о том, какие ходы лучше всего использовать, но он не использует информацию других игроков.
Редактировать: удален ненужный расчет точки
Редактировать: без комментариев игрока
источник