设计一副牌
2018-07-22 本文已影响9人
MontyOak
作为演示代码,做了以下的简化处理:
- 总共52张牌,不包含大小王
from abc import ABCMeta, abstractmethod
from enum import Enum
import sys
class Suit(Enum):
HEART = 0
DIAMOND = 1
CLUBS = 2
SPADE = 3
class Card(metaclass=ABCMeta):
def __init__(self, value, suit):
self.value = value
self.suit = suit
self.is_available = True
@property
@abstractmethod
def value(self):
pass
@value.setter
@abstractmethod
def value(self, other):
pass
class BlackJackCard(Card):
def __init__(self, value, suit):
super(BlackJackCard, self).__init__(value, suit)
def is_ace(self):
return self._value == 1
def is_face_card(self):
"""Jack = 11, Queen = 12, King = 13"""
return 10 < self._value <= 13
@property
def value(self):
if self.is_ace() == 1:
return 1
elif self.is_face_card():
return 10
else:
return self._value
@value.setter
def value(self, new_value):
if 1 <= new_value <= 13:
self._value = new_value
else:
raise ValueError('Invalid card value: {}'.format(new_value))
class Hand(object):
def __init__(self, cards):
self.cards = cards
def add_card(self, card):
self.cards.append(card)
def score(self):
total_value = 0
for card in card:
total_value += card.value
return total_value
class BlackJackHand(Hand):
BLACKJACK = 21
def __init__(self, cards):
super(BlackJackHand, self).__init__(cards)
def score(self):
min_over = sys.MAXSIZE
max_under = -sys.MAXSIZE
for score in self.possible_scores():
if self.BLACKJACK < score < min_over:
min_over = score
elif max_under < score <= self.BLACKJACK:
max_under = score
return max_under if max_under != -sys.MAXSIZE else min_over
def possible_scores(self):
"""Return a list of possible scores, taking Aces into account."""
# ...
class Deck(object):
def __init__(self, cards):
self.cards = cards
self.deal_index = 0
def remaining_cards(self):
return len(self.cards) - deal_index
def deal_card():
try:
card = self.cards[self.deal_index]
card.is_available = False
self.deal_index += 1
except IndexError:
return None
return card
def shuffle(self): # ...
每张牌有花色、牌号、状态三个属性。也可以用collections
里的namedtuple
数据结构来实现。