Poker게임에 사용되는 카드 덱을 OOP로 구현해보자

 

Deck

포커1덱은 모양(4) * 랭크(13) = 52 장의 카드로 구성되어져 있다. 

 

Stack

카드를 썪은후 맨위부터 한장씩 꺼낸다고 해보자

 

썩다 vs 썪다

  • 고기가 썩다
  • 카드를 썪다 ( 셔플 )

 

카드를 바닥에 놓았을때는 자료구조중 Stack과 닮아 있다.

한장씩 사용할때마다 맨위에서 하나씩 꺼내(POP) 사용하면된다.

 

FIFO(First in First Out) , LIFO( Last in First Out ) 인지는 카드를 운영(작동)하는 방식에 따라달라질수 있다.

OOP는 현실세계의 추상적 개념을 반영하는 개발 패러다임이기때문에 현실의 모습을 연상하면 자료구조의 작동방식을

찾아내기가 쉽다.

 

스택은 접시를 의미하며 접시쌓기를 연상하면된다.  설겆이가 끝난 여러개의 접시를 차례로 쌓았서 정리했다고 해보자

( 카드의 경우는 딜러에 의해 최초 카드 생성을 바닥에 놓았을 경우)

 

처리가 먼저 끝난 접시는, 가장아래에 쌓여있기때문에 꺼내기가 어렵다. ( 물론 전체 접시를 든후 빼내면된다 )

마지막에 처리된 접시를 가장 먼저 사용을 하는것이 효율적이며~ 이것을 스택구조라고 하며  LIFO 로 작동된다.

( 마지막 처리된것을 가장 먼저 사용할수 있음 )

 

카드도 맨아래 카드를 빼는것보다 일반적으로 맨위에 카드를 사용하는것이 일반적이기 때문에

모습만 닯았다고 표현을하였다. 카드의 셔플및 덱 운영은 다양할수 있기때문에 LIFO/FIFO로 작동될수 있지만

카드를 바닥에 놓았을때  밑장빼기를 하면안되는 스택구조와 닮아있기 때문에 카드의 자료구조를 Stack으로 채택할수 있다. 

 

카드를 한장씩 공급받고 바로 사용이되면 FIFO 큐 구조처럼 작동되는것 처럼 보일수 있지만 , 이러한 자료구조로 카드게임의 덱이 운영되기는 어렵다. 다만 덱전체를 하나의 요소로 가정하고 덱을 공급하는 경우 FIFO로 작동되는 큐를 채택할수 있다.

 

내가 빙다리 핫바지로 보이냐? : 타짜중 밑장빼기를 저지하는 아귀 - 스택의 규칙을 어기면 큰일난다~

 

Stack을 이용하는데 밑장을 빼면 성능상 느려지기도 하지만 ( 자료구조상 성능이 늦어진다.) 

룰에도 어긋난다. 그래서 자료구조를 이해하는것은 성능과도 연관이 있다.

Deck 구현

그럼 이것을 자바코드로 실제 구현을 해보자 

package game.poker;
import java.util.Collections;
import java.util.Random;
import java.util.Stack;

import game.poker.Card.Suit;

public class Deck
{

    private Stack<Card> cards;
    private Random rand;

    public Deck()
    {
        rand = new Random();
        init();
    }

    public Deck(Random givenGenerator)
    {
        rand = givenGenerator;
        init();
    }

    public Card pop()
    {
        return cards.pop();
    }

    /**
     * Initializes a new deck of 52 cards.
     */
    private void init()
    {
        cards = new Stack<>();
        int index = 0;
        for (int rank = 1; rank <= 13; ++rank)
        {
            cards.push(new Card(rank, Suit.CLUBS));
            cards.push(new Card(rank, Suit.DIAMONDS));
            cards.push(new Card(rank, Suit.HEARTS));
            cards.push(new Card(rank, Suit.SPADES));
        }

        // Todo : Improve Shuffle Rule...
        Collections.shuffle(cards);
    }
}
  • init : 카드를 스택에 쌓는다. 생성된 순으로 push(바닥에 쌓임)

  • shuffle : 카드를 썪어주는 기능을 한다. 난수발생에 커스텀 알고리즘을 적용할수 있으며 확률게임의 신뢰성을 위해 난수검증 자체를 인증하고 인증마크를 부여하는 솔루션도 존재한다.

 

Deck Test

@Test
public void deckTest(){
    Deck deck = new Deck();
    System.out.println(deck.pop());
    System.out.println(deck.pop());
    System.out.println(deck.pop());
}

Nine of HEARTS
King of DIAMONDS
Two of CLUBS

 

위 테스트 코드는 셔플된 카드덱중 맨위 3장을 꺼내며

덱에 포함된 무작위 카드 3장을 뽑는것과 동일하며 덱을 다 사용할때까지만 뽑을수 있기때문에

1덱으로 운영되는 카드자료구조로 사용할수가 있습니다. ( 카드의 중복이나 , 셔플로직을 분리및 운영할수 있음)

덱을 여러개 구성해 N덱을 운영하거나, 덱운영이 아닌 1스테이지 게임후 항상 랜덤을 채택할수도 있습니다.

 

 

  • No labels
Write a comment…