스캇 핸드 평가


18

소개

Skat 는 3 명의 플레이어를위한 전통적인 독일 카드 게임입니다. 데크는 Ace, King, Queen, Jack, 10, 9, 8, 7 등 총 32 가지 카드로 구성됩니다 (클럽, 스페이드, 하트, 다이아몬드).

매 라운드마다 한 명의 플레이어가 솔로 연주하고 다른 두 명의 플레이어가 솔로 연주합니다. 라운드가 시작될 때 각 플레이어는 10 장의 카드를 받고 나머지 2 장의 카드를 스케이트 라고 하며 가운데에 뒤집어 놓습니다. 솔로 플레이어는 입찰 단계에 의해 결정됩니다. 이것은이 도전에서 다루어야 할 게임의 일부입니다. 이에 대한 자세한 내용은 아래에 있습니다.

입찰 단계에서이긴 플레이어는 솔로 플레이어가됩니다. 그는 스카트를 집어 든 다음 두 장의 카드를 떨어 뜨립니다 (동일한 팀은 알지 못함).

한 라운드는 10 개의 트릭으로 구성됩니다. 트릭을이긴 플레이어는 모든 카드가 재생 될 때까지 다음 트릭을 이깁니다. 여기서 규칙을 설명하지는 않지만 많은 트럼프 카드를 사용하는 것이 좋습니다. 규칙에 대해 배우고 싶다면이 게시물의 시작 부분에 링크 된 Wikipedia 기사를 확인하십시오. 그러나이 도전에는 필요하지 않습니다.

도전

당신은 두 아들에게 스카트를하는 법을 가르치기를 원합니다. 규칙은 그렇게 어렵지 않으므로 신속하게 적용됩니다. 그들에게 힘든 시간을주는 유일한 것은 입찰, 특히 손의 게임 가치를 계산합니다. 그래서 당신은 그들이 현재의 손으로 주어진 입찰 할 수있는 최대 게임 가치를 출력하는 작은 프로그램을 작성하기로 결정합니다.

게임 가치 계산

모든 핸드에는 특정 게임 가치가 있습니다. 그것은 당신이 가지고있는 순차 잭의 양과 트럼프로 선택하고자하는 슈트에 의해 결정됩니다. 첫 번째 요소 인 잭부터 시작하겠습니다!

잭 팩터

잭은 항상 트럼프 카드이며 다른 모든 트럼프 카드를 이깁니다. 4 개의 잭 사이의 강도 순서는 다음과 같습니다.

  1. 클럽 잭 (가장 높음)
  2. 스페이드 잭
  3. 하트 잭
  4. 잭 오브 다이아몬드 (가장 낮음)

추가 설명에서 나는 여기에 그들에게 할당 된 번호로 그들을 참조 할 것입니다.

당신은 게임 가치의 일부인 잭에서 당신이 얻는 어떤 종류의 요소가 있다는 것을 기억합니까? 큰! 얻는 방법은 다음과 같습니다.

이 잭 팩터는 순서대로 상단 잭 수 (위 순서 참조)에 1을 더한 값입니다. 따라서 4 개의 잭이 모두 있으면 4 + 1 = 5입니다. 처음 2 개의 잭만있는 경우 2 + 1 = 삼.

또는, 좀 더 일을 복잡하게 만들기 위해 잭 요인은 또한 당신이 것을 순서대로 상위 잭의 숫자가 될 수 없는 첫 번째 하나를 누락하는 경우에 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

이것이 첫 번째 요소였습니다. 두 번째 방법은 다음과 같습니다.

트럼프 슈트 팩터

이것은 훨씬 간단합니다. 두 번째 요소는 솔로 플레이어가 다음 매핑을 사용하여 선택하는 트럼프 슈트에 의해 결정됩니다.

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

쉽지 않았습니까?

게임 가치

게임 가치는 두 가지 요소의 곱입니다. 꽤 쉽게 생각하십니까? 잘못된! Jack-Factor는 고정되어 있지만 적합 요인은 없습니다. 트럼프로 선택하는 소송은 트럼프의 양과 비 트럼프 카드의 가치에 달려 있습니다. 좋은 손 모양을 설명하기에는 너무 복잡하므로 다음 알고리즘을 사용합니다.

어느 트럼프-도 -I- 픽 알고리즘

입찰에 참여하지 않아도됩니다. 당신의 손이 솔로 연주하기에 너무 나쁘다고 결정하면 그냥 지나칠 수 있습니다. 플레이하려면 손이 다음 기준과 일치해야합니다.

  • 적어도 6 개의 트럼프 카드 (선택한 트럼프 카드 + 잭 수)가 있어야합니다. 한 벌 이상이 가능하다면 더 많은 카드를 얻을 수있는 것을 선택하십시오. 여전히 넥타이 가 있다면 위에 주어진 등급이 가장 높은 슈트를 선택하십시오.

  • 트럼프가 아닌 카드 중에서 하나 이상의 에이스가 있어야합니다.

