Skat-Hand'i değerlendirin


18

Giriş

Skat , 3 oyuncu için geleneksel bir Alman kart oyunudur. Deste 32 karttan oluşur: As, Kral, Kraliçe, Jack, 4 takımın hepsinde (Kulüpler, Maçalar, Kalpler, Elmaslar) 10, 9, 8, 7.

Her turda bir oyuncu solo oynar, diğer ikisi ona karşı oynar. Bir raundun başında her oyuncuya 10 kart dağıtılır, kalan 2 karta skat denir ve ortada yüzü aşağıya bakacak şekilde yerleştirilir. Yalnız oyuncu bir teklif aşaması ile belirlenir. Bu, bu meydan okumada ele almanız gereken bölümdür, aşağıda daha fazla ayrıntı.

Teklif aşamasını kazanan oyuncu solo oyuncu olur. Pateni alır ve sonra iki kart bırakır (aynı olabilir, diğer takım bilmiyor), koz takımını alır ve tur başlar.

Bir tur on numaradan oluşur. Bir numara kazanan oyuncu, tüm kartlar oynanana kadar bir sonrakini yönlendirir. Buradaki kuralları açıklamayacağım, ancak çok fazla koz kartına sahip olmanın iyi olduğunu bilmelisin. Kurallar hakkında bilgi edinmek istiyorsanız, bu yazının başında bağladığım Wikipedia makalesine bakın, ancak bu meydan okuma için gerekli değildir.

Meydan okuma

İki oğluna nasıl skat çalmayı öğretmek istiyorsun. Kurallar o kadar zor değil, bu yüzden hızla içine giriyorlar. Onlara zor zaman veren tek şey, özellikle ellerinin oyun değerini hesaplamak için teklif vermektir. Böylece, mevcut elleriyle teklif verebilecekleri maksimum oyun değerini veren küçük bir program yazmaya karar verdiniz.

Oyun değerinin hesaplanması

Her elin belirli bir oyun değeri vardır. Sahip olduğunuz sıralı Jakların miktarı ve koz olarak seçmek istediğiniz takım tarafından belirlenir. İlk faktör, krikolar ile başlayalım!

Jack Faktörü

Krikolar her zaman koz kartlarıdır ve diğer koz kartlarını yenerler. Dört Kriko arasındaki güç sırası:

  1. Jack of Clubs (en yüksek)
  2. Maça Krikosu
  3. Jack of Hearts
  4. Jack of Diamonds (en düşük)

Daha fazla açıklamada, burada kendilerine atadığım numaralarla onlara atıfta bulunacağım.

Oyundaki değerin bir parçası olan elindeki Jack'lerden aldığın bir çeşit faktör olduğunu hatırlıyor musun? Harika! İşte bunu nasıl elde edersiniz:

Bu Jack faktörü, sırayla üstteki en iyi Jakların sayısıdır (yukarıdaki sıraya bakın), artı 1'dir. Bu nedenle, 4 Jakın hepsine sahipseniz 4 + 1 = 5'tir. Sadece ilk 2 Jakınız varsa, 2 + 1 = 3.

Alternatif olarak, işleri biraz daha karmaşık hale getirmek için, Jack Factor, eksik olduğunuz sırayla en iyi Jack'lerin sayısı da artı 1 olabilir. ilk 3 eksik, 3 + 1 = 4. İşte yukarıdaki numaralandırma kullanarak bazı örnekler:

[1, 4] -> 1 + 1 = 2
[1, 2, 4] -> 2 + 1 = 3
[2, 3, 4] -> 1 + 1 = 2
[1, 2, 3, 4] -> 4 + 1 = 5
[] -> 4 + 1 = 5

İlk faktör buydu. İşte ikincisini nasıl alacağınız:

Koz Takım Faktörü

Bu çok daha basit. 2. faktör, solo oyuncunun aşağıdaki eşlemeyi kullanarak seçtiği koz tarafından belirlenir:

Clubs    -> 12
Spades   -> 11
Hearts   -> 10
Diamonds ->  9

Kolaydı, değil mi?

Oyun Değeri

Oyun değeri iki faktörün ürünüdür. Sence oldukça kolay mı? Yanlış! Jack Faktörü sabitken, takım faktörü sabit değildir. Koz olarak topladığınız takım koz miktarına ve koz olmayan kartlarınızın elindeki değerine bağlıdır. İyi bir elin neye benzediğini açıklamak çok karmaşık olurdu, bu nedenle aşağıdaki algoritmayı kullanacaksınız:

Hangi Trump-do-I-Pick Algoritması

