포커 핸드가 똑바로 있는지 여부를 결정하는 기능?
-
22-08-2019 - |
문제
숙제를 위해 나는 순위와 소송에 대한 유형을 열거 한 카드 수업을 받았다. 나는 두 개의 포커 손을 비교해야합니다 (각 손은 ArrayList
5 장의 카드) 및 승자를 결정하십시오.
그만큼 isStraight()
에이스 이후 수를 시작해야하기 때문에 기능은 정말로 나를 괴롭 힙니다. 예를 들어,
여왕, 왕, 에이스, 둘, 셋
여전히 똑바로 간주됩니다. 이 기능을 코딩하는 가장 좋은 방법은 무엇입니까?
도움이된다면 순위/소송 열거 형 유형 코드는 다음과 같습니다.
public enum Rank
{
TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9),
TEN(10), JACK(11), QUEEN(12), KING(13), ACE(14);
private final int points;
private Rank(int points)
{
this.points = points;
}
public int points()
{
return this.points;
}
}
public enum Suit
{
DIAMONDS, CLUBS, HEARTS, SPADES;
}
해결책
당신은 내가 연기 한 포커 게임의 규칙에 따라 똑바로 연주하거나 들어 본 적이 없다는 것을 알고 있습니까? 에이스는 [A, 2,3,4,5] 또는 높음 [10, J, Q, K, A] 일 수 있지만 포장 할 수는 없습니다. 그 규칙 (당신이 아님)에 따르면 나는 이전에 비슷한 것을 구현했습니다. 기본적으로 배열을 정렬하고 걸어서 현재 카드가 이전 카드보다 높습니다. 첫 번째 반복에서 ACE라면 [A, 2,3,4,5]를 명시 적으로 확인합니다. 그것이 당신이 진실을 돌려주고 그렇지 않으면 정상적인 직선 논리를 계속합니다. 이것은 당신을 올바른 방향으로 설정해야합니다.
다른 팁
일반적으로 포커 핸즈를 해결하기위한 좋은 접근 방식은 비트 ((rank-2)*2) 비트 세트와 비트 (Suit+28) 세트로 비트 값을 할당하는 것입니다. , 4 = 16 등. 최대 a = 0x1000000). 그런 다음 모든 카드를 추가하십시오 (결과 'sum'을 호출하십시오. compute v1 = (sum & 0x2aaaaaa) >> 1, v0 = (sum & 0x1555555) 및 v2 = v1 & v0. 및 계산 v3 = orvalue & 0xf0000000;
- 쌍의 경우 v1에는 단일 비트 세트가 있고 V0은 여러 비트 세트가 있고 V2는 0이됩니다.
- 2 쌍의 경우 v1에는 2 개의 비트 세트가 있고 v2는 0과 같습니다.
- 세 가지의 경우 V1은 단일 비트 세트를 갖고 V2는 V1과 같습니다.
- 직선의 경우 V0은 0x1000055 또는 그렇지 않으면 0x155의 두 배수의 배수입니다.
- 플러시의 경우 v2는 정확히 하나의 비트 세트를 갖습니다.
- 풀 하우스의 경우 v1에는 두 개의 비트 세트가 있고 V2는 0이 아닙니다.
- 네 가지의 경우, V1은 두 배의 V0이 될 것이며, 둘 다 1 개의 비트 세트를 가지거나 V0은 정확히 2 개의 비트 세트가 있고 V1은 0이됩니다.
- 직선 플러시의 경우 직선 및 플러시 조건이 충족됩니다.
이 접근법에 필요한이 테스트는 최소한의 분기로 빠르게 구현할 수 있어야합니다.
가능한 카드의 수에도 불구하고 True를 반환하기 위해 멋진 알고리즘을 작성할 수 있지만 정렬 된 손에 10 개의 유효한 조합 만 있다는 것을 알고 있다면 다음을 찾을 수 있습니다.
2-6, 3-7, 4-8, 5-9, 6-T, 7-J, 8-Q, 9-K, T-A, (2-5,A)
목록에는 5 개의 카드 만 있으므로 정렬하고 2 개의 연속 카드의 차이를 결정할 수 있습니다. ACE가 포함되어 있으면 카드도 낮은 카드로 고려해야합니다. 모든 차이가 1 (또는 정렬 순서에 따라 -1, -1) 인 경우 직선이 있습니다.
나는 그 순위의 정의를 감안할 때, 그 똑바로는 최대의 에이스 .points () - 4로만 시작할 수 있다고 주장합니다.
따라서 손을 분류하고 가장 낮은 순위가> ace.points () -4라면 똑바로 가질 수 없습니다. 그렇지 않으면 각 카드가 이전 순위 + 1임을 확인하기 위해 손을 반복합니다.
에이스가 높거나 낮을 수 있다면 Shs 대답 한 내용으로 가십시오.
내부 루프를 사용하면 매우 사소한 일입니다. 도전은 내부 루프없이 수행하는 것입니다 ...
또한 선생님이나 선생님이 게임의 규칙을 오해 (또는 잘못 표현한) 이해했는지에 따라 다릅니다.
나는 배열을 만들고 [2..14], 카드를 그들의 순위에 해당하는 위치에 놓으려는 유혹을 받고 있다고 생각합니다. 중복에 부딪히면 직선이 아니며 완료되면 8 개의 공간이 있어야합니다. 연속 8 개 미만의 공간이 있다면 직선이 아닙니다.
내가 제시 할 수있는 다른 모든 솔루션에는 내부 루프가 필요하며 내부 루프는 존경할만한 프로그래머가 될 때마다 피해야 할 조잡한 프로그래밍 중 하나입니다.
편집 : 또한 교사를 오해하고 유일한 포장 조건이 "10, j, q, k, a"(실제 규칙에서와 같이)라면 2, 13 및 14가 모두 인 경우 추가 테스트가 필요합니다. 세트, 그것은 또한 실패입니다 (2-AK 랩 어라운드).
(질문을 다시 읽은 후 14로 ACE의 1을 교체하기 위해 다시 편집)
나는 열거적 인 상수를 많이 사용하지 않고, 이름이 상수를 선호하지만 "에이스"에서 "14"로 가면 사소하다고 가정 할 것입니다.
나는 실제 Java 코드를 작성하기에는 너무 게으르다 (당신 옆에는 실제로 숙제를해야합니다 ^^)
check if the list has 5 cards
convert card names to a card number list named array
sort the list array
for i=1 to 4
if not (array[i] + 1) % 13 == (array[i+1]) % 13
then it is not a straight
% 연산자는 Modulo라고 불립니다 (15 % 13) == 2 나는 "Wrap Over"Challenge에 직면 할 때 마다이 연산자를 사용합니다.
편집 : 질문을 다시 읽은 후 내 솔루션은 상자에서 벗어날 수 없습니다. 열 열거를 재정렬하여 2 == 0
비트 벡터를 사용하여 카드를 나타냅니다. 이것은 분류를 피할 필요가 없습니다. 에이스를 두 번 추가 할 수 있습니다 (한 번은 1 번으로 왕으로 1 번) 또는 2가 설정되어 있는지 확인하기 전에 에이스 비트가 설정되어 있는지 확인하여 시작 상황을 특별 사례로 할 수 있습니다). 속도가 중요한 경우 큰 룩 업 테이블을 구축 할 수 있습니다. 이 접근법은 또한 스케일을 청소하여 나머지 손 (플러시, 2 쌍, 풀 하우스, 여행 등)을 찾습니다. 또한 주어진 직선이 다른 것보다 높는지 쉽게 파악할 수 있습니다. 그리고 7 카드 평가자로 깨끗하게 확장됩니다
의사 코드에서는 매우 일반적인 경우에 이와 같은 것이 보입니다 (카드가 많을 수 있습니다. 첫 번째 직선을 반환합니다).
long cardBitMask
for each card in hand
setBit in cardBitMask
hearts = mask(cardBitMask)
diamonds = mask(cardBitMask)
clubs = mask(cardBitMask)
spades = mask(cardBitMask)
// find straight
uniqueCards = hearts|diamonds|clubs|spades
int cardsInaRow = 0
if uniqueCards&AceCardMask:
cardsInaRow = 1
for card = 2...King
if uniqueCards&(1<<card)
cardsInARow++
else
if cardsInARow == 5
break
cardsInARow = 0
if cardsInARow==5:
return true
return false
목록에 두 번 모든 순위를 추가하십시오. 그런 다음 손이 똑바로 있는지 확인하려면 손을 순위별로 정렬 한 다음 손이 그 목록의 하위 목록인지 확인하십시오.
모든 카드를 특정 카드 값으로 변환하는 클래스를 쓸 수 있습니다.
조커 = 11 퀸 = 12 킹 = 13 에이스 = 0 또는 14
카드 처리와 가능한 손을 찾기가 훨씬 쉬워집니다.