Морда кирпичом
Вступление
Лео нравится играть в покер, но его работа в Tech Inc. слишком сложна, чтобы научиться хорошо играть. Лев, будучи специалистом по информатике, не унывает. Он решает потратить больше времени, чем просто учиться покеру, и использовать его, чтобы написать покерного бота, чтобы помочь ему играть лучше. Но теперь у Лео есть проблема: чтобы понять, как играть немного лучше, Лео нужно наблюдать за несколькими играми нескольких «людей», но «людям» нужны разные стили игры, чтобы улучшить качество и реальность игры.
Соревнование
Лео вспоминает, что на самом деле есть сайт, посвященный программированию, и заручается вашей помощью! Ваша задача - написать программу, которая играет в «Pokerface» модифицированную версию 5-карточного покера. Программа примет ввод в виде 5-карточной раздачи в любом формате, который вы пожелаете, после чего программа выведет:
- Точно (с учетом регистра) "true", "1" или "t", если игрок хочет обменять карты, любой другой непустой вывод в противном случае.
- Если это правда, список индексов карт и / или названий карт, которые игрок хочет обменять.
- Одно число от 0 до 3, которое указывает, сколько дополнительных карт хочет игрок.
- Распечатайте руку, которую игрок хочет использовать.
(См. Форматирование ниже)
Правила покера
- Поскольку pokerface - это текстовая приключенческая игра, карты должны быть представлены в согласованном порядке. Карты представлены двумя кодами символов, первый символ - масть, а второй - название карты.
- Карты:
- 2-9 = 2-9
- 10 = Т
- Джек = J
- Королева = Q
- Кинг = К
- Ace = A
- Костюмы:
- Пики = S
- Клубы = C
- Hearts = H
- Алмаз = D
- Карты:
Таким образом, пиковым тузом будет SA, 10 червей - HT, 4-й бриллиант - D4 и т. Д.
- Один раунд Pokerface состоит из четырех этапов:
- Колода перетасовывается, и каждому игроку раздается пятикарточная комбинация.
- Каждому игроку предоставляется возможность обменять столько карт, сколько они захотят.
- Каждому игроку предоставляется возможность получить еще три карты.
- Каждый игрок должен показать свою лучшую руку.
- Лучшая рука выигрывает и получает этому игроку очко. В случае ничьей оба игрока получают очко.
- В одной игре разыгрывается десять раундов, и игрок, набравший наибольшее количество очков, выигрывает и получает одно «очко победы». В случае ничьей оба игрока получают выигрышное очко.
- У Лео на самом деле нет большой суммы денег, поэтому ваш бот может предположить, что это идеальный мир без ставок.
Руки
- Руки составляют ровно 5 карт (начальный ввод и окончательный вывод).
- Руки ранжируются в соответствии с правилами, описанными здесь .
Ввод, вывод
- Лев знает только Java, поэтому ваша программа должна быть исполняемой через Process API (командную строку) и использовать STDIN и STDOUT для ввода и вывода соответственно.
- Для каждого шага ввода и вывода, описанного выше, вход и выход должны находиться в одной строке.
- После окончательного вывода должна быть хотя бы одна завершающая новая строка. (Это связано со способом чтения ввода из STDIN)
- Никакой посторонний ввод / вывод не допускается, кроме конечных и начальных пробелов. Парсер просто не понимает таких вещей, как
final_hand=...
илиdraw 0
. - При рисовании выводом является одно целое число, когда обмен выводом представляет собой список целых чисел и / или карт, определенных ниже, а при раздаче исходной руки, вывод представляет собой список карт, определенных ниже.
- Все числа ввода / вывода должны быть положительными целыми числами в базе 10.
- Вы можете определить формат для ввода карты (см. Формат сообщения ниже).
- True определяется как «true», «1» или «t», а false - это любое другое непустое значение.
- На этапе обмена:
- Индексы карт должны быть выведены с хотя бы одним пробелом между ними (например
3 4 0
) - Имена карт должны быть выведены с хотя бы одним пробелом между ними (например
H4 S8
) - Имена карт и индексы могут быть смешаны в выводе (например
0 H7 3 D3
) - Трейлинг и ведущие пробелы разрешены.
- Ввод данных в результате вывода проигрывателем вышеупомянутого будет отформатирован, как указано в
bot.jlsc
файле, в том же порядке, что и запрошенный
- Индексы карт должны быть выведены с хотя бы одним пробелом между ними (например
- Количество карт, которые игрок хочет добавить в свою руку, может иметь пробелы в начале и в конце.
- Руки должны быть выведены, по крайней мере, с одним пробелом между ними (например
H4 D5 CA
), допускаются завершающие пробелы и начальные пробелы. - Руки не должны быть выведены в правильном порядке (например,
H4 D4 C4 DA SA
иH4 DA D4 SA C4
обе представляют 4, 4, 4, туз, туз, который является фулл-хаусом). - Если вы хотите построить стратегию, анализируя руки оппонентов, вы можете хранить данные в
<botname>/data
каталоге.- После того, как конкурирующие боты отобразят свои руки, они будут записаны в каждый каталог данных ботов, в hands.txt, с каждой рукой в новой строке (разделенной \ n). Файл будет закодирован в US_ASCII.
- После того, как ваш бот запросит новые карты или обменные карты, карты будут введены в зависимости от того, какой формат вы указали в
bot.jlsc
файле.
Формат сообщения
- Каждый пост должен включать две вещи:
- Исходный код вашего бота или ссылка на общедоступный репозиторий.
- ZIP-файл, содержащий:
- Скомпилированная / исполняемая версия вашего бота (если это файл .exe или другой некомпилируемый файл, пожалуйста, просто включите инструкции по компиляции в ваш пост).
bot.jlsc
Файл, смотрите ниже (сторона примечание: .jlsc расширение только из сайд - проекта шахты, формат конфигурации Файл ниже спичек правильный синтаксис, так что не беспокойтесь.).
- Файл .zip должен называться так же, как ваш бот.
- Если у вас нет доступа к окнам или какой-либо другой утилите архивации, или вы по какой-либо причине не можете создать .zip, просто включите в свой пост текст файла bot.jlsc.
файл bot.jlsc:
name= "Botty"
link= "example.com"
cmd= "java -jar Botty.jar"
input_hand= "${0} ${1} ${2} ${3} ${4}"
input_1= "${0}"
input_2= "${0} ${1}"
input_3= "${0} ${1} ${2}"
input_4= "${0} ${1} ${2} ${3}"
Где:
- «cmd» - это команда командной строки Windows для запуска вашего бота. Обратите внимание, что ваш бот будет в каталоге
<botname>
, поэтому настройте команду соответствующим образом. - «name» - это имя вашего бота.
- "ссылка" - это ссылка на ваш ответ, вам нужно будет отредактировать ее после публикации.
- «input_hand» - это то, как вы хотите, чтобы оригинальная раздача была отформатирована (с $ {#}, представляющим карточки 0-4).
- «input_1» - это то, как вы хотите отформатировать ввод одной дополнительной карты.
- «input_2» - это способ форматирования ввода двух дополнительных карточек.
- «input_3» - это способ форматирования ввода трех дополнительных карточек.
- «input_4» - это способ форматирования ввода четырех дополнительных карточек.
конкретика
- Эти лазейки запрещены (см. «Общие ловушки»)
- Вы не можете написать бота, который всегда будет выдавать лучшую возможную руку, каждый раз, в пределах набора правил. (т.е. никаких длительных ботов-ботов, ничто не должно быть столь же «хорошим», как LeoBot)
- Ваш бот должен работать в течение ~ 100 мс или меньше (в этот момент не более 1 секунды)
- Любой вывод бота после выбранной руки будет игнорироваться.
- Стандартные лазейки запрещены.
- Да, я знаю, что Linux лучше, но у меня Windows-ПК, поэтому убедитесь, что скомпилированную / исполняемую версию вашей программы можно запустить из командной строки Windows.
- На моем компьютере уже установлены python и java, но я хочу обновиться до новых версий и установить другие среды, поэтому, пожалуйста, укажите, какой тип среды требует ваша программа.
- Вы не можете написать бота, который делает то же самое, что и другой бот в каждом случае. Спам-боты разрешены, но не приветствуются.
- Ваш бот может использовать только те карты, которые у него есть. Карты, утерянные в результате обмена или не сданные для начала, являются недействительными на выходе в последней раздаче.
- Вход и выход могут содержать только символы ASCII.
Турниры
- Турниры будут проводиться, когда у меня будет время (мое расписание почти такое же плотное, как у Лео, так что это может быть немного нечастым. Приносим извинения за неудобства.).
- Боты будут противостоять друг другу в играх на 4 человека, и будет по одной игре на каждое возможное подмножество ботов (то есть множество игр).
- Этот процесс будет повторяться пять раз.
- Из-за способа, которым обработчик турнира формирует группы ботов, будет добавлено до трех ботов-наполнителей, чтобы количество ботов делилось на 4. Эти боты просто вернут руку, с которой они были изначально разыграны.
- После каждого раунда и запуска игры очки ботов будут рассчитываться на основе количества выигранных игр.
- Множество ботов могут разделять позиции (связи для первого победителя с первым опубликованным).
- После окончания турнира результаты будут добавлены в конец этого поста.
счет
Нормальные правила KoTH. Бот (ы), которые выигрывают в большинстве игр, выигрывают вызов.
LeoBot
Бот Лео довольно умен. Он не обменивает карты, это слишком сложно, но он запрашивает максимальное количество дополнительных карт, определяет наилучшую возможную руку и разыгрывает эту руку. Основная логика леобота ниже.
package com.gmail.socraticphoenix.pokerface.leobot;
import com.gmail.socraticphoenix.pokerface.lib.card.Card;
import com.gmail.socraticphoenix.pokerface.lib.card.Deck;
import com.gmail.socraticphoenix.pokerface.lib.rule.HandRegistry;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class LeoBot {
public static void main(String[] args) {
List<Card> hand = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
hand.addAll(Card.parseHand(scanner.nextLine()));
System.out.println(false);
System.out.println(3);
hand.addAll(Card.parseHand(scanner.nextLine()));
List<List<Card>> possibleHands = LeoBot.getSubsets(hand, 5);
System.out.println(Deck.toString(possibleHands.stream().sorted((a, b) -> HandRegistry.determineWinner(b, a).comparable()).findFirst().get()));
}
private static <T> void getSubsets(List<T> superSet, int k, int idx, List<T> current, List<List<T>> solution) {
if (current.size() == k) {
solution.add(new ArrayList<>(current));
return;
}
if (idx == superSet.size()) return;
T x = superSet.get(idx);
if (!current.contains(x)) {
current.add(x);
}
getSubsets(superSet, k, idx + 1, current, solution);
current.remove(x);
getSubsets(superSet, k, idx + 1, current, solution);
}
public static <T> List<List<T>> getSubsets(List<T> superSet, int k) {
List<List<T>> res = new ArrayList<>();
getSubsets(superSet, k, 0, new ArrayList<T>(), res);
return res;
}
}
Обратите внимание, что если LeoBot постоянно выигрывает турниры, и в нем много призов, я перестану включать его в забег.
Важные ссылки
отказ
Leo и Tech Inc. являются элементами истории, и любое сходство с реальными компаниями или людьми является чисто непреднамеренным. (Однако, когда «ситуация» Лео добавляет или вычитает условия из вопроса, они фактически являются частью вопроса ...)
"f"q+
удовлетворяет минимальным требованиям. Если в соревновании участвуют 10 человек, это, вероятно, превосходит все нематериальные записи (в нематурной записи, вероятно,> 75 символов, 5 * 10 (оценка немого бота, идущего последним) = 50 <75 (оценка очень маленького умного бота). (впереди))). Таким образом, вы, вероятно, должны удалить Codegolf из этого испытания