İhaleye katılmak zorunda değilsiniz. Elinizin solo oynamak için çok kötü olduğuna karar verirseniz, sadece geçebilirsiniz. Oynatılabilmesi için elinizin aşağıdaki kriterlere uyması gerekir:

  • En az 6 koz kartınız var (seçtiğiniz kozun kartları + Jack sayısı). Bu, birden fazla takım için mümkünse, daha fazla kozla sonuçlanacak olanı seçin. Yoksa hala bir kravat, yukarıda verilen en yüksek derece ile takım elbise almak.

  • Koz olmayan kartlardan en az 1 As var.

Eliniz bu kriterlerin her ikisine de uymuyorsa, geçersiniz. Varsa, hesaplanan oyun değerini ve seçilen kozu çıkarırsınız.

Kısa not: Tabii ki bu çok basitleştirilmiş bir algoritma. Böyle bir meydan okumayı ele alabileceğimizden çok daha fazla strateji ve deneyim bir eli yargılamak için gidiyor.

Giriş

Her kartın benzersiz bir tanımlayıcısı vardır. Birinci bölüm takım (olup LUBS, S kürekler, H earts, D iamonds), ikinci bölüm, bu eşleme ile verilmektedir değerdir:

Ace -> A
King -> K
Queen -> Q
Jack -> J
10 -> 0
9 -> 9
8 -> 8
7 -> 7

Her iki parça da bir kart oluşturur. Değer önce gelir, sonra takım elbise gelir. Kartları istediğiniz formatta alabilirsiniz.

Çıktı

El oynanabiliyorsa, oyun değerini ve çekilen koz takımını (sipariş önemli değildir) çıktılayın. Değilse, çıktı "pass".

kurallar

  • Belirtildiği gibi, girişi sizin için en uygun biçimde alabilirsiniz. Örnekler test örneklerinde aşağıya bakınız.
  • Girdi, komut satırı bağımsız değişkenleri, kullanıcı girdisi veya işlev bağımsız değişkenleri tarafından sağlanabilir.
  • Çıktı dönüş değeri olarak sağlanabilir veya sadece ekrana yazdırılabilir.
  • Girişteki kartlar hiçbir şekilde sipariş edilemeyebilir. Programınız herhangi bir rastgele kart siparişi ile başa çıkabilmelidir.
  • En düşük bayt sayısı kazanır!

testcases

Test senaryolarına giriş 2 karakterlik Dizelerin bir listesi olacaktır.

1. ["JC", "JS", "JD", "AC", "KC", "9C", "AS", "7H", "QD", "8D"] -> 36 Clubs
2. ["JD", "AS", "0S", "KS", "QS", "9S", "8S", "AD", "8C", "9C"] -> 44 Spades
3. ["JH", "JD", "0S", "KS", "9C", "8C", "QH", "KH", "AD", "9D"] -> pass
4. ["JD", "AS", "KS", "QS", "0S", "9S", "8D", "7D", "0C", "QH"] -> pass

Açıklama:

  1. Üstün koç olarak kulüpleri ile üst üste iki jack. Yani oyun değeri 3 x 12 = 36
  2. Üst üste üç Vale koz olarak Maça eksik. Yani oyun değeri 4 x 11 = 44
  3. Sadece en fazla 4 koz mümkündür, bu yüzden geçersiniz.
  4. Maça ile altı koz ama koz olmayan as, böylece geçecek.

Bazı kurallar net değilse, devam edin ve yorum yapın. Bu oyunla büyüdüm, bu yüzden her şeyi yeterince ayrıntılı olarak tarif edip etmediğimi yargılamak zor.

Ve şimdi ... Mutlu Kodlama!

edit: yorumlarda bana işaret gibi (isaacg sayesinde), "Jack faktörü" içine 4 Jacks sonra aşağıdaki üst koyar sayar bir kural var bu yüzden 11 kadar gidebilir. ve insanları karıştırmamak için, başlangıçta önerdiğim kurallar oldukları gibi kalacak. Böylece maksimum faktör 5'de kalır.


6
Programlama Bulmacalar ve Kod Golf hoş geldiniz - mükemmel ilk meydan okuma! :)
Kapı tokmağı

1
Düz jakların / eksik jakların sayısı üst sıradaki koz sıralarını da içermeli midir? Vikipedi burada
isaacg

@isaacg Şimdiye kadar bu kuralı bilmediğimi itiraf etmeliyim. Bunu işaret ettiğiniz için teşekkürler. Biraz araştırma yaptım ve haklısın. Ailemde bu kuralla oynamıyoruz ve ben de onunla oynayan hiç kimseyle karşılaşmadım. O kadar yüksek bir ilgiye sahip değil, çünkü böyle bir eliniz olduğunda, çoğu zaman farklı sayılan Grand'ı oynayacaksınız. Bu meydan okuma için sadece önerdiğim kurallara bağlı kalacağız. Gönderiyi herkesin görebileceği şekilde düzenleyeceğim.
Denker

