Đánh giá một tay trượt


18

Giới thiệu

Skat là một trò chơi bài truyền thống của Đức dành cho 3 người chơi. Bộ bài gồm 32 lá bài: Ace, King, Queen, Jack, 10, 9, 8, 7 trong cả 4 bộ đồ (Câu lạc bộ, Spades, Trái tim, Kim cương).

Trong mỗi vòng có một người chơi chơi một mình trong khi hai người còn lại chơi với anh ta. Khi bắt đầu một vòng, mỗi người chơi được chia 10 lá bài, 2 lá bài còn lại được gọi là skat và được đặt ở giữa. Người chơi solo được xác định bởi một giai đoạn đấu thầu. Đây là một phần của trò chơi mà bạn sẽ phải đối phó trong thử thách này, chi tiết hơn về điều này dưới đây.

Người chơi chiến thắng trong giai đoạn đấu thầu sẽ trở thành người chơi solo. Anh ta nhặt ván trượt và sau đó làm rơi hai lá bài (có thể giống nhau, đội kia không biết), chọn bộ đồ át chủ bài, và vòng đấu bắt đầu.

Một vòng bao gồm mười mánh. Người chơi thắng một mánh khóe sẽ dẫn người tiếp theo cho đến khi tất cả các thẻ được chơi. Tôi sẽ không giải thích các quy tắc ở đây, nhưng bạn nên biết rằng có nhiều át chủ bài là tốt. Nếu bạn muốn tìm hiểu về các quy tắc, hãy kiểm tra bài viết Wikipedia mà tôi đã liên kết ở đầu bài này, nhưng không cần thiết cho thử thách này.

Các thách thức

Bạn muốn dạy hai con trai của bạn cách chơi skat. Các quy tắc không khó lắm, vì vậy họ nhanh chóng tham gia vào nó. Điều duy nhất khiến họ gặp khó khăn là đấu thầu, đặc biệt tính toán giá trị trò chơi của họ. Vì vậy, bạn quyết định viết một chương trình nhỏ tạo ra giá trị trò chơi tối đa mà họ có thể trả giá bằng tay hiện tại của mình.

Tính giá trị trò chơi

Mỗi tay có một giá trị trò chơi nhất định. Nó được xác định bởi số lượng Jack liên tiếp bạn có và bộ đồ bạn muốn chọn làm át chủ bài. Hãy bắt đầu với yếu tố đầu tiên, jack cắm!

Nhân tố Jack

Jack luôn là con át chủ bài, và chúng đánh bại mọi con át chủ bài khác. Thứ tự sức mạnh giữa bốn Jack là:

  1. Jack of Câu lạc bộ (cao nhất)
  2. Jack của Spades
  3. Jack của trái tim
  4. Jack of Diamonds (thấp nhất)

Trong phần giải thích thêm tôi sẽ đề cập đến họ với những con số tôi đã gán cho họ ở đây.

Bạn nhớ rằng có một số yếu tố mà bạn nhận được từ Jacks trong tay bạn là một phần của giá trị trò chơi? Tuyệt quá! Đây là cách bạn có được nó:

Hệ số Jack này là số lượng Jack hàng đầu (xem thứ tự ở trên) theo thứ tự, cộng với 1. Vì vậy, nếu bạn có tất cả 4 Jack thì đó là 4 + 1 = 5. Nếu bạn chỉ có 2 Jack đầu tiên, thì đó là 2 + 1 = 3.

Ngoài ra, để làm cho mọi thứ phức tạp hơn một chút, Yếu tố Jack cũng có thể là số lượng Jack hàng đầu mà bạn đang thiếu , cộng thêm 1. Vì vậy, nếu bạn đang thiếu cái đầu tiên, thì đó là 1 + 1 = 2. Nếu bạn thiếu anh 3 đầu tiên, đó là 3 + 1 = 4. Dưới đây là một số ví dụ, sử dụng cách đánh số ở trên:

