随机将实例对象从一个列表交换到另一个列表

时间:2017-12-30 19:36:12

标签: python object

我想我的代码需要帮助,我不知道错误是什么或修复它的位置。以下是一些处理基本扑克牌的类,它想要做的是从牌组对象中随机挑选牌并将它们放入手牌对象中,然后从手牌对象中删除对象,以便我创造的下一手不会拿起重复。也许这是一种迟钝的思考方式,但它似乎是管理一副卡片的最佳方式,就像它在现实世界中一样。

问题出在日志记录方法或create_hand()方法中。当我运行我的代码后,当我看到我的手时,如果我在日志中查看报告,我会看到手中的卡片仍在卡片中。相反,有不同的卡被删除。它报告从甲板上取出的卡片数量正确,但它也只报告心脏被取出,根据套装计算卡片的数量。然而,我的手上有各种各样的独特卡片,具有独特的价值和套装。这部分有效。

class Suit(Enum):
    HEARTS = "Hearts"
    CLUBS = "Clubs"
    DIAMONDS = "Diamonds"
    SPADES = "Spades"

class Card:
    def __init__(self, suit, value):

        self.suit = suit
        self.value = value
        if self.suit == 1:
            self.suit = Suit.HEARTS
        elif self.suit == 2:
            self.suit = Suit.CLUBS
        elif self.suit == 3:
            self.suit = Suit.DIAMONDS
        else:
            self.suit = Suit.SPADES

    #and a host of magic methods that are irrelevant


class Deck:
    def __init__(self, deck_size):
        self.deck_size = deck_size
        self.deck = []
        card_suit = 1
        card_value = 2
        while len(self.deck) < self.deck_size:
            self.deck.append(Card(suit=card_suit, value=card_value))
            card_value += 1
            if card_value > 14:
                card_suit += 1
                card_value = 2

    def log_deck(self):
        logging.info("Deck cards: {}".format(len(self.deck)))
        hearts = clubs = diamonds = spades = 0
        for card in self.deck:
            if card.suit == Suit.HEARTS:
                hearts += 1
            elif card.suit == Suit.CLUBS:
                clubs += 1
            elif card.suit == Suit.DIAMONDS:
                diamonds += 1
            else:
                spades += 1
            logging.info("{} |".format(str(card)))
        logging.info("Hearts: {}, Clubs: {}, Diamonds: {}, Spades: {}".format(hearts, clubs, diamonds, spades))
        logging.info("*"*20)


class Hand:

    def __init__(self, size=2):
        self.size = size
        self.cards = []

    def create_hand(self, deck):
        self.cards = []
        while len(self.cards) < self.size:
            card = random.sample(deck.deck_cards, k=1)
            card_value = card[0].value
            card_suit = card[0].suit
            if card not in self.cards:
                self.cards.append(card)
                for card in deck.deck_cards:
                    if card.value == card_value and card.suit == card_suit:
                        deck.deck_cards.remove(card)
        deck.log_deck()
        return self.cards

以下是日志的样本示例。为了简洁起见,我从列表中删除了大部分卡片:

INFO:root:Deck cards: 47
INFO:root:|2 of Hearts| |
INFO:root:|3 of Hearts| |
INFO:root:|5 of Hearts| |
INFO:root:|6 of Hearts| |
....
INFO:root:|King of Spades| |
INFO:root:|Ace of Spades| |
INFO:root:Hearts: 8, Clubs: 13, Diamonds: 13, Spades: 13
INFO:root:********************

底部的标签似乎总是显示出一只手产生后只有八颗心,即使我的手没有心脏,即使丢失的卡片不是心脏。

基本上,我无法弄清楚我的日志是否记录错误,或者我是否正确删除了卡片。或两者。使用同一套牌创建两只手的一些测试显示了重复的卡片,这正是我想要避免的。

由于

2 个答案:

答案 0 :(得分:0)

您的外部变量cardlist而不是Card个实例。

您将包含一个项目(您的采样卡片)的list附加到self.cards列表,而不是项目本身。我认为这会导致一些中断,试图删除你最后一行中的卡片。

我建议将card更改为

中的card[0]
if card not in self.cards

self.cards.append(card)

看看是否能解决问题。

此外,您似乎是从deck.deck_cards抽样;我假设deckDeck个对象,但您的给定Deck实现似乎没有deck_cards属性。我想这会抛出一个AttributeError

另外,为了保护自己(以及任何阅读代码的人)一些不必要的混淆,也许你不希望在内循环中覆盖card变量名。

答案 1 :(得分:0)

我在reddit的/ r / learnpython上得到了/ u / Zigity_Zagity的帮助。稍微改写一下我的代码,感谢他:

    def create_hand(self, deck):
        self.cards = random.sample(deck.deck_cards, k=self.size)

        deck.deck_cards = [card for card in deck.deck_cards if card not in self.cards]

        deck.log_deck()
        return self.cards

修复卡片对象的__eq__方法:

def __eq__(self, other):
    return self.value == other and self.suit.value == other