표준 데크에서 볼 수있는 것보다 더 복잡한 카드 종류에 맞는 수업을 만드는 좋은 방법은 무엇입니까?


9

나는 객체 지향 프로그래밍을 처음 접했고 간단한 카드 게임을 만들어 파이썬에서 배우려고합니다 (전통적인 것처럼 보입니다!). 나는 잘 작동하는 다음 예제를 수행했으며 PlayingCard()클래스의 인스턴스를 만들기 위해 클래스 의 여러 인스턴스를 만드는 방법을 가르쳐 줍니다 Deck().

class PlayingCard(object):
    def __init__(self, suit, val):
        self.suit = suit
        self.value = val

    def print_card(self):
        print("{} of {}".format(self.value, self.suit))

class Deck(object):
    def __init__(self):
        self.playingcards = []
        self.build()

    def build(self):
        for s in ["Spades", "Clubs", "Diamonds", "Hearts"]:
            for v in range(1,14):
                self.playingcards.append(PlayingCard(s,v))

deck = Deck()



표준 52 데크가 아닌 더 복잡한 카드로 무언가를 만들고 싶습니다. 내가 생각하는 갑판은 독점 카드 게임입니다.

여기에 이미지 설명을 입력하십시오

액션 카드, 속성 카드 및 돈 카드의 세 가지 기본 유형의 카드가 있습니다. 액션 카드는 다른 액션을 수행하고 속성 카드는 다른 색상 세트에 속하며 머니 카드는 다른 값을 가질 수 있습니다. 또한 속성 카드는 "와일드 카드"일 수 있으며 두 세트 중 하나의 일부로 사용할 수 있습니다. 마지막으로, 모든 카드에는 동등한 금액이 있습니다 (각 카드의 상단 모서리에 표시됨). 임대 조치 카드에서 카드는 카드에 표시된 색상 특성에만 적용 할 수 있습니다.

내 질문은 일반적으로 이와 같은 상황을 처리하는 방법이며 클래스 기반 파이썬 프로그램에 이러한 다른 카드를 포함시키는 좋은 방법은 무엇입니까? 단일 PlayingCard()클래스를 유지 하고와 같은 많은 입력을해야 PlayingCard(type="PROPERTY", value="3M")합니다. 아니면 같은 별도의 클래스를 만드는 더 나은 것 ActionPlayingCard(), PropertyPlayingCard()등? 아니면 더 좋은 방법이 있습니까? 내가 말했듯이, 나는 여기에서 학습을 시작할 때, 그리고 더 높은 수준의 디자인 측면에서 이러한 유형의 상황을 구성하는 방법에 있습니다.

많은 감사합니다.


다른 유형의 카드가 일부 기능을 공유하는 경우 상속 또는 Abstract 클래스를 사용할 수 있습니다. 팩토리 패턴을 읽고 사용할 수 있으므로 카드 유형을 전달하면 해당 클래스가 사용됩니다.
Tomerikoo

@Tomerikoo 지적 해 주셔서 감사합니다. 언급 한 팩토리 패턴에 대해 조금 읽었습니다. 내가 알기로, 이것은 어떤 객체 클래스를 생성 해야하는지 미리 알지 못하는 경우에 가장 유용합니다 (아마 런타임에만 알고 있음). 그러나이 경우 전체 데크가 어떻게 보이는지 알고 있기 때문에 (각 유형의 카드 수, 카드 등) 공장 패턴이 여기에 적용됩니까?
teeeeee

답변:


3

OOP 관련 문제에 접근 할 때 일반적으로 재사용 가능한 방식으로 동작과 속성을 모델링하려고합니다. 즉, 추상화를 생각하고이를 기반으로 클래스 계층을 구성해야합니다.

나는 다음과 같은 것을 쓸 것이다.

class Card:
    def __init__(self, money_value=0):
        self.money_value = money_value

class ActionCard(Card):
    def __init__(self, action, money_value=0):
        super().__init__(money_value=money_value)

        self.action = action