[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

Đó là yếu tố đầu tiên. Đây là cách bạn có được cái thứ 2:

Yếu tố phù hợp với Trump

Điều này là đơn giản hơn rất nhiều. Yếu tố thứ 2 được xác định bởi bộ đồ phù hợp mà người chơi solo chọn sử dụng ánh xạ sau:

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

Điều đó thật dễ dàng phải không?

Giá trị trò chơi

Giá trị trò chơi là sản phẩm của hai yếu tố. Bạn có dễ nghĩ không? Sai lầm! Trong khi Jack-Factor được cố định, yếu tố phù hợp thì không. Bộ đồ cuối cùng bạn chọn là át chủ bài phụ thuộc vào số lượng vấp ngã và giá trị của những lá bài không phải là con át chủ bài trong tay bạn. Sẽ là quá phức tạp để giải thích một bàn tay tốt trông như thế nào, vì vậy bạn sẽ sử dụng thuật toán sau:

Thuật toán which-Trump-do-I-Pick

Bạn không phải tham gia đấu thầu. Nếu bạn quyết định rằng tay của bạn quá tệ để chơi solo, bạn có thể vượt qua. Bàn tay của bạn phải phù hợp với các tiêu chí sau để có thể chơi được:

  • Có ít nhất 6 át chủ bài (các lá bài phù hợp với bạn chọn + số lượng Jack). Nếu điều này là có thể cho nhiều hơn một bộ quần áo, hãy chọn một bộ đồ sẽ dẫn đến nhiều át chủ bài hơn. Nếu vẫn còn cà vạt, hãy chọn bộ đồ có xếp hạng cao nhất được đưa ra ở trên.

  • Trong số những người không chơi bài, có ít nhất 1 Ace.

Nếu bàn tay của bạn không phù hợp với cả hai tiêu chí này, bạn sẽ vượt qua. Nếu vậy, bạn sẽ xuất giá trị trò chơi được tính toán và phù hợp với át chủ bài đã chọn.

Lưu ý ngắn: Tất nhiên đây là một thuật toán rất đơn giản. Có quá nhiều chiến lược và kinh nghiệm để đánh giá một bàn tay hơn là chúng ta có thể bao quát trong một thử thách như thế này.

Đầu vào

Mỗi thẻ có một định danh duy nhất. Phần thứ nhất là phù hợp với ( C lubs, S pades, H earts, D iamonds), phần thứ hai là giá trị được đưa ra bởi lập bản đồ này:

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

Cả hai phần kết hợp tạo thành một thẻ. Giá trị đến trước, sau đó đến bộ đồ. Bạn có thể lấy thẻ theo bất kỳ định dạng nào bạn muốn.

Đầu ra

Nếu tay có thể chơi được, hãy xuất giá trị trò chơi và phù hợp với át chủ bài (thứ tự không thành vấn đề). Nếu không, đầu ra "vượt qua".

Quy tắc

  • Như đã đề cập, bạn có thể lấy đầu vào ở định dạng thuận tiện nhất cho bạn. Ví dụ xem dưới đây trong các trường hợp thử nghiệm.
  • Đầu vào có thể được cung cấp bởi các đối số dòng lệnh, đầu vào của người dùng hoặc đối số chức năng.
  • Đầu ra có thể được cung cấp dưới dạng giá trị trả về hoặc chỉ có thể được in trên màn hình.
  • Các thẻ trong đầu vào có thể không được đặt hàng theo bất kỳ cách nào. Chương trình của bạn phải có khả năng đối phó với bất kỳ thứ tự thẻ ngẫu nhiên nào.
  • Số đếm byte thấp nhất!

Tủ thử

Đầu vào trong các trường hợp thử nghiệm sẽ là một danh sách các Chuỗi 2 ký tự.

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

Giải trình:

  1. Hai Jacks liên tiếp với Câu lạc bộ như át chủ bài. Vậy giá trị trò chơi là 3 x 12 = 36
  2. Ba Jacks liên tiếp mất tích với Spades là át chủ bài. Vậy giá trị trò chơi là 4 x 11 = 44
  3. Chỉ có tối đa 4 con át chủ bài là có thể, vì vậy bạn sẽ vượt qua.
  4. Sáu con át chủ bài với Spades nhưng không có át chủ bài, vì vậy bạn sẽ vượt qua.

Nếu một số quy tắc không rõ ràng, hãy tiếp tục và bình luận. Tôi đã lớn lên với trò chơi này, vì vậy thật khó để tôi đánh giá nếu tôi mô tả mọi thứ chi tiết.

Và bây giờ ... Chúc mừng mã hóa!

chỉnh sửa: Như đã chỉ ra cho tôi trong các nhận xét (nhờ vào isaacg), có một quy tắc tính các lần vượt qua hàng đầu sau 4 Jacks vào "Yếu tố Jack" để có thể lên đến 11. Để giữ cho thử thách này đơn giản và để không gây nhầm lẫn cho mọi người, các quy tắc tôi đề xuất ban đầu sẽ vẫn như cũ. Vì vậy, yếu tố tối đa vẫn ở mức 5.


6
Chào mừng bạn đến với Câu đố lập trình & Code Golf, thử thách đầu tiên tuyệt vời! :)
Doorknob

