如何比较两张扑克牌的价值和套装价值? Python3

时间:2017-02-22 17:45:59

标签: python python-3.x

我正在尝试制作基于文本的面向对象的纸牌游戏。两名球员各自从一副纸牌中抽出一张牌,最强牌的玩家获胜。我有四个课程:卡片,甲板,播放器,游戏。我的问题是:我如何比较每个球员卡彼此,并确定最强的卡。欢迎所有关于代码的其他建议。最好的问候HWG。

这是我的代码:

class Card():

    values = [None, None, 2, 3, 4, 5, 6, 7, 8, 9, 10, "Jack", "Queen", "King",
        "Ace"]
    suits = ["hearts", "spades", "diamond", "clubs"]

    def __init__(self, value, suit):
        self.value = value
        self.suit = suit

    def __repr__(self):
        return str(self.values[self.value]) + " of " + str(self.suits[self.suit])

甲板

from random import shuffle
from card import Card

class Deck():

    def __init__(self):
        self.cards = []
        for v in range(2, 15):
            for s in range(4):
                self.cards.append(Card(v, s))
        shuffle(self.cards)

播放器

from deck import Deck

class Player():

    def __init__(self, name):
        self.name = name
        self.card = None
        self.wins = 0

游戏

from player import Player
from deck import Deck
import getch

class Game():

    def __init__(self):
        player1_name = input("Player One Name: ")
        player2_name = input("Player Two Name: ")
        self.deck = Deck()
        self.player1 = Player(player1_name)
        self.player2 = Player(player2_name)
        self.cards = self.deck.cards

    def game_loop(self):
        while len(self.cards) >= 2:
            print("\nPress enter to draw")
            getch.getch()
            player1_card = self.cards.pop()
            player2_card = self.cards.pop()

4 个答案:

答案 0 :(得分:1)

这是一种方法草图。您可以轻松地将其与您自己的方法相结合,这是Card类的最大变化。在这里,我使用namedtuple创建了一个Card类,但是您当前的类只能包含一个tuple值:

import enum
from functools import total_ordering
from collections import namedtuple

@total_ordering
class OrderedEnum(enum.Enum):
    def __lt__(self, other):
        if isinstance(other, type(self)):
            return self.value < other.value
        return NotImplemented

Rank = OrderedEnum('Rank', ['one', 'two', 'three', 'four', 'five', 'six',
                    'seven', 'eight', 'nine', 'jack', 'queen','king', 'ace'])

Suit = OrderedEnum('Suit', ['clubs', 'diamonds', 'hearts', 'spades'])

Card = namedtuple('Card', ['rank', 'suit'])

c1 = Card(Rank.four, Suit.clubs)
c2 = Card(Rank.four, Suit.spades)
c3 = Card(Rank.ace, Suit.diamonds)

现在,在行动中:

>>> c1
Card(rank=<Rank.four: 4>, suit=<Suit.clubs: 1>)
>>> c2
Card(rank=<Rank.four: 4>, suit=<Suit.spades: 4>)
>>> c1 < c2
True
>>> c1 > c3
False

元组排序是词典的!尼斯!

>>> hand = [c2, c1, c3]
>>> hand
[Card(rank=<Rank.four: 4>, suit=<Suit.spades: 4>), Card(rank=<Rank.four: 4>, suit=<Suit.clubs: 1>), Card(rank=<Rank.ace: 13>, suit=<Suit.diamonds: 2>)]
>>> sorted(hand)
[Card(rank=<Rank.four: 4>, suit=<Suit.clubs: 1>), Card(rank=<Rank.four: 4>, suit=<Suit.spades: 4>), Card(rank=<Rank.ace: 13>, suit=<Suit.diamonds: 2>)]
>>>

注意,我已经使用了total_ordering装饰器,这只是一个快捷方式,而且我认为简单地手工操作整个班级可能会更好。 Here's食谱。