1
@DenkerAffe, yıllarca Almanya'da bir kulüpte Skat oynadım ve bana güvenin, kural önemlidir ve son derece alakalı olduğu durumlar vardır (ve evet, ciddi olmayan oyuncuların çoğunda bilinmemektedir). Özellikle eksik tarafla - diğer renklerde koz K, D, 9, 8, 7 ve üç A ve iki 10 olduğunu hayal edin. Büyükünüz kesin olarak ölür, ancak B'nin teklifte nasıl oturduğuna dair bir fikriniz olduğunu varsayarak 'ohne 6' oynayabilir (bazı kontraları toplayabilirsiniz) ve onları yenebilirsiniz. Ve güneş bu kartla gelene kadar teklif verebilirsiniz.
Aganju

@Aganju Zaten bu kuralın çoğu hobi oyuncusu tarafından bilinmediğini varsaydım. Onay için teşekkürler. Bunun önemli olduğundan şüphe duymuyorum, ancak tecrübelerimden böyle eller oldukça nadirdir, bu yüzden kural o kadar sık ​​devreye girmez.
Denker

Yanıtlar:


1

Python 2, örnek uygulama

Henüz bir başvuru olmadığı için Python'da örnek bir uygulama yazdım. Giriş formatı, testteki test senaryolarıyla aynıdır.

Belki bu sizi gitmeye motive eder, o kadar da zor değil :)

def gameValue(hand):
    jacks = ""
    suits = {"C" : 0, "S" : 0, "H" : 0, "D" : 0}
    # Loop through the hand, find all jacks and count the cards of each suit
    for card in hand:
        jacks += card[1] if "J" in card else ""
        suits[card[1]] += 1 if card[0] != "J" else 0

    # Map the Jacks to numbers while 1 is the highest (Clubs) then sort them ascending
    jacks =  sorted(map(lambda j: {"C" : 1, "S" : 2, "H" : 3, "D" : 4}[j], list(jacks)))

    # Sort the suits by amount. Highest amount and value is first after that
    suits = sorted(suits.items(), key = lambda suit: suit[1], reverse = True)
    trumpSuit = suits[0][0];
    # Amount of trumps is jack-count plus trumpsuit-count
    trumpCount = len(jacks) + suits[0][1];

    # Check for at least one ace that is no trump
    hasAce  = len(filter(lambda c: c[0] == "A" and c[1] != trumpSuit, hand)) >= 1

    # If the hand  is playable, calculate jack-factor and output the result, otherwise pass
    if trumpCount >= 6 and hasAce:
        # If there no jacks the factor is 5. If there are, find the first gap
        if len(jacks) > 0:
            lastJack = 0
            for jack in jacks:
                if jack - lastJack >= 2:
                    break
                lastJack = jack

            jackFactor = jacks[0] if lastJack == 0 else lastJack + 1
        else:
            jackFactor = 5

        trumpFactor = {"C" : 12, "S" : 11, "H" : 10, "D" : 9}[suits[0][0]]
        print str(trumpFactor * jackFactor) + " " + {12 : "Clubs", 11 : "Spades", 10 : "Hearts", 9 : "Diamonds"}[trumpFactor]
    else:
        print "pass"

0

Java, 256 bayt

h->{int i,j=1,m=0,t,n=0,a[]=new int[8];for(var c:h){t=c[1]-48;if(c[0]==74){j+=1<<t;n++;}else{m+=i=c[0]==65?1:0;a[--t+4]+=i;a[t]++;}}for(i=t=0;i<4;i++)t=a[i]<a[t]?t:i;return a[t]+n<6|m-a[t+4]<1?"p":(t+++9)*(5-(int)(Math.log(j>7?~j&7:j)/Math.log(2)))+" "+t;}

Biçiminde karakter dizileri dizisi olarak girişi alır A4, 4olan Kulüpler , 3olduğu maça , 2olduğu Kalpler ve 1bir elmas . Çıktı olduğu 36 4koz ile 36 değerinde bir teklif için Kulüpler , pgeçiş için.

Burada çevrimiçi deneyin .

Ungolfed sürümü:

