我正在尝试制作基于文本的面向对象的纸牌游戏。两名球员各自从一副纸牌中抽出一张牌,最强牌的玩家获胜。我有四个课程:卡片,甲板,播放器,游戏。我的问题是:我如何比较每个球员卡彼此,并确定最强的卡。欢迎所有关于代码的其他建议。最好的问候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()
答案 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食谱。
修改强>
所以,详细说明一下,我将如何实现您的Card
和Deck
类。请注意,使用enum
和namedtuple
时,您的代码可读性有多大。
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