- Pygame – TexasHoldem 만들기 – 기초학습
- Pygame – TexasHoldem 만들기 – 싱글 플레이 Version
- Pygame – TexasHoldem 만들기 – 멀티 플레이 Version
이번 포스트에서는 싱글 플레이어 기반의 Stand-Alone 형태의 단순히 패를 비교해서 승자를 보여주는 식의 Texas-Holdem 의 내용에 대해서 다룬다. 작년에 만든 것으로 Betting 이 없기 때문에 사용자의 개입 없이 자동으로 패가 섞인 후에, 승자를 보여주고 자동으로 다음 Round 로 넘어가는 식이다. 혹시 Texas-Holdem Poker 에 대해 생소하신 분들을 위해 아래 동영상을 참고하길 바란다.
1. Texas Holdem’ Play Rule
Texas Holdem Poker 는 각 Round 가 PreFlop > Flop > Turn > River > ShowDown 로 구성되어 있으며, Player 별로 각각 2장의 Card 가 배부된다. 공통 Card 를 Community Card 라고 부르며, Flop, Turn, River 단계에서 Community Card 가 공개된다. 각 Player 는 매 단계마다 Betting 을 한다. 이번 포스트에서는 Betting 은 생략되어 있으므로 Betting 에 대한 자세한 설명은 다음 포스트에서 하기로 하자. ShowDown 단계에서는 최종적으로 남아 있는 Player 들의 패가 공개되고, 각자의 패 중에서 가장 최고의 패끼리 비교하여 우위에 있는 Player 가 최종 승자가 된다. 승자는 Betting 하여 Pot 에 저장된 돈을 전부 가져간다.
게임 구현을 위해 사용된 용어와 각 단계에 대해서 정리해 보면, 다음과 같다.
- Game : 전체 게임, 각 Round 가 반복된다.
- Player : Game 에 참여하는 참여자
- Round : 매 Round 는 PreFlop > Flop > Turn > River > ShowDown 의 개별 단계로 구성되어 있다. 각 Round 마다 승자(Winner) 가 결정된다.
- Stage : Round 의 각 단계를 지칭한다.
- PreFlop : 각 Round 의 최초 단계이며, 이 때 각 Player 에게 2장의 Card 가 배부된다.
- Flop : Community Card 3장이 모두에게 공통으로 공개되는 단계이다.
- Turn : Community Card 1장이 추가되어, 총 4장이 공개되는 단계이다.
- River : Community Card 1장이 추가되어, 총 5장이 공개되는 단계이다.
- ShowDown : 살아남은 Player 들끼리 최고 패(Best Hands) 를 비교하여 해당 Round 의 승자 (Winner) 를 정하는 단계
- Hands : 패의 다른 말. ShowDown 단계에서는 Player 자신이 갖고 있는 2개의 패 이외에 Community Card 5장을 더해서 7장 중에 최고 조합을 만든다.
- Deck : 카드 52장을 담고 있는 보관소. 매 Round 마다 섞는다. 4종류의 Suit [clubs (♣), diamonds (♦), hearts (♥), spades (♠)] 와 각 Suit 는 13장의 Rank 를 갖는다.
- Suit : 4 종류의 문양. 일반적으로 spades (♠) → diamonds (♦) → hearts (♥) → clubs (♣) 순으로 높다.
- Rank : 9개의 숫자 카드와 4개의 문자 카드가 있다. Ace (A), 2, 3, …, 10, J, Q, K 순인데 A 는 Straight 의 1 로 되면서도 K 뒤에 설 수도 있다.
- Pot : Betting 된 돈을 모아 놓는 임시 저장소
- Hand Ranking : 승자 비교시 확률이 낮은 순으로 높은 Ranking 을 갖게 되어 있다. 자세한 내용은 여기 를 참조하자.
2. Mediator Pattern
게임을 만들기 위해서 참조한 곳은 여기 다. 이 저자의 Blog 를 통해서 Mediator (중재자) Pattern 을 사용하였다. 저자의 주장대로 코드가 증가할 수록 코드가 스파게티화가 될 가능성이 높아서 중재자 패턴을 사용하는 것을 권장했다. 하지만, 아이러니하게도 멀티 플레이 모드에서 도저히 이 패턴을 사용하기 힘들어서 다음 포스트에 다루는 멀티 플레이 모드에서는 사용하지 않았다.
이 패턴은 다음과 같은 형태로 표현된다. (저자 Blog 이미지)
위의 그림에서 Mediator ; 중간자(중재자)는 Event Manager 가 담당한다. 이 중재자는 등록된 Listener 들에게 다른 Object 의 상태 변경을 전달해 준다. 해당 Object 는 얼마나 많은 Listener 가 있는지 몰라도 되며 Listener 들은 동적으로 해제되거나 할당 가능하다. 모든 Object 들은 EventManager 에게 해당 Event 들을 전달한다. 어떤 Object 들이 event 들을 수신받기 원한다면 반드시 등록절차를 거쳐야 한다. 우리는 weakref WeakKeyDictionary class 를 사용하여 구현할 수 있다. (명시적으로 해제하지 않아도 되게끔)
Event Manager Code 와 Controller 와 View Code 를 한눈에 합친 것은 각각 다음과 같다. (저자 Blog 발췌)
3. Class design & Implementation
Mediator Pattern 을 사용하여 Keyboard Event 를 보고하고, 매 Tick 의 발생을 보고하여 게임이 진행되도록 한다. 해당 Input 들은 (Keyboard Input, Tick Event) Game 와 PygameView 클래스에 전달되어 게임의 논리적인 진행과 시각화를 담당하게 된다.
게임 구현을 위한 Class 들을 그림으로 정리해 보면 다음과 같다.
간단히 설명을 하자면,
- Sprites : Pygame 의 Sprite 객체로 그룹화된 그리기 객체로 생각하면 된다. 이 게임에서는 Card 와 Text, Table, 사각형 등을 그리고 전체를 관장하는 PygameView 클래스가 있다.
- Mediator : Event Manager 가 Post, Notify 를 담당한다.
- Controllers : Keyboard 입력과 Game 진행, Tick Event 발생기로 이루어 진다.
- Events : Event Manager 를 통해 입력되고 전파되는 모든 종류는 Event 로 정의된다.
- CardCommon : 게임 진행을 위한 패(Hands) 비교나 Card, Player, Deck, Pot 같은 기본적인 사용자 정의 클래스들을 포함한다.
※ 여기에 사용된 Pygame Animation 효과에 대해서 크게 2가지가 사용되었는데 처음에 컨셉을 이해하기 어려워 애 먹은 기억이 난다.
- Sprite 이동 : 일정한 목적지로 x, y 위치가 변하며 이동하는 기능
- Text 크기 변경 : Text 크기가 커졌다가 작아지면서 하이라이트
4. Screenshot & Playing Video
5. Source Code
소스코드는 여기 Github 에 올려두었다. (Python3.x 기준)
자유롭게 사용하셔도 되나, 출처는 꼭 남겨 주시기 바란다.