1
Số lượng jack cắm thẳng / jack cắm bị thiếu cũng bao gồm các bộ quần áo hàng đầu theo thứ tự? Đó là những gì wikipedia nói ở đây
isaacg

@isaacg Tôi phải thừa nhận rằng tôi đã không biết về quy tắc này cho đến bây giờ. Cảm ơn đã chỉ ra rằng. Tôi đã làm một số nghiên cứu và bạn thực sự đúng. Trong gia đình tôi, chúng tôi không chơi theo luật này và tôi cũng chưa gặp ai chơi với nó. Nó không có mức độ liên quan cao như vậy, bởi vì khi bạn có một ván bài như vậy, hầu hết mọi lúc bạn sẽ chơi Grand mà được tính khác nhau. Vì vậy, đối với thử thách này, chúng tôi sẽ chỉ ở lại với các quy tắc tôi đề xuất. Tôi sẽ chỉnh sửa bài viết của mình để mọi người rõ ràng.
Denker

1
@DenkerAffe, tôi đã chơi Skat trong nhiều năm tại một câu lạc bộ ở Đức và tin tưởng tôi, luật này rất quan trọng, và có những trường hợp nó cực kỳ phù hợp (và vâng, nó không được biết đến ở hầu hết những người chơi không nghiêm túc). Đặc biệt với mặt còn thiếu - hãy tưởng tượng bạn có át chủ bài K, D, 9, 8, 7 và ba A và hai 10 trong các màu khác. Grand của bạn chắc chắn chết, nhưng bạn có thể chơi 'ohne 6' (thu thập một số contra) và đánh bại họ, giả sử bạn có ý tưởng về cách B đang ngồi trong đấu thầu. Và bạn có thể trả giá cho đến khi mặt trời xuất hiện với thẻ đó.
Aganju

@Aganju Tôi đã cho rằng quy tắc này không được biết đến với hầu hết người chơi sở thích. Cám ơn vì đã xác nhận. Tôi không nghi ngờ rằng điều đó quan trọng nhưng từ kinh nghiệm của tôi như thế này là khá hiếm, vì vậy quy tắc không được áp dụng thường xuyên.
Denker

Câu trả lời:


1

Python 2, ví dụ thực hiện

Vì chưa có bài nộp nào, tôi đã viết ra một ví dụ triển khai trong Python. Định dạng đầu vào giống như trong các thử nghiệm trong thử thách.

Có lẽ điều đó thúc đẩy các bạn đi, không khó lắm :)

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

Đưa đầu vào dưới dạng một mảng các mảng ký tự theo định dạng A4, trong đó 4Câu lạc bộ , 3Spades , 2Trái tim1Kim cương . Đầu ra là 36 4cho một giá thầu 36 với các câu lạc bộ phù hợp với át chủ bài , pđể vượt qua.

Hãy thử trực tuyến tại đây .

Phiên bản bị đánh cắp:

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

Cổng câu trả lời Java của tôi .

Hãy thử trực tuyến tại đây .

Đưa đầu vào dưới dạng một mảng các ký tự ở định dạng A4, trong đó 4Câu lạc bộ , 3Spades , 2Trái tim1Kim cương . Đầu ra là 36 4cho một giá thầu 36 với các câu lạc bộ phù hợp với át chủ bài , pđể vượt qua.

Phiên bản bị đánh cắp:

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
}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.