Poker yüzü
Giriş
Leo poker oynamaktan hoşlanır, ancak Tech Inc.'deki işi onun nasıl iyi oynayacağını öğrenmesi için çok talep eder. Bilgisayar bilimcisi olan Leo, cesaretini kırmadı. Sadece pokeri öğrenmek için gerekenden daha fazla zaman almaya karar verir ve daha iyi oynamasına yardımcı olmak için bir poker botu yazmak için kullanır. Ama şimdi Leo'nun bir sorunu var: Biraz daha iyi oynamayı anlamak için Leo'nun birden fazla "insan" ın birden fazla oyununu gözlemlemesi gerekiyor, ancak "insanlar" oyunun kalitesini ve gerçekliğini geliştirmek için farklı oyun tarzlarına ihtiyaç duyuyor.
Meydan okuma
Leo, aslında programlama zorluklarına adanmış bir web sitesi olduğunu hatırlıyor ve yardımınızı alıyor! İşiniz, 5 kartlı pokerin değiştirilmiş bir versiyonunu "Pokerface" oynayan bir program yazmaktır. Program, girişinizi istediğiniz formatta 5 kartlı bir el olarak alacak ve daha sonra program çıktı verecektir:
- Oynatıcı kart değiştirmek istiyorsa, tam olarak (büyük / küçük harfe duyarlı) "true" "1" veya "t", aksi takdirde boş olmayan diğer çıktılar.
- Doğruysa, oyuncunun değiştirmek istediği kart indeksleri ve / veya kart isimleri listesi.
- Oyuncunun kaç ek kart istediğini belirten 0 ile 3 arasında tek bir sayı.
- Oynatıcının kullanmak istediği eli yazdırın.
(Aşağıdaki biçimlendirmeye bakın)
Pokerface kuralları
- Pokerface metin tabanlı bir macera oyunu olduğundan, kartlar tutarlı bir şekilde sunulmalıdır. Kartlar iki karakter koduyla temsil edilir, ilk karakter takımdır ve ikincisi kartın adıdır.
- Kartlar:
- 2-9 = 2-9
- 10 = T
- Jack = J
- Kraliçe = Q
- Kral = K
- Ace = A
- Takım elbise:
- Maça = S
- Kulüpler = C
- Kalpler = H
- Elmas = D
- Kartlar:
Yani maça ası SA, kalplerin 10'u HT, elmasların dördüncü'si D4 vb.
- Tek bir Pokerface turu dört adımdan oluşur:
- Deste değişikliği yapılır ve her oyuncuya beş kartlık bir el dağıtılır.
- Her oyuncuya istediği kadar kart değiştirme şansı verilir.
- Her oyuncuya en fazla üç kart kazanma şansı verilir.
- Her oyuncu en iyi elini göstermelidir.
- En iyi el kazanır ve oyuncuya bir puan kazandırır. Beraberlik durumunda, her iki oyuncu da bir puan alır.
- Tek bir oyunda on tur oynanır ve en çok puana sahip olan oyuncu kazanır ve tek bir "kazanma puanı" kazanır. Beraberlik durumunda, her iki oyuncu da bir kazanma puanı kazanır.
- Leo'nun gerçekten çok fazla parası yok, bu yüzden botunuz bunun bahissiz mükemmel bir dünya olduğunu varsayabilir.
Eller
- Eller tam olarak 5 kart uzunluğundadır (ilk giriş ve son çıkış).
- Eller, burada açıklanan kurallara uygun olarak sıralanır .
Giriş çıkış
- Leo yalnızca Java'yı biliyor, bu nedenle programınızın İşlem API'sı (komut satırı) aracılığıyla yürütülebilir olması ve giriş ve çıkış için sırasıyla STDIN ve STDOUT kullanması gerekir.
- Yukarıda ayrıntıları verilen her girdi ve çıktı adımı için, girdi ve çıktıların her biri bir satırda bulunmalıdır.
- Nihai çıktıdan sonra en az bir yeni satır olmalıdır. (Bunun nedeni girişin STDIN'den okunmasıdır)
- Sondaki ve öndeki boşluklar dışında herhangi bir yabancı giriş / çıkışa izin verilmez. Ayrıştırıcı,
final_hand=...
veya gibi şeyleri anlamıyordraw 0
. - Çizim yaparken, çıktı tek bir tamsayıdır, çıktı alışverişi aşağıda tanımlanan tamsayıların ve / veya kartların bir listesi olduğunda ve orijinal el dağıtılırken çıktı aşağıda tanımlanan kartların bir listesidir.
- Tüm giriş / çıkış numaraları, taban 10'daki pozitif tamsayılar olmalıdır.
- Kart girişi için format tanımlayabilirsiniz (aşağıdaki yazı formatına bakınız).
- True, tam olarak "true", "1" veya "t" olarak tanımlanır ve false, boş olmayan başka bir değerdir.
- Değişim adımı sırasında:
- Kart endeksleri aralarında en az bir boşluk çıkışı olmalıdır (örneğin
3 4 0
) - Kart adları, aralarında en az bir boşluk bırakılmalıdır (ör.
H4 S8
) - Kart adları ve indeksler çıktıda karışık olabilir (ör.
0 H7 3 D3
) - Sondaki ve öndeki boşluklara izin verilir.
- Yukarıdakilerin çıkışını yapan oynatıcının sonucu olarak girdi,
bot.jlsc
dosya tarafından belirtildiği şekilde , istendiği gibi aynı sırada biçimlendirilir
- Kart endeksleri aralarında en az bir boşluk çıkışı olmalıdır (örneğin
- Bir oyuncunun eline eklemek istediği kart sayısı önde ve arkada olabilir.
- Eller, aralarında en az bir boşluk (örneğin
H4 D5 CA
) olacak şekilde verilmelidir , sondaki boşluklar ve önde gelen boşluklara izin verilir. - Ellerin uygun sırada çıkmasına gerek yoktur (örneğin
H4 D4 C4 DA SA
veH4 DA D4 SA C4
her ikisi de tam bir ev olan 4, 4, 4, Ace, Ace'i temsil eder). - Rakiplerin ellerini analiz ederek bir strateji oluşturmak isterseniz, verileri bir
<botname>/data
dizinde saklayabilirsiniz .- Rakip botlar ellerini görüntüledikten sonra, her bot yeni bir satırda (\ n ile ayrılmış) hands.txt içinde her bot veri dizinine yazılır. Dosya US_ASCII olarak kodlanacaktır.
- Botunuz yeni kartlar veya kart alışverişi istediğinde, kartlar
bot.jlsc
dosyada belirttiğiniz biçime bağlı olarak girilir .
Yazı Biçimi
- Her yazı iki şey içermelidir:
- Botunuzun kaynak kodu veya halka açık bir depoya bağlantı.
- Şunları içeren bir zip dosyası:
- Botunuzun derlenmiş / yürütülebilir sürümü (Dosya bir .exe veya başka bir derlenemeyen dosyaysa, lütfen gönderinize derleme talimatlarını ekleyin).
- Bir
bot.jlsc
dosya, aşağıya bakın (yan not: .jlsc uzantısı sadece bir yan projemden, bir yapılandırma biçiminden kaynaklanmaktadır. Aşağıdaki dosya uygun sözdizimiyle eşleştiğinden endişelenmeyin).
- .Zip dosyası botunuzla aynı şekilde adlandırılmalıdır.
- Pencerelere veya başka bir sıkıştırma yardımcı programına erişiminiz yoksa veya herhangi bir nedenle bir .zip yapamıyorsanız, yazınıza bot.jlsc dosyasının metnini ekleyin
bot.jlsc dosyası:
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}"
Nerede:
- "cmd" botunuzu çalıştırmak için kullanılan windows komut satırı komutudur. Botunuzun dizinde olacağını unutmayın
<botname>
, bu yüzden komutu uygun şekilde ayarlayın. - "name", botunuzun adıdır.
- "bağlantı" cevabınızın bağlantısıdır, yayınladıktan sonra bunu düzenlemeniz gerekir.
- "input_hand", orijinal işlemin nasıl biçimlendirilmesini istediğinizdir ($ {#}, 0-4 numaralı kartları temsil eder).
- "input_1", ek bir kartın girişinin nasıl biçimlendirilmesini istediğinizdir.
- "input_2" iki ek kart girişinin nasıl biçimlendirilmesini istediğinizdir.
- "input_3" üç ek kart girişinin nasıl biçimlendirilmesini istediğinizdir.
- "input_4" dört ek kart girişinin nasıl biçimlendirilmesini istediğinizdir.
Ayrıntılı Bilgiler
- Bu boşluklara izin verilmiyor (bkz. 'Ortak tuzaklar')
- Kural setinde her zaman mümkün olan en iyi eli verecek bir bot yazamazsınız. (yani uzun süren kaba kuvvet botları yok, hiçbir şey LeoBot kadar 'iyi' olmamalı)
- Botunuz ~ 100 ms veya daha az bir sürede çalışmalıdır (Bu noktada Lenient, en fazla ~ 1 saniye)
- Seçilen elden sonra botun herhangi bir çıkışı göz ardı edilecektir.
- Standart boşluklara izin verilmez.
- Evet, linux'un daha iyi olduğunu biliyorum, ancak bir Windows PC'im var, bu yüzden programınızın derlenmiş / yürütülebilir sürümünün windows komut satırından çalıştırılabileceğinden emin olun.
- Bilgisayarımda zaten python ve java yüklü, ancak yeni sürümlere güncelleme yapmaya ve diğer ortamları yüklemeye hazırım, bu yüzden lütfen programınızın ne tür bir ortam gerektirdiğini belirtin.
- Her durumda başka bir bot ile aynı şeyi yapan bir bot yazamazsınız. Spam botlarına izin verilir, ancak önerilmez.
- Botunuz sadece sahip olduğu kartları kullanabilir. Takas ile kaybedilen veya başlamak için dağıtılmayan kartlar nihai eldeki geçersiz çıktıdır.
- Giriş ve çıkış yalnızca ASCII karakterleri içerebilir.
Turnuvalar
- Zamanı aldığımda turnuvalar düzenlenecek (programım neredeyse Leo'nunki kadar dolu, bu yüzden bu benim biraz seyrek. Rahatsızlık için özür dilerim.).
- Botlar 4 kişilik oyunlarda birbirine karşı çukur olacak ve her olası bot alt kümesi için bir oyun olacak (yani birçok oyun).
- Bu işlem beş kez tekrarlanacaktır.
- Turnuva işleyicisinin bot gruplarını yapma şekli nedeniyle, bot sayısını 4'e bölünebilir hale getirmek için üç taneye kadar dolgu botu eklenecektir. Bu botlar ilk başta ele alındıkları eli geri getirecektir.
- Her tur ve maç yapıldıktan sonra, kazanılan sayı oyunlarına göre botların puanları hesaplanacaktır.
- Birden fazla bot bir pozisyonu paylaşabilir (ilk kaydedilen ilk kazanma için bağlar).
- Turnuva bittikten sonra skorlar bu yazının sonuna eklenir.
puanlama
Normal KoTH kuralları. En fazla oyunu kazanan botlar mücadeleyi kazanır.
LeoBot
Leo'nun botu oldukça akıllı. Herhangi bir kart takas etmez, bu çok zordur, ancak maksimum sayıda ek kart talep eder ve yapabileceği en iyi eli belirler ve o eli oynar. Leobot'un ana mantığı aşağıdadır.
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 sürekli olarak turnuvaları kazanırsa ve iyi miktarda giriş varsa, onu koşuya dahil etmeyi bırakacağımı unutmayın.
Önemli Linkler
feragat
Leo ve Tech Inc. hikaye ögeleridir ve gerçek hayattaki şirketlere veya insanlara herhangi bir benzerlik tamamen kasıtsızdır. (Ancak, Leo'nun 'durumu' soruya koşul eklediğinde veya çıkardığında, bunlar aslında sorunun bir parçasıdır ...)
"f"q+
minimum gereksinimleri karşılar. Rekabette 10 kişi varsa, bu muhtemelen tüm aptal olmayan girişleri yener (aptal olmayan giriş muhtemelen> 75 karakter, 5 * 10 (aptal bot puanı, son geliyor) = 50 <75 (çok küçük akıllı bot puanı) (önce geliyor))). Bu nedenle, muhtemelen bu mücadeleden codegolf'u kaldırmalısınız