修改 所以,详细说明一下,我将如何实现您的CardDeck类。请注意,使用enumnamedtuple时,您的代码可读性有多大。

import enum
from functools import total_ordering
from collections import namedtuple
from random import shuffle 

@total_ordering
class OrderedEnum(enum.Enum):
    def __lt__(self, other):
        if isinstance(other, type(self)):
            return self.value < other.value
        return NotImplemented

Rank = OrderedEnum('Rank', ['one', 'two', 'three', 'four', 'five', 'six',
                    'seven', 'eight', 'nine', 'jack', 'queen','king', 'ace'])
Suit = OrderedEnum('Suit', ['clubs', 'diamonds', 'hearts', 'spades'])
CardValue = namedtuple('CardValue', ['rank', 'suit'])

@total_ordering
class Card(object):
    def __init__(self, rank, suit):
        self.value = CardValue(rank, suit)
    def __repr__(self):
        return "Card({:s}, {:s})".format(self.value.rank, self.value.suit)
    def __lt__(self, other):
        if isinstance(other, type(self)):
            return self.value < other.value
        return NotImplemented
    def __eq__(self, other):
        if isinstance(other, type(self)):
            return self.value == other.value
        return NotImplemented

class Deck(object):
    def __init__(self):
        self.cards = []
        for rank in Rank:
            for suit in Suit:
                self.cards.append(Card(rank, suit))
        shuffle(self.cards)

现在,在行动中:

>>> deck = Deck()
>>> c1 = deck.cards.pop()
>>> c2 = deck.cards.pop()
>>> c1
Card(Rank.queen, Suit.hearts)
>>> c2
Card(Rank.king, Suit.clubs)
>>> c1 == c2
False
>>> c1 > c2
False
>>> c1 < c2
True
>>> c1.value
CardValue(rank=<Rank.queen: 11>, suit=<Suit.hearts: 3>)
>>> c2.value
CardValue(rank=<Rank.king: 12>, suit=<Suit.clubs: 1>)

另外,请注意__repr__应该尝试代表对象,如果你想要一个漂亮的消息,请使用__str__。见this question

答案 1 :(得分:0)

您可以为您的Card类实现运算符 __gt__(), __lt__(),等......

比你可以使用许多标准库函数(如max())来确定更高价值的卡片或套牌,甚至可以使用sort()来简单地对一只手进行排序&#39;例如列表[卡片,卡片......]。

答案 2 :(得分:0)

枚举(https://docs.python.org/3.5/library/enum.html)是合适的。对于丰富的比较(和排序),您还应考虑实施部分或全部__eq____ne____lt____le____gt__,{{1 __ge__类上的方法(来自https://docs.python.org/3/reference/datamodel.html)。

答案 3 :(得分:0)

我建议你将每张卡的值存储为int,这样你就可以比较它们,而不是使用诸如“King”或“Ace”之类的字符串。您可以执行此操作并更改 repr ()以使用这些字符串打印人类可读的版本。

Card类看起来像这样:

class Card(object):
     suits = ["Clubs", "Diamonds", "Hearts", "Spades"] #list of suits
     values = [None, "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"] #list of card values

     def __init__(self, suit= 0, value= 2):
         """
         Initializes card
         :param suit: Suit of card int value 0-3
         :param value: Value of card int value 0-13
         """
         self.suit = suit
         self.value = value

     def __str__(self):
         """
         Returns a readable format of the card
         """
         return "%s of %s" %(Card.values[self.value],
                             Card.suits[self.suit])

注意卡的值是如何一直存储为int的。

在Game类中你可以有一个比较两张牌的功能,我不知道你想怎么做但它看起来像这样:

def compare(card1, card2):
     """
     Compares the value of two cards and returns the greater of the two
     :param card1: A card object
     :param card2: A second card object
     :return: The higher value card, if tie returns 0
     """
     if card1.value > card2.value:
         return card1
     elif card2.value == card1.value:
         return 0
     else:
         return card2