Standart bir destede bulunanlardan daha karmaşık oyun kartı türleri için sınıf oluşturmanın iyi bir yolu var mı?


9

Nesneye yönelik programlamaya son derece yeniyim ve basit bir kart oyunu (geleneksel gibi görünüyor!) Yaparak python'da öğrenmeye başlamaya çalışıyorum. İyi çalışan ve PlayingCard()sınıfın bir örneğini oluşturmak için sınıfın birden çok örneğini yapma hakkında öğretir aşağıdaki örnek yaptım 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()



Şimdi daha karmaşık kartlarla bir şey yapmak istiyorum, sadece standart 52 deste değil (güzel değerlere sahip). Aklımdaki güverte Tekel kart oyunu:

resim açıklamasını buraya girin

3 temel kart türü vardır: EYLEM kartları, MÜLK kartları ve PARA kartları. Aksiyon kartları farklı eylemler gerçekleştirir, özellik kartları farklı renk setlerine aittir ve para kartları farklı değerlere sahip olabilir. Ek olarak, özellik kartları "joker karakterler" olabilir ve iki setten birinin parçası olarak kullanılabilir. Son olarak, her kartın eşdeğer bir para değeri vardır (her kartın üst köşesinde gösterilir). Kira işlem kartlarında, kart yalnızca kartta belirtilen renk özelliğine uygulanabilir.

Benim sorum genellikle böyle bir durumun nasıl ele alınacağı ve bu farklı kartları sınıf tabanlı bir python programına dahil etmenin iyi bir yolu ne olurdu? Tek dersimi tutmalı mıyım PlayingCard()ve sadece birçok girdiye sahip olmalıyım PlayingCard(type="PROPERTY", value="3M"). Yoksa gibi ayrı sınıflar oluşturmak için daha iyi olurdu ActionPlayingCard(), PropertyPlayingCard()vb? Yoksa daha iyi bir yol var mı? Söylediğim gibi, burada öğrenmemin başlangıcındayım ve bu tür durumları daha üst düzey tasarım açısından nasıl organize edeceğim.

Çok teşekkürler.


Farklı kart türlerinin bazı özellikleri paylaştığını fark ederseniz, miras, hatta bir Abstract sınıfı kullanabilirsiniz. Fabrika
Tipi'ni

@Tomerikoo Bunu belirttiğiniz için teşekkür ederim - Bahsettiğiniz fabrika düzeni hakkında biraz okudum. Anladığım kadarıyla, daha önce hangi nesne sınıflarını oluşturmanız gerektiğini önceden bilmediğinizde yararlıdır (belki de yalnızca çalışma zamanında bilmek). Ancak, bu durumda tüm destenin neye benzemesi gerektiğini bildiğim için (her bir kart türünden kaç tanesi, her biri ne yapıyor, vb.) Fabrika modeli burada uygulanabilir mi?
teeeeee

Yanıtlar:


3

OOP ile ilgili bir soruna yaklaşırken , genellikle davranışları ve özellikleri yeniden kullanılabilir bir şekilde modellemek istersiniz, yani soyutlamaları düşünmeli ve sınıf hiyerarşinizi buna göre organize etmelisiniz.

Aşağıdaki gibi bir şey yazmak istiyorum:

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)


Python'un dinamik olarak yazılan bir dil olması nedeniyle , OOP'un bence haklı çıkması biraz daha zor, çünkü ördek yazımına ve dinamik bağlamaya güvenebileceğimiz için , hiyerarşinizi düzenleme şekliniz daha az önemlidir.

Örneğin bu sorunu C # 'da modelleyecek olsaydım, şüphesiz yukarıda gösterilen hiyerarşiyi kullanırdım, çünkü farklı türleri temsil etmek ve ne tür bir kartın analiz edildiğine bağlı olarak mantığımın akışını yönlendirmek için polimorfizme güvenebilirdim .

Birkaç son açıklama:

  1. Python'un çok güçlü yerleşik tipleri vardır, ancak çoğu zaman yeni özel tipler kullanarak bunları inşa etmek hayatınızı kolaylaştırır.
  2. Python 3'tekiobject türler (bugünden beri korunan tek) varsayılan olarak devraldığı için miras almak zorunda değilsiniz .object

Ancak, günün sonunda mükemmel bir cevap yoktur, en iyi yol her iki yaklaşımı da denemek ve neyle daha rahat olduğunuzu görmek olacaktır.


7

Buna "tasarım kararları" diyoruz. Genellikle "doğru" yol bir görüş meselesidir. Yeni başlayanlar olarak, nasıl çalıştıklarını görmek için her iki uygulamayı da denemenin öğretici olacağını düşünüyorum. Hangisini seçerseniz seçin, değişimler olacaktır. Hangisinin en önemli olduğuna karar vermelisiniz. Daha fazla deneyim kazandıkça bu tür kararları almak size bildirilecektir.


Evet, teşekkürler, tam olarak söylediğin gibi yapıyorum - sadece içgüdüsel olarak iyi bir yaklaşımı bilen ve umarım nedenini anlayacak kadar deneyimli kişilerden rehberlik arıyorum.
teeeeee

2

Kalıtım kullanabilirsiniz. Burada ana sınıf oluşturduğunuz ve ana sınıftan işlevler ve değerler içeren alt sınıflara sahip olduğunuz, ancak belirli bir sınıf için ek değerlere ve işlevlere sahip olabileceğiniz yerdir.

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

Şimdi iPhone sınıfı, Apple sınıfı ve kendi işlevi ile aynı işlevlere sahip. Kalıtım hakkında daha fazla bilgi edinmek isterseniz biraz araştırma yapmanızı tavsiye ederim.


@teeeeee Her kartın bir değeri olduğundan, bunları takas edebilir ve oynayabilirsiniz, bu olayları işlemek için bir sınıfta işlevler / prosedürler oluşturabilir ve ardından bir alt sınıftaki belirli kartlar için ekstra özelliklere ve işlevlere sahip olabilirsiniz.
MoriartyPy

0

Tekel için oyunun iniş bakış açısını tasarlarım. Kartlar değil. Kartlar sadece gerçek dünya için inişleri temsil eder.


Lütfen detaylandırın.
teeeeee
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.