Mengevaluasi Tangan-Skat

18

pengantar

Skat adalah permainan kartu tradisional Jerman untuk 3 pemain. Dek terdiri dari 32 kartu: Ace, King, Queen, Jack, 10, 9, 8, 7 dalam semua 4 suit (Clubs, Spades, Hearts, Diamonds).

Di setiap babak ada satu pemain bermain solo sementara dua lainnya bermain melawannya. Pada awal putaran setiap pemain dibagikan 10 kartu, 2 kartu sisanya disebut skat dan diletakkan menghadap ke bawah di tengah. Pemain solo ditentukan oleh fase penawaran. Ini adalah bagian dari permainan yang harus Anda hadapi dalam tantangan ini, detail lebih lanjut tentang ini di bawah ini.

Pemain yang memenangkan fase penawaran menjadi pemain solo. Dia mengambil skateboard dan kemudian menjatuhkan dua kartu (yang mungkin sama, tim lain tidak tahu), mengambil baju truf, dan putaran dimulai.

Satu putaran terdiri dari sepuluh trik. Pemain yang memenangkan trik memimpin yang berikutnya sampai semua kartu dimainkan. Saya tidak akan menjelaskan aturannya di sini, tetapi Anda harus tahu bahwa memiliki banyak kartu as adalah baik. Jika Anda ingin belajar tentang aturan, periksa artikel Wikipedia yang saya tautkan pada awal posting ini, tetapi tidak diperlukan untuk tantangan ini.

Tantangan

Anda ingin mengajari kedua putra Anda cara bermain skating. Aturannya tidak terlalu sulit, jadi mereka dengan cepat memahaminya. Satu-satunya hal yang membuat mereka kesulitan adalah penawaran, khususnya menghitung nilai permainan tangan mereka. Jadi, Anda memutuskan untuk menulis sebuah program kecil yang menghasilkan nilai gim maksimum yang dapat mereka tawarkan dengan bantuan yang ada.

Menghitung nilai game

Setiap tangan memiliki nilai gim tertentu. Itu ditentukan oleh jumlah Jack berurutan yang Anda miliki dan setelan yang ingin Anda pilih sebagai kartu truf. Mari kita mulai dengan faktor pertama, jack!

Faktor Jack

Jack selalu kartu truf, dan mereka mengalahkan setiap kartu truf lainnya. Urutan kekuatan antara keempat Jack adalah:

  1. Jack of Clubs (tertinggi)
  2. Jack of Spades
  3. Jack of Hearts
  4. Jack of Diamonds (terendah)

Dalam penjelasan lebih lanjut saya akan merujuk mereka dengan nomor yang saya berikan kepada mereka di sini.

Anda ingat bahwa ada beberapa faktor yang Anda dapatkan dari Jack di tangan Anda yang merupakan bagian dari nilai permainan? Bagus! Inilah cara Anda mendapatkannya:

Faktor Jack ini adalah jumlah Jack top (lihat urutan di atas) secara berurutan, ditambah 1. Jadi, jika Anda memiliki semua 4 Jack, maka adalah 4 + 1 = 5. Jika Anda hanya memiliki 2 Jack pertama, itu adalah 2 + 1 = 3.

Atau, untuk membuat hal-hal sedikit lebih rumit, Faktor Jack juga bisa menjadi jumlah Jack top dalam urutan yang Anda lewatkan , ditambah 1. Jadi, jika Anda melewatkan yang pertama, itu adalah 1 + 1 = 2. Jika Anda hilang pertama 3, itu 3 + 1 = 4. Berikut beberapa contoh, menggunakan penomoran di atas:

