프로그램 개발/Python

[코딩 인터뷰]개념과 알고리즘 - 객체 지향 설계 문제(카드 한 벌:Python)

(ㅇㅅㅎ) 2022. 12. 22. 15:11
728x90
반응형

 

카드 한 벌

 카드 게임에 쓰이는 카드 한 벌을 나타내는 자료구조를 설계하라. 그리고 블랙잭 게임을 구현하려면 이 자료구조의 하위 클래스를 어떻게 만들어야 하는지 설명하라.

 

👀 카드 게임과 블랙잭 게임에 대해서 알지 못하여 아래 사이트의 java코드를 바탕으로 python 코드로 재구성해보았습니다. GameAutomator에 필요한 부분은 작성하지 않았습니다.

https://github.com/czepeda/Java-Cracking-the-Coding-Interview/tree/master/Chapter%208/8.1%20Deck%20of%20Cards%20and%20BlackJack/src/pkg8/pkg1/deck/of/cards/and/blackjack

 

GitHub - czepeda/Java-Cracking-the-Coding-Interview

Contribute to czepeda/Java-Cracking-the-Coding-Interview development by creating an account on GitHub.

github.com

 

 

[ Suit ]

from enum import Enum
class Suit(Enum):
    Club = 0
    Diamond = 1
    Heart = 2
    Spade = 3

    def __init__(self, v, *args, **kwds):
        super().__init__(*args, **kwds)
        self.__value = v

    def getValue(self):
        return self.__value

    def getSuitFromValue(self, v):
        return Suit(v)

👀 enum으로 구성하기 위해서 Enum을 import 하였습니다. 굳이 Enum으로 사용하지 않고 dictionary를 사용하여도 상관없을 것 같습니다. 대신 관련 항목을 전부 수정해야합니다.

 

 

[ Deck ]

import random
class Deck:
    def __init__(self):
        self.__cards = []
        self. __dealtIndex = 0

    def setDeckOfCards(self, deckOfCards):
        self.__cards = deckOfCards

    def shuffle(self):
        random.shuffle(self.__cards)

    def remainingCards(self):
        return len(self.__cards) - self.__dealtIndex

    def __str__(self):
        for card in self.__cards:
            card.print()
        return ''

👀 deck에서는 shuffle을 위하여 random을 import하였습니다.

 

 

[ Card ]

from abc import *
class Card(metaclass=ABCMeta):
    def __init__(self, c, s: Suit):
        self.__available = True
        self.__faceValue = c
        self.__suit = s

    @abstractmethod
    def value(self):
        pass

    def suit(self):
        return self.__suit

    def isAvailable(self):
        return self.__available

    def markUnavailable(self):
        self.__available = False

    def markAvailable(self):
        self.__available = True

    def print(self):
        suit = {Suit.Club: "c", Suit.Diamond: "d", Suit.Heart: "h", Suit.Spade: "s"}
        faceValues = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
        print(f'{faceValues[self.__faceValue - 1]}{suit[self.__suit]}')

👀 Card는 추상 클래스로 구현하기 위하여 abc를 import 하였습니다.

 

 

[ Hand ]

class Hand:
    def __init__(self):
        self.__cards = []

    def score(self):
        score = 0
        for card in self.__cards:
            score += card.value()
        return score

    def addCard(self, card: Card):
        self.__cards.append(card)

    def __str__(self):
        for card in self.__cards:
            card.print()
        return ''

 

 

[ BlackJackCard ]

class BlackJackCard(Card):
    def __init__(self, c, s):
        super().__init__(c, s)

    def value(self):
        if self.isAce():
            return 1
        elif (self.__faceValue >= 11) and (self.__faceValue <= 13):
            return 10
        else:
            return self.__faceValue

    def minValue(self):
        if self.isAce():
            return 1
        else:
            return self.value()

    def maxValue(self):
        if self.isAce():
            return 11
        else:
            return self.value()

    def isAce(self):
        return self.__faceValue == 1

    def isFaceCard(self):
        return (self.__faceValue >= 11) and (self.__faceValue <= 13)

 

 

[ BlackJackHand ]

class BlackJackHand(Hand):
    def score(self):
        scores = self.possibleScores()
        maxUnder = float('-inf')
        minOver = float('inf')
        for score in scores:
            if score > 21 and score < minOver:
                minOver = score
            elif score <= 21 and score > maxUnder:
                maxUnder = score
        return minOver if maxUnder == float('-inf') else maxUnder

    def possibleScores(self):
        if len(self.__cards) == 0: return []

        scores = []
        for card in self.__cards:
            scores = self.addCardToScoreList(card, scores)
        return scores

    def addCardToScoreList(self, card: BlackJackCard, scores):
        if scores == []: scores.append(0)
        length = len(scores)

        for i in range(length):
            score = scores[i]
            scores[i] += card.minValue()
            if card.minValue() != card.maxValue():
                scores.append(score + card.maxValue())
        return scores

    def busted(self):
        return self.score() > 21

    def is21(self):
        return self.score() == 21

    def isBlackJack(self):
        if len(self.__cards) != 2: return False
        first = self.__cards[0]
        second = self.__cards[1]
        return (first.isAce() and second.isAce()) or (first.isFaceCard() and second.isAce())

 

반응형