class RentActionCard(ActionCard):
    def __init__(self, action, color, money_value=0):
        super().__init__(action, money_value=money_value)

        self.color = color

    def apply(self, property_card):
        if property_card.color != self.color:
            # Don't apply
        # Apply

class PropertyCard(Card):
    def __init__(self, color, money_value=0):
        super().__init__(money_value=money_value)

        self.color = color

class WildcardPropertyCard(PropertyCard):
    def __init__(self, color, money_value=0):
        super().__init__(color, money_value=money_value)

class MoneyCard(Card):
    def __init__(self, money_value=0):
        super().__init__(money_value=money_value)

파이썬 이 동적으로 입력되는 언어이기 때문에 OOP오리 타이핑동적 바인딩 에 의존 할 수 있기 때문에 계층 구조를 구성하는 방식이 덜 중요하다고 생각합니다.

예를 들어 C # 에서이 문제를 모델링한다면 위의 계층 구조를 사용하는 것은 의심의 여지가 없습니다. 왜냐하면 다형성 에 의존하여 다른 유형을 표현하고 어떤 유형의 카드가 분석되는지에 따라 논리의 흐름을 유도 할 수 있기 때문 입니다.

몇 가지 마지막 말 :

  1. 파이썬 은 매우 강력한 내장 유형을 가지고 있지만, 대부분 새로운 유형의 맞춤형 유형을 사용하면 삶을 더 쉽게 만들 수 있습니다.
  2. Python 3의object 유형 (현재 유일하게 유지 관리되는 유형 ) 이 기본적으로 상속 되므로 상속받을 필요가 없습니다 .object

그러나 하루가 끝나면 완벽한 대답이 없습니다. 가장 좋은 방법은 두 가지 접근법을 모두 시도하고 더 편한 것을 보는 것입니다.


7

이것을 "디자인 결정"이라고합니다. 종종 "올바른"방법은 의견의 문제입니다. 초보자로서, 두 가지 구현을 통해 작동 방식을 확인하는 것이 유익하다고 생각합니다. 어느 쪽을 선택하든 트레이드 오프가 발생합니다. 그 중 어느 것이 가장 중요한지 결정해야합니다. 경험이 많을수록 이러한 종류의 결정을 내릴 수 있습니다.


그렇습니다. 감사합니다. 여러분이 말한대로 정확하게하고 있습니다. 좋은 접근 방식을 본능적으로 알고 충분한 이유를 이해하기에 충분한 경험이있는 사람들의지도를 찾고 있습니다.
teeeeee

2

상속을 사용할 수 있습니다. 여기에서 메인 클래스를 만든 다음 여전히 모 클래스의 함수와 값을 포함하는 하위 클래스가 있지만 해당 클래스에 대한 추가 값과 함수를 가질 수도 있습니다.

class Apple:
    def __init__(self, yearMade):
        pass

    def ring(self):
        print('ring ring')

class iPhone(Apple):
    def __init__(self, number)
        number = number

    def func():
        pass

이제 iPhone 클래스는 Apple 클래스와 동일한 기능 및 자체 기능을 갖습니다. 상속에 대해 더 배우고 싶다면 약간의 연구를 권장합니다.


감사합니다. 상속과 작동 방식을 이해합니다. 독점 데크의 특성을 고려할 때 특정 상황에 어떻게 적용 할 수 있는지에 더 관심이 있습니다.
teeeeee

@teeeeee 각 카드에는 가치가 있기 때문에 거래 할 수 있고 거래 할 수 있으므로 클래스에서 함수 / 프로 시저를 만들어 이러한 이벤트를 처리 한 다음 하위 클래스의 특정 카드에 대한 추가 속성과 함수를 가질 수 있습니다.
MoriartyPy

0

독점의 경우, 게임 랜딩 관점을 설계 할 것입니다. 카드가 아닙니다. 카드는 단순히 실제 세계의 상륙을 나타냅니다.


정교하게 작성하십시오.
teeeeee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.