h -> { // lambda taking a char[][] as argument and returning a String
    int i,                // used as a loop variable and as a temporary variable
        j = 1,            // variable storing the jacks present in the hand in its four last-to-least significant bits
        m = 0,            // number of aces in the hand
        t,                // used as a temporary variable at first, later stores the trump suit
        n = 0,            // number of jacks in the hand
        a[] = new int[8]; // in the lower 4 indices, stores the number of non-jack cards present in the hand for each suit; in the higher 4 indices, stores the number of aces present in the hand for each suit (0 or 1)

    for(var c : h) {   // loop over all the cards in the hand
        t = c[1] - 48; // determine the suit of the current card; 48 is the ASCII code for '0'
        if(c[0] == 74) { // if it's a jack; 74 is the ASCII code for 'J'
            j += 1 << t; // set the corresponding bit
            n++;         // and increment the total number of jacks
        } else {                             // if it's not a jack
            m += (i = (c[0] == 65 ? 1 : 0)); // increment the total number of aces if it's an ace (65 is the ASCII code for 'A')
            a[ --t + 4] += i;                // increment the number of aces for this suit if it's an ace
            a[t]++;                          // increment the number of non-jack cards for this suit
        }
    }

    for(i = t = 0; i < 4; i++)     // loop over the suits ...
        t = (a[i] < a[t]) ? t : i; // ... and find the one with the most cards, giving priority to higher-valued suits in case of a tie

    return (a[t] + n < 6) |                                             // if there are less than 6 trump cards
           (m - a[t + 4] < 1) ?                                         // or less than 1 non-trump ace
           "p"                                                          // return "p" to pass on the hand
           :                                                            // else return
           ((t++ + 9) *                                                 // the value of the trump suit (and increment the trump suit for output later)
           (5 - (int) (Math.log((j > 7) ? (~j & 7) : j) / Math.log(2))) // times the jack factor
           + " " + t);                                                  // followed by the trump suit
}

0

C, 235 bayt

f(char*h){int i,j=1,m=0,t,n=0,a[8]={0};for(;*h;h+=2){t=h[1]-48;if(*h-74){m+=i=*h==65;a[--t+4]+=i;a[t]++;}else{j+=1<<t;n++;}}for(i=t=0;i<4;i++)t=a[i]<a[t]?t:i;printf(a[t]+n<6|m-a[t+4]<1?"p":"%d %d",(t+9)*(5-(int)log2(j>7?~j&7:j)),t+1);}

Java'mın bağlantı noktası noktası .

Çevrimiçi deneyin Burada.

Biçiminde karakter bir dizi olarak girişi alır A4, 4olan Kulüpler , 3olduğu maça , 2olduğu Kalpler ve 1bir elmas . Çıktı 36 4koz kıyafeti ile 36 teklif içindir Kulüpler , pgeçiş için.

Ungolfed sürümü:

f(char* h) { // function taking an array of characters as argument (and implicitly returning an unused int)
    int i,          // used as a loop variable and as a temporary variable
        j = 1,      // variable storing the jacks present in the hand in its four last-to-least significant bits
        m = 0,      // number of aces in the hand
        t,          // used as a temporary variable at first, later stores the trump suit
        n = 0,      // number of jacks in the hand
        a[8] = {0}; // in the lower 4 indices, stores the number of non-jack cards present in the hand for each suit; in the higher 4 indices, stores the number of aces present in the hand for each suit (0 or 1); partially initialized to zero, the compiler will do the rest

    for(; *h; h += 2) { // loop over all the cards in the hand
        t = h[1] - 48;  // determine the suit of the current card; 48 is the ASCII code for '0'
        if(*h - 74) {              // if it's not a jack; 74 is the ASCII code for 'J'
            m += (i = (*h == 65)); // increment the total number of aces if it's an ace (65 is the ASCII code for 'A')
            a[ --t + 4] += i;      // increment the number of aces for this suit if it's an ace
            a[t]++;                // increment the number of non-jack cards for this suit
        } else {         // if it's a jack
            j += 1 << t; // set the corresponding bit
            n++;         // and increment the total number of jacks
        }
    }

    for(i = t = 0; i < 4; i++)   // loop over the suits ...
        t = a[i] < a[t] ? t : i; // ... and find the one with the most cards, giving priority to higher-valued suits in case of a tie

    printf( (a[t] + n) < 6 |                             // if there are less than 6 trump cards
            (m - a[t + 4] < 1) ?                         // or less than 1 non-trump ace
            "p" : "%d %d",                               // print "p" to pass on the hand, else print two numbers
            (t + 9) *                                    // first the value of the trump suit ...
            (5 - (int) log2((j > 7) ? (~j & 7) : j)),    // ... times the jack factor,
            t + 1                                     ); // followed by the trump suit
}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.