ประเมิน Skat-Hand


18

บทนำ

Skatเป็นเกมไพ่เยอรมันแบบดั้งเดิมสำหรับผู้เล่น 3 คน สำรับประกอบด้วย 32 ใบ: Ace, King, Queen, Jack, 10, 9, 8, 7 ในทั้งหมด 4 ชุด (Clubs, Spades, Hearts, Diamonds)

ในทุก ๆ รอบมีผู้เล่นคนเดียวเล่นคนเดียวในขณะที่อีกสองคนเล่นกับเขา ในช่วงเริ่มต้นของรอบผู้เล่นแต่ละคนจะได้รับไพ่ 10 ใบส่วนที่เหลืออีก 2 ใบเรียกว่าskatและวางคว่ำลงตรงกลาง ผู้เล่นเดี่ยวจะถูกกำหนดโดยขั้นตอนการเสนอราคา นี่เป็นส่วนหนึ่งของเกมที่คุณจะต้องจัดการกับความท้าทายนี้โดยมีรายละเอียดเพิ่มเติมด้านล่างนี้

ผู้เล่นที่ชนะช่วงประมูลจะกลายเป็นผู้เล่นเดี่ยว เขาหยิบรองเท้าสเก็ตแล้วหยดการ์ดสองใบ (ซึ่งอาจเหมือนกันทีมอื่นไม่รู้) หยิบชุดทรัมป์และเริ่มรอบ

หนึ่งรอบประกอบด้วยสิบเทคนิค ผู้เล่นที่ชนะเคล็ดลับนำไปสู่คนต่อไปจนกว่าจะเล่นไพ่ทั้งหมด ฉันจะไม่อธิบายกฎที่นี่ แต่คุณควรรู้ว่าการมีไพ่คนดีมาก หากคุณต้องการเรียนรู้เกี่ยวกับกฎตรวจสอบบทความ Wikipedia ที่ฉันเชื่อมโยงในตอนต้นของโพสต์นี้ แต่มันไม่จำเป็นสำหรับความท้าทายนี้

ความท้าทาย

คุณต้องการสอนลูกสองคนถึงวิธีการเล่นสเกต กฎนั้นไม่ยากดังนั้นพวกเขาจึงรีบเข้าไป สิ่งเดียวที่ทำให้พวกเขาลำบากคือการประมูลโดยเฉพาะการคำนวณมูลค่าเกมในมือของพวกเขา ดังนั้นคุณตัดสินใจที่จะเขียนโปรแกรมขนาดเล็กซึ่งแสดงมูลค่าของเกมสูงสุดที่พวกเขาสามารถเสนอราคาได้เมื่อมือนั้น

การคำนวณมูลค่าของเกม

ทุกมือมีค่าเกมที่แน่นอน มันถูกกำหนดโดยปริมาณของแจ็คตามลำดับที่คุณมีและชุดที่คุณต้องการเลือกเป็นคนดี เริ่มจากปัจจัยแรกแจ็ค!

ปัจจัยแจ็ค

แจ็คมักจะเป็นคนที่กล้าหาญไพ่และพวกเขาเอาชนะทุกคนที่กล้าหาญ ลำดับความแข็งแกร่งระหว่างแจ็คทั้งสี่คือ:

  1. Jack of Clubs (สูงสุด)
  2. แจ็คโพดำ
  3. แจ็คออฟฮาร์ตส์
  4. Jack of Diamonds (ต่ำสุด)

ในคำอธิบายเพิ่มเติมฉันจะอ้างถึงพวกเขาด้วยตัวเลขที่ฉันได้รับพวกเขาที่นี่

คุณจำได้ไหมว่ามีปัจจัยบางอย่างที่คุณได้รับจากแจ็คในมือของคุณซึ่งเป็นส่วนหนึ่งของมูลค่าของเกม? ที่ดี! นี่คือวิธีที่คุณได้รับ:

แจ็คตัวคูณนี้คือจำนวนแจ็คยอดนิยม (ดูลำดับด้านบน) ตามลำดับบวก 1 ดังนั้นถ้าคุณมีแจ็คทั้งหมด 4 ตัวมันคือ 4 + 1 = 5 หากคุณมีแจ็คแรกเพียง 2 ตัวนั่นคือ 2 + 1 = 3

อีกทางหนึ่งเพื่อให้สิ่งต่าง ๆ มีความซับซ้อนยิ่งขึ้นแจ็คแฟคเตอร์อาจเป็นจำนวนแจ็คอันดับสูงสุดตามลำดับที่คุณหายไปบวก 1 ดังนั้นหากคุณพลาดอันดับแรกก็คือ 1 + 1 = 2 หากคุณ หายไปตอนแรกเขาที่ 3 คือ 3 + 1 = 4 นี่คือตัวอย่างบางส่วนโดยใช้ตัวเลขด้านบน:

[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

นั่นเป็นปัจจัยแรก นี่คือวิธีที่คุณจะได้รับอันดับที่สอง:

ปัจจัย Trump Suit

อันนี้ง่ายกว่ามาก ปัจจัยที่สองถูกกำหนดโดยชุดทรัมป์ที่ผู้เล่นเดี่ยวเลือกโดยใช้การแมปต่อไปนี้:

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

นั่นเป็นเรื่องง่ายใช่มั้ย

คุณค่าของเกม

มูลค่าของเกมเป็นผลคูณของสองปัจจัย ค่อนข้างง่ายที่คุณคิด ไม่ถูกต้อง! ในขณะที่แจ็ค - แฟคเตอร์ได้รับการแก้ไขแล้ว ชุดที่คุณเลือกเก็บท้ายที่สุดคือทรัมป์ขึ้นอยู่กับปริมาณของปั้นและมูลค่าของการ์ดที่ไม่ใช่ของทรัมป์ในมือของคุณ มันจะซับซ้อนเกินไปที่จะอธิบายว่ามือที่ดีนั้นเป็นอย่างไรดังนั้นคุณจะใช้อัลกอริทึมต่อไปนี้:

อัลกอริทึมแบบไหนที่ต้องทำเลือก

คุณไม่จำเป็นต้องมีส่วนร่วมในการเสนอราคา หากคุณตัดสินใจว่ามือของคุณแย่เกินกว่าจะเล่นเดี่ยวคุณก็สามารถผ่านได้ มือของคุณจะต้องตรงกับเกณฑ์ต่อไปนี้เพื่อให้สามารถเล่นได้:

  • มีไพ่อย่างน้อย 6 ใบ (ไพ่ของทรัมป์ที่คุณเลือก + จำนวนแจ็ค) หากเป็นไปได้สำหรับชุดสูทมากกว่าหนึ่งชุดให้เลือกชุดที่จะส่งผลให้มีไพ่ดีกว่า หากยังมีเน็คไทให้เลือกสูทที่มีคะแนนสูงสุดตามที่ระบุไว้ด้านบน

  • จากไพ่ที่ไม่ใช่ของทรัมป์มีอย่างน้อย 1 เอซ

หากมือของคุณไม่ตรงกับเกณฑ์ทั้งสองนี้คุณจะผ่าน ถ้าเป็นเช่นนั้นคุณจะส่งออกมูลค่าเกมที่คำนวณได้และชุดทรัมป์ที่เลือก

บันทึกย่อ: แน่นอนว่านี่เป็นอัลกอริทึมที่ง่ายมาก มีกลยุทธ์และประสบการณ์มากเกินไปในการตัดสินมือเกินกว่าที่เราจะสามารถรับมือกับความท้าทายเช่นนี้

อินพุต

บัตรทุกใบมีตัวระบุที่ไม่ซ้ำกัน ส่วนแรกคือชุดสูท ( C lubs, S pades, H earts, D iamonds) ส่วนที่สองคือค่าที่ได้จากการทำแผนที่นี้:

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

ทั้งสองส่วนรวมกันเป็นการ์ดใบเดียว ค่ามาก่อนแล้วจึงมาสูท คุณสามารถนำไพ่ในรูปแบบใดก็ได้ตามที่คุณต้องการ

เอาท์พุต

หากมือสามารถเล่นได้ให้ส่งออกมูลค่าของเกมและชุดทรัมป์ที่หยิบ (ลำดับไม่สำคัญ) ถ้าไม่ใช่ให้เอาท์พุท "pass"

กฎระเบียบ

  • ตามที่กล่าวไว้คุณสามารถรับอินพุตในรูปแบบที่สะดวกที่สุดสำหรับคุณ ตัวอย่างดูด้านล่างในกรณีทดสอบ
  • อินพุตอาจมีให้โดยอาร์กิวเมนต์บรรทัดคำสั่งอินพุตของผู้ใช้หรืออาร์กิวเมนต์ของฟังก์ชัน
  • อาจให้เอาท์พุทเป็นค่าตอบแทนหรืออาจจะพิมพ์บนหน้าจอ
  • การ์ดในอินพุตอาจไม่สามารถสั่งซื้อได้ไม่ว่าด้วยวิธีใด โปรแกรมของคุณจะต้องสามารถจัดการกับการสั่งซื้อบัตรแบบสุ่มใด ๆ
  • การนับจำนวนไบต์ที่ต่ำที่สุด!

Testcases

อินพุตในกรณีทดสอบจะเป็นรายการของ 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

คำอธิบาย:

  1. แจ็คสองตัวติดต่อกันกับสโมสรในฐานะคนที่กล้าหาญ ดังนั้นมูลค่าของเกมคือ 3 x 12 = 36
  2. สามแจ็คในแถวหายไปโดยมี Spades เป็นคนดี ดังนั้นมูลค่าของเกมคือ 4 x 11 = 44
  3. มีการ์ดทรัมป์สูงสุด 4 ใบเท่านั้นดังนั้นคุณจะผ่านได้
  4. ไพ่ทรัมป์หกใบที่มีโพดำ แต่ไม่มีเอซที่ไม่ใช่คนที่กล้าหาญดังนั้นคุณจะผ่าน

หากกฎบางอย่างไม่ชัดเจนให้ไปข้างหน้าและแสดงความคิดเห็น ฉันโตมากับเกมนี้มันจึงยากสำหรับฉันที่จะตัดสินว่าฉันอธิบายทุกอย่างในรายละเอียดเพียงพอ

และตอนนี้ ... Happy Coding!

แก้ไข:ตามที่ฉันเห็นในความคิดเห็น (ขอบคุณ isaacg) มีกฎที่นับยอดปั้นต่อไปนี้หลังจาก 4 Jacks เป็น "Jack-factor" ดังนั้นมันจึงสามารถสูงถึง 11 เพื่อให้ความท้าทายนี้ง่าย และเพื่อไม่ให้ผู้คนสับสนกฎที่ฉันเสนอไว้ในตอนแรกจะยังคงเหมือนเดิม ดังนั้นปัจจัยสูงสุดอยู่ที่ 5


6
ยินดีต้อนรับสู่ Programming Puzzles & Code Golf— ความท้าทายแรกที่ยอดเยี่ยม! :)
Doorknob