[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

Itu faktor pertama. Inilah cara mendapatkan yang ke-2:

The Trump Suit Factor

Yang ini jauh lebih sederhana. Faktor ke-2 ditentukan oleh setelan truf yang diambil pemain solo menggunakan pemetaan berikut:

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

Itu mudah, bukan?

Nilai Game

Nilai permainan adalah produk dari dua faktor. Cukup mudah menurut Anda? Salah! Sementara Faktor-Jack sudah diperbaiki, faktor-jas tidak. Setelan yang Anda pilih sebagai kartu truf tergantung pada jumlah kartu truf dan nilai kartu non-kartu truf di tangan Anda. Akan terlalu rumit untuk menjelaskan seperti apa tangan yang bagus, jadi Anda akan menggunakan algoritma berikut:

Algoritma Yang-Trump-do-I-Pick

Anda tidak harus berpartisipasi dalam penawaran. Jika Anda memutuskan bahwa tangan Anda terlalu buruk untuk bermain solo, Anda bisa lewat begitu saja. Tangan Anda harus sesuai dengan kriteria berikut untuk dapat dimainkan:

  • Memiliki setidaknya 6 kartu truf (kartu setelan truf yang Anda pilih + jumlah Jack). Jika ini memungkinkan untuk lebih dari satu setelan, pilih satu yang akan menghasilkan lebih banyak kartu truf. Jika masih ada dasi, pilih jas dengan peringkat tertinggi yang diberikan di atas.

  • Dari kartu non-truf, miliki setidaknya 1 Ace.

Jika tangan Anda tidak cocok dengan kedua kriteria ini, Anda akan lulus. Jika ya, Anda akan menampilkan nilai gim yang dihitung dan setelan truf yang dipilih.

Catatan singkat: Tentu saja ini adalah algoritma yang sangat disederhanakan. Ada terlalu banyak strategi dan pengalaman dalam menilai tangan daripada yang bisa kita bahas dalam tantangan seperti ini.

Memasukkan

Setiap kartu memiliki pengidentifikasi unik. Bagian pertama adalah setelan ( C lubs, S pades, H earts, D iamonds), bagian kedua adalah nilai yang diberikan oleh pemetaan ini:

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

Kedua bagian digabungkan membentuk satu kartu. Nilainya datang pertama, lalu datang jas. Anda dapat mengambil kartu dalam format apa pun yang Anda inginkan.

Keluaran

Jika hand dimainkan, output nilai game dan suit truf yang dipilih (urutan tidak masalah). Jika tidak, output "lulus".

Aturan

  • Seperti yang disebutkan, Anda dapat mengambil input dalam format yang paling nyaman bagi Anda. Contohnya lihat di bawah dalam kasus uji.
  • Input dapat disediakan oleh argumen baris perintah, input pengguna, atau argumen fungsi.
  • Output dapat diberikan sebagai nilai balik atau hanya dapat dicetak di layar.
  • Kartu dalam input mungkin tidak dipesan dengan cara apa pun. Program Anda harus dapat menangani pesanan kartu acak apa pun.
  • Kemenangan jumlah byte terendah!

Testcases

Masukan dalam kasus uji akan menjadi daftar 2-char Strings.

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

Penjelasan:

  1. Dua Jack berturut-turut dengan Clubs sebagai truf. Jadi nilai game adalah 3 x 12 = 36
  2. Tiga Jack berturut-turut hilang dengan Spades sebagai truf. Jadi nilai gamenya adalah 4 x 11 = 44
  3. Hanya maksimal 4 kartu truf yang dimungkinkan, jadi Anda akan lulus.
  4. Enam kartu truf dengan Spades tetapi tanpa kartu as, jadi Anda akan lulus.

Jika beberapa aturan tidak jelas, silakan dan komentar. Saya telah tumbuh dengan game ini, jadi sulit bagi saya untuk menilai jika saya menggambarkan semuanya dengan cukup detail.

Dan sekarang ... Selamat Coding!

sunting: Seperti yang ditunjukkan kepada saya di komentar (terima kasih kepada isaacg), ada aturan yang menghitung truf teratas berikut setelah 4 Jack ke dalam "Jack-factor" sehingga bisa naik ke 11. Untuk menjaga tantangan ini tetap sederhana dan untuk tidak membingungkan orang, aturan yang saya usulkan pada awalnya akan tetap seperti semula. Jadi faktor maksimum tetap di 5.

Denker
sumber
6
Selamat datang di Programming Puzzles & Code Golf — tantangan pertama yang luar biasa! :)
Gagang Pintu
1
Haruskah jumlah straight jack / jack yang hilang juga termasuk truf setelan teratas secara berurutan? Itulah yang dikatakan wikipedia di sini
isaacg
@isaacg saya harus mengakui bahwa saya tidak tahu tentang aturan ini sampai sekarang. Terima kasih telah menunjukkannya. Saya melakukan riset dan Anda memang benar. Dalam keluarga saya, kami tidak bermain dengan aturan ini dan saya belum pernah bertemu siapa pun yang bermain dengan aturan ini. Itu tidak memiliki relevansi tinggi tho, karena ketika Anda memiliki tangan seperti itu, Anda akan sebagian besar kali bermain Grand yang dihitung berbeda pula. Jadi untuk tantangan ini kita hanya akan tetap dengan aturan yang saya usulkan. Saya akan mengedit posting saya sehingga jelas bagi semua orang.
Denker
1
@ DenkerAffe, saya bermain Skat selama bertahun-tahun di sebuah klub di Jerman, dan percayalah, aturannya penting, dan ada kasus di mana itu sangat relevan (dan ya, itu tidak diketahui di sebagian besar pemain yang tidak serius). Terutama dengan sisi yang hilang - bayangkan Anda memiliki truf K, D, 9, 8, 7, dan tiga A dan dua 10 dalam warna lain. Grand Anda pasti mati, tetapi Anda bisa bermain 'ohne 6' (mengumpulkan beberapa kontra), dan mengalahkan mereka, dengan asumsi Anda memiliki ide bagaimana B duduk dari penawaran. Dan Anda dapat menawar hingga matahari muncul dengan kartu itu.
Aganju
@ Agganju Saya sudah berasumsi bahwa aturan ini tidak diketahui oleh kebanyakan pemain hobi. Terima kasih atas konfirmasinya. Saya tidak ragu bahwa ini penting tetapi dari pengalaman saya tangan seperti ini cukup langka, jadi aturannya tidak sering bermain.
Denker

Jawaban:

1

Python 2, contoh implementasi

Karena belum ada pengiriman, saya menuliskan contoh implementasi dengan Python. Format input sama dengan di testcases di tantangan.

Mungkin itu memotivasi kalian untuk pergi, tidak sulit :)

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"
Denker
sumber
0

Java, 256 byte

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;}

Mengambil input sebagai array dari array karakter dalam format A4, di mana 4adalah Klub , 3adalah Spades , 2adalah Hati dan 1adalah Diamonds . Output adalah 36 4untuk tawaran 36 dengan truf suit Clubs ,p untuk passing.

Cobalah online di sini .

Versi tidak disatukan:

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
}
Ketidakseimbangan
sumber
0

C, 235 byte

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);}

Port Java saya jawaban .

Cobalah online sini .

Mengambil input sebagai array dari karakter dalam format A4, di mana 4adalah Klub , 3adalah Spades , 2adalah Hati dan 1adalah Diamonds . Output adalah 36 4untuk tawaran 36 dengan truf suit Clubs , puntuk passing.

Versi tidak disatukan:

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
}
Ketidakseimbangan
sumber
226 byte
ceilingcat