당신의 손이이 두 기준에 맞지 않으면 통과 할 것입니다. 그렇다면 계산 된 게임 값과 선택한 트럼프 슈트를 출력합니다.

짧은 참고 : 물론 이것은 매우 단순화 된 알고리즘입니다. 이와 같은 도전에서 다룰 수있는 것보다 손을 판단하기에는 너무 많은 전략과 경험이 있습니다.

입력

모든 카드에는 고유 식별자가 있습니다. 첫 번째 부분은 슈트 (인 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"를 출력하십시오.

규칙

  • 언급 한 바와 같이 가장 편리한 형식으로 입력 할 수 있습니다. 예제는 아래 테스트 사례를 참조하십시오.
  • 입력은 명령 행 인수, 사용자 입력 또는 함수 인수로 제공 될 수 있습니다.
  • 출력은 반환 값으로 제공되거나 화면에 인쇄 될 수 있습니다.
  • 입력 된 카드는 어떤 방식으로도 주문할 수 없습니다. 프로그램은 임의의 카드 주문을 처리 할 수 ​​있어야합니다.
  • 최저 바이트 수 승리!

테스트 케이스

테스트 사례의 입력은 2 자 문자열 목록입니다.

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. 스페이드와 함께 행에서 3 개의 잭이 트럼프로 누락되었습니다. 게임 값은 4 x 11 = 44입니다
  3. 트럼프 카드는 최대 4 개만 가능하므로 합격하십시오.
  4. 스페이드가 있지만 트럼프가 아닌 에이스가없는 6 개의 트럼프 카드이므로 통과 할 수 있습니다.

일부 규칙이 명확하지 않은 경우 계속해서 의견을 말하십시오. 나는이 게임으로 자랐기 때문에 모든 것을 충분히 자세하게 묘사했는지 판단하기가 어렵다.

그리고 지금 ... 행복한 코딩!

편집 : 의견 (isaacg 덕분에)에서 지적했듯이, 4 개의 잭 다음에 "잭 팩터"로 다음 상위 트럼프를 계산하여 11까지 올라갈 수있는 규칙이 있습니다. 사람들을 혼동하지 않기 위해 원래 제안한 규칙은 그대로 유지됩니다. 따라서 최대 계수는 5로 유지됩니다.


6
프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다 – 탁월한 첫 번째 도전! :)
Doorknob

1
직선형 잭 / 누락 된 잭의 수에 상단 슈트 트럼프도 순서대로 포함해야합니까? 무엇 위키 피 디아의 말씀 즉, 여기
isaacg

@isaacg 나는 지금 까지이 규칙에 대해 몰랐 음을 인정해야합니다. 지적 해 주셔서 감사합니다. 나는 약간의 연구를했다. 그리고 당신은 정말로 옳다. 우리 가족은이 규칙을 따르지 않으며 그 규칙을 가진 사람도 만나지 않았습니다. 그것은 당신이 그런 손을 가질 때, 당신은 어쨌든 다르게 계산되는 대부분의 그랜드를 할 것이기 때문에 그 높은 관련성을 가지고 있지 않습니다. 따라서이 과제를 위해 우리는 내가 제안한 규칙을 그대로 따릅니다. 내 게시물을 편집하여 모든 사람이 알 수 있도록합니다.
Denker

1
@ DenkerAffe, 나는 독일의 클럽에서 수년간 Skat을 뛰었고, 나를 믿고, 규칙이 중요하며 그것이 매우 관련이있는 경우가 있습니다 (그렇습니다. 특히 잃어버린 면-K, D, 9, 8, 7과 다른 색으로 3 A와 2 10을 능가한다고 가정하십시오. 당신의 그랜드는 확실히 죽지 만, B가 입찰에서 어떻게 앉아 있는지에 대한 아이디어가 있다고 가정하면, 당신은 'ohne 6'(일부 콘트라를 수집)을하고 그들을 이길 수 있습니다. 그리고 당신은 태양이 그 카드를 떠날 때까지 입찰 할 수 있습니다.
Aganju

@ 아 간주 (Aganju) 나는 이미이 규칙이 대부분의 취미 선수들에게는 모른다고 가정했다. 확인 감사합니다. 나는 그것이 중요하다는 것을 의심하지는 않지만, 내 경험으로는 이와 같은 손이 매우 드물기 때문에 규칙이 자주 적용되지 않습니다.
Denker

답변:


1

파이썬 2, 예제 구현

아직 제출물이 없기 때문에 파이썬으로 구현 예제를 작성했습니다. 입력 형식은 챌린지의 테스트 케이스와 동일합니다.

어쩌면 그것은 당신이 갈 수 있도록 동기를 부여합니다, 그렇게 어렵지는 않습니다 :)

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

자바, 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이다 스페이드 , 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);}

내 자바 답변 포트 .

여기에서 온라인으로 사용해보십시오 .

형식의 문자 배열로 입력을 받아 A4, 4클럽 , 3이다 스페이드 , 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.