1
จำนวนแจ็คแบบตรง / แจ็คที่หายไปควรรวมชุดทรัพสูทยอดนิยมตามลำดับหรือไม่ นั่นคือสิ่งที่วิกิพีเดียพูดที่นี่
isaacg

@isaacg ฉันต้องยอมรับว่าฉันไม่รู้เกี่ยวกับกฎนี้จนกระทั่งตอนนี้ ขอบคุณสำหรับการชี้ให้เห็นว่า ฉันทำวิจัยแล้วและคุณพูดถูก ในครอบครัวของฉันเราไม่ได้เล่นกับกฎนี้และฉันไม่ได้พบใครที่เล่นด้วยเช่นกัน มันไม่ได้มีความเกี่ยวข้องสูงเช่นนั้นเพราะเมื่อคุณมีมือคุณจะเล่น Grand ซึ่งส่วนใหญ่จะนับว่าแตกต่างกันอยู่แล้ว ดังนั้นสำหรับความท้าทายนี้เราจะอยู่กับกฎที่ฉันเสนอ ฉันจะแก้ไขโพสต์ของฉันดังนั้นจึงเป็นที่ชัดเจนสำหรับทุกคน
Denker

1
@ DenkerAffe ฉันเล่น Skat เป็นเวลาหลายปีในสโมสรในเยอรมนีและเชื่อใจฉันกฎเป็นสิ่งสำคัญและมีบางกรณีที่มีความเกี่ยวข้องมาก (และใช่เป็นที่รู้จักในผู้เล่นที่ไม่จริงจังที่สุด) โดยเฉพาะอย่างยิ่งกับด้านที่ขาดหายไป - ลองจินตนาการว่าคุณมีคนที่กล้าหาญ K, D, 9, 8, 7 และสาม A และอีกสอง 10 สี แกรนด์ของคุณตายแน่นอน แต่คุณสามารถเล่น 'ohne 6' (รวบรวมบางส่วน) และเอาชนะพวกเขาโดยสมมติว่าคุณมีความคิดว่า B กำลังนั่งจากการเสนอราคาอย่างไร และคุณสามารถประมูลจนถึงพระอาทิตย์ขึ้นด้วยการ์ดใบนั้น
แกนจู

@Aganju ฉันคิดไปแล้วว่ากฎนี้ไม่เป็นที่รู้กันสำหรับผู้เล่นงานอดิเรกส่วนใหญ่ ขอบคุณสำหรับการยืนยัน ฉันไม่สงสัยเลยว่ามันเป็นสิ่งสำคัญ แต่จากประสบการณ์ของฉันมือนี้ค่อนข้างหายากดังนั้นกฎไม่เข้ามาเล่นที่มักจะ
Denker

คำตอบ:


1

Python 2 ตัวอย่างการนำไปใช้

เนื่องจากยังไม่มีการส่งฉันจึงเขียนตัวอย่างการใช้งานใน Python รูปแบบการป้อนข้อมูลเหมือนกับในการทดสอบในความท้าทาย

บางทีนั่นอาจเป็นแรงบันดาลใจให้พวกคุณก้าวไปข้างหน้าไม่ใช่เรื่องยาก :)

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 ไบต์

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

จะเข้าเป็นอาร์เรย์ของอาร์เรย์ตัวละครในรูปแบบA4ที่4เป็นคลับ , 3เป็นSpades , 2เป็นหัวใจและ1เป็นเพชร ผลผลิตเป็นที่36 4สำหรับการเสนอราคา 36 กับชุดคนดีคลับ , 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 ไบต์

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 ของฉันคำตอบ

ลองออนไลน์ได้ที่นี่

จะเข้าเป็นอาร์เรย์ของตัวละครในรูปแบบA4ที่4เป็นคลับ , 3เป็นSpades , 2เป็นหัวใจและ1เป็นเพชร ผลผลิตเป็นที่36 4สำหรับการเสนอราคา 36 กับชุดคนดีคลับ , 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
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.