Pokerowa twarz
Wprowadzenie
Leo lubi grać w pokera, ale jego praca w Tech Inc. jest zbyt wymagająca, aby nauczył się dobrze grać. Leo, jako informatyk, nie jest zniechęcony. Postanawia poświęcić więcej czasu niż na naukę pokera i użyć go do napisania pokerowego bota, który pomoże mu lepiej grać. Ale teraz Leo ma problem: aby zrozumieć, jak grać nieco lepiej, Leo musi obserwować wiele gier wielu „ludzi”, ale „ludzie” potrzebują różnych stylów gry, aby poprawić jakość i rzeczywistość gry.
Wyzwanie
Leo przypomina, że istnieje strona internetowa poświęcona wyzwaniom programistycznym i pozyskuje waszą pomoc! Twoim zadaniem jest napisanie programu, który gra w „Pokerface” zmodyfikowaną wersję pokera na 5 kart. Program pobierze dane jako 5-kartowe rozdanie w dowolnym formacie, po którym program wyświetli:
- Dokładnie (z rozróżnieniem małych i wielkich liter) „prawda” „1” lub „t”, jeśli gracz chce wymienić karty, w przeciwnym razie inne niepuste dane wyjściowe.
- Jeśli to prawda, lista wskaźników kart i / lub nazw kart, które gracz chce wymienić.
- Pojedyncza liczba od 0 do 3, która określa, ile dodatkowych kart chce gracz.
- Wydrukuj rękę, której gracz chce użyć.
(Zobacz formatowanie poniżej)
Zasady Pokerface
- Ponieważ pokerface jest tekstową grą przygodową, karty muszą być prezentowane w spójny sposób. Karty są reprezentowane przez dwa kody znaków, pierwszy znak to kolor, a drugi to nazwa karty.
- Karty:
- 2-9 = 2-9
- 10 = T
- Jack = J
- Królowa = Q
- King = K
- As = A
- Garnitury:
- Pik = S
- Kluby = C
- Kierki = H
- Diament = D
- Karty:
Tak więc as pik to SA, 10 kier to HT, czwarty karo to D4 itd.
- Pojedyncza runda Pokerface składa się z czterech kroków:
- Talia zostaje przetasowana i każdemu graczowi rozdaje się pięć kart.
- Każdy gracz ma szansę wymienić tyle kart, ile chce.
- Każdy gracz ma szansę na uzyskanie do trzech kolejnych kart.
- Każdy gracz musi ujawnić swoją najlepszą rękę.
- Najlepsza ręka wygrywa i zdobywa punkt. W przypadku remisu obaj gracze otrzymują punkt.
- W jednej grze rozgrywanych jest dziesięć rund, a gracz z największą liczbą punktów wygrywa i zdobywa pojedynczy „punkt wygranej”. W przypadku remisu obaj gracze zyskują punkt wygranej.
- Leo tak naprawdę nie ma dużych pieniędzy, więc twój bot może założyć, że jest to idealny świat bez zakładów.
Ręce
- Ręce mają dokładnie 5 kart długości (początkowe wejście i końcowe wyjście).
- Układy rąk są uszeregowane zgodnie z zasadami opisanymi tutaj .
Wejście wyjście
- Leo zna tylko Javę, więc twój program musi być wykonywalny poprzez Process API (wiersz poleceń) i używaj STDIN i STDOUT odpowiednio dla wejścia i wyjścia.
- Dla każdego kroku wejścia i wyjścia wyszczególnionego powyżej, dane wejściowe i wyjściowe muszą istnieć w jednym wierszu.
- Po końcowym wyjściu musi być co najmniej jeden końcowy nowy wiersz. (Jest to spowodowane sposobem odczytu danych wejściowych ze STDIN)
- Nie jest dozwolone żadne zewnętrzne wejście / wyjście, inne niż spacje końcowe i wiodące. Analizator składni po prostu nie rozumie rzeczy takich jak
final_hand=...
lubdraw 0
. - Podczas losowania, wyjście jest pojedynczą liczbą całkowitą, podczas wymiany wyjścia jest lista liczb całkowitych i / lub kart zdefiniowanych poniżej, a gdy jest rozdawana oryginalna ręka, wyjście jest listą kart zdefiniowanych poniżej.
- Wszystkie liczby wejść / wyjść muszą być dodatnimi liczbami całkowitymi w bazie 10.
- Możesz zdefiniować format wprowadzania karty (patrz format postu poniżej).
- Prawda jest zdefiniowana jako dokładnie „prawda”, „1” lub „t”, a fałsz oznacza każdą inną niepustą wartość.
- Podczas etapu wymiany:
- Wskaźniki kart muszą być wyprowadzane z przynajmniej jedną spacją między nimi (np.
3 4 0
) - Nazwy kart muszą być wyprowadzane z przynajmniej jedną spacją między nimi (np.
H4 S8
) - Nazwy kart i wskaźniki mogą być mieszane w danych wyjściowych (np.
0 H7 3 D3
) - Dozwolone są spacje końcowe i wiodące.
- Dane wejściowe w wyniku wyprowadzenia przez odtwarzacz powyższych danych zostaną sformatowane zgodnie z
bot.jlsc
plikiem, w takiej samej kolejności, jak żądana
- Wskaźniki kart muszą być wyprowadzane z przynajmniej jedną spacją między nimi (np.
- Liczba kart, które gracz chce dodać do ręki, może mieć spacje wiodące i końcowe.
- Ręce muszą być wyprowadzane z przynajmniej jedną spacją między nimi (np.
H4 D5 CA
), Dozwolone są spacje końcowe i spacje wiodące. - Ręce nie muszą być wydawane w odpowiedniej kolejności (np.
H4 D4 C4 DA SA
IH4 DA D4 SA C4
oba reprezentują 4, 4, 4, as, as, czyli fula). - Jeśli chcesz zbudować strategię, analizując ręce przeciwników, możesz przechowywać dane w
<botname>/data
katalogu.- Po wyświetleniu rąk konkurujących botów zostaną one zapisane w każdym katalogu danych botów, w pliku hands.txt, z każdą ręką w nowej linii (oddzielone znakiem \ n). Plik zostanie zakodowany w US_ASCII.
- Po tym, jak bot poprosi o nowe karty lub wymieni karty, zostaną one wprowadzone w zależności od formatu określonego w
bot.jlsc
pliku.
Format postu
- Każdy post musi zawierać dwie rzeczy:
- Kod źródłowy twojego bota lub link do publicznego repozytorium.
- Plik zip zawierający:
- Skompilowana / wykonywalna wersja bota (jeśli plik jest w formacie .exe lub innym pliku, którego nie można skompilować, proszę zamieścić w swoim poście instrukcje dotyczące kompilacji).
bot.jlsc
Plik, patrz poniżej (dygresja: rozszerzenie .jlsc to właśnie z powodu projektu bocznej kopalni formacie konfiguracji poniższy plik dopasowania właściwego składni, więc nie martw się.).
- Plik .zip musi mieć taką samą nazwę jak bot.
- Jeśli nie masz dostępu do systemu Windows lub innego narzędzia do kompresowania lub z dowolnego powodu nie możesz utworzyć pliku .zip, po prostu dołącz tekst pliku bot.jlsc do swojego postu
plik 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}"
Gdzie:
- „cmd” to komenda systemu Windows służąca do uruchamiania bota. Zauważ, że twój bot będzie w katalogu
<botname>
, więc odpowiednio dostosuj polecenie. - „name” to nazwa twojego bota.
- „link” to link do Twojej odpowiedzi, którą musisz edytować po opublikowaniu.
- „input_hand” to sposób, w jaki chcesz sformatować pierwotne rozdanie ($ {#} reprezentuje karty 0-4).
- „input_1” to sposób, w jaki chcesz sformatować wejście jednej dodatkowej karty.
- „input_2” to sposób, w jaki chcesz sformatować wejście dwóch dodatkowych kart.
- „input_3” to sposób, w jaki chcesz sformatować wejście trzech dodatkowych kart.
- „input_4” to sposób, w jaki chcesz sformatować wejście czterech dodatkowych kart.
Specyfika
- Luki te są niedozwolone (patrz „częste pułapki”)
- Nie możesz napisać bota, zawsze wyda najlepszą możliwą rękę, za każdym razem, w zestawie reguł. (tj. bez długich botów typu brute-force, nic nie powinno być tak „dobre” jak LeoBot)
- Twój bot powinien działać w ~ 100 ms lub mniej (Łagodny w tym punkcie, maksymalnie ~ 1 sekunda)
- Każde wyjście bota po wybranej ręce zostanie zignorowane.
- Standardowe luki są niedozwolone.
- Tak, wiem, że Linux jest lepszy, ale mam komputer z systemem Windows, więc upewnij się, że skompilowaną / wykonywalną wersję programu można uruchomić z wiersza poleceń systemu Windows.
- Mam już Pythona i Javę zainstalowanych na moim komputerze, ale jestem gotów aktualizować do nowych wersji i instalować inne środowiska, więc proszę określić, jakiego rodzaju środowiska wymaga Twój program.
- Nie możesz napisać bota, który w każdym przypadku robi to samo, co inny bot. Spoty są dozwolone, ale odradzane.
- Twój bot może używać tylko posiadanych kart. Karty utracone w wyniku wymiany lub nieprzedstawione na początku są nieprawidłowym wyjściem w ostatnim rozdaniu.
- Dane wejściowe i wyjściowe mogą zawierać tylko znaki ASCII.
Turnieje
- Turnieje będą się odbywać, kiedy będę miał czas (mój harmonogram jest prawie tak napięty jak Leo, więc to będzie trochę rzadkie. Przepraszam za niedogodności.)
- Boty będą rywalizować ze sobą w grach 4-osobowych, i będzie jedna gra dla każdego możliwego podzbioru botów (tj. Wiele gier).
- Proces ten zostanie powtórzony pięć razy.
- Ze względu na sposób, w jaki przewodnik turniejowy tworzy grupy botów, zostaną dodane maksymalnie trzy boty wypełniające, aby liczba botów była podzielna przez 4. Boty te po prostu zwrócą rękę, w której zostały pierwotnie rozdane.
- Po każdej rundzie i uruchomieniu gry wyniki botów będą obliczane na podstawie liczby wygranych gier.
- Wiele botów może dzielić pozycję (remisy dla pierwszego wygranego przez pierwszego wysłanego).
- Po zakończeniu turnieju wyniki zostaną dodane na dole tego postu.
Punktacja
Normalne reguły KoTH. Bot (y), który wygra najwięcej gier, wygrywa wyzwanie.
LeoBot
Bot Leo jest całkiem sprytny. Nie wymienia żadnych kart, co jest zbyt trudne, ale żąda maksymalnej liczby dodatkowych kart i określa najlepszą możliwą rękę, którą może wykonać, i zagrywa tę rękę. Główna logika leobota znajduje się poniżej.
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;
}
}
Pamiętaj, że jeśli LeoBot konsekwentnie wygrywa turnieje, a liczba zgłoszeń jest spora, przestanę włączać go do biegania.
Ważne linki
Zrzeczenie się
Leo i Tech Inc. to elementy fabularne, a wszelkie podobieństwo do prawdziwych firm lub ludzi jest całkowicie niezamierzone. (Jednak gdy „sytuacja” Leo dodaje lub odejmuje warunki od pytania, są one faktycznie częścią pytania ...)
źródło
"f"q+
spełnia minimalne wymagania. Jeśli w zawodach bierze udział 10 osób, to prawdopodobnie pokonuje wszystkie niemądre wpisy (nie-głupie wpisy prawdopodobnie mają> 75 znaków, 5 * 10 (wynik głupiego bota, nadchodzi ostatni) = 50 <75 (wynik bardzo małego inteligentnego bota (pierwsze miejsce))). Dlatego prawdopodobnie powinieneś usunąć codegolfa z tego wyzwaniaOdpowiedzi:
(Python), Pairbot, niezbyt konkurencyjny (nie wiem, jak tworzyć polecenia cmd i takie tam)
Pairbot będzie konkurował, gdy tylko ktoś pomoże przy pomocy bot.jlsc, plików zip itp.
Pairbot wie, że nie zawsze masz dobre ręce. Wie, że dobre ręce są rzadkie. Pairbot wie, że pary i inne duplikaty to jedne z najlepszych układów. Pairbot również wie, że najniższa ręka, którą możesz zdobyć, to siedem high, więc wie, że jeśli ma 6 high, to właściwie strita (pairbot nie wie, dlaczego to wie). Wie również, że jeśli jego najniższa karta to 10 (bez par), to także strit (pairbot wie, że może w ten sposób uzyskać kolor królewski). Pairbot sprawdza głównie duplikaty tej samej liczby, ale także sprawdza dwa typy prostych w szczególnych przypadkach.
Format wejściowy jest taki sam jak w przykładzie: oddzielone spacjami
Gdyby Socratic Phoenix mógł pomóc z plikami, byłoby dobrze
źródło
Hydraulik, Python
W hydrauliku chodzi o kolory. Hydraulik również traktuje priorytetowo karty o wyższej wartości (co oznacza, że czasami może uzyskać pokera, szczególnie królewskiego (jeśli się pojawią)). Hydraulik jest w bardzo złym stanie, jeśli nie dostanie koloru, z tym wyjątkiem, że może mieć szczęście do strita. Hydraulik dostanie uderzeń gorąca w około 20% przypadków, jeśli obliczenia Sherlock9 są prawidłowe
Również pobiera dane wejściowe oddzielone spacjami, tak jak inne moje dwa boty
źródło
LadyGaga, Python 3
I od czasu do czasu lubi grać w Poker Face
źródło
def V(A): b=[A[0]];c=A[1] if c=='T':c=10 if c=='J':c=11 if c=='Q':c=12 if c=='K':c=13 if c=='A':c=14 return (b + [int(c)])
dox={"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,"T":10,"J":11,"Q":12,"K":13,"A":14,} def V(A):return(A[0] + x[A[1]])
LuckyBot, Python
Pairbot zaprosił swojego kumpla Luckybota, który skoczył na okazję. Luckybot oglądał dużo fikcyjnego pokera i stwierdził, że odkrył sekret pokera: szczęście. Wszyscy wiedzą, że prawdziwi profesjonaliści (na przykład James Bond) naprawdę polegają i mają dobre ręce, a nie umiejętności. Dlatego nie patrzy na swoje karty i próbuje włożyć w nie tyle szczęścia, ile to możliwe
źródło