我正在尝试创建一个简单的纸牌游戏,以更好地了解OOP和类。
游戏如下:从牌组发出两张牌。然后发出第三张牌。如果第三张牌位于前两张牌之间,则玩家获胜。如果第三张牌等于前两张牌中的任何一张,或者在该牌组之外,则该牌手输了。
这是我到目前为止所做的:
class Deck(object):
def __init__(self):
self.deck = []
def PopulateDeck(self):
suits = ["Hearts", "Diamonds", "Clubs", "Spades"]
for suit in suits:
for rank in range(2, 15):
if rank == 11:
value = "Jack"
elif rank == 12:
value = "Queen"
elif rank == 13:
value = "King"
elif rank == 14:
value = "Ace"
self.deck.append(str(value) + " of " + suit)
class Card(object):
def __init__(self, rank, value):
self.rank = rank
self.value = value
self.card = self.rank + self.value
我在课堂和OOP上遇到困难,我不确定这是一个好的开始,还是我应该去哪里。其中大部分是通过阅读其他来源和示例创建的。任何人都可以提供关于我可能想要运行我的游戏的其他课程的建议,以及这些课程如何与彼此互动/继承?谢谢。
答案 0 :(得分:9)
这更多是代码/方法审核。纸牌游戏是一种组合而非继承的案例; Deck
包含Card
,但其本身并不是Card
的类型,反之亦然。
我认为您正在重复Card
中的信息。只需存储套装和排名,然后使用__str__
创建'x of y'
。您还可以实施rich comparison methods:
class Card(object):
FACES = {11: 'Jack', 12: 'Queen', 13: 'King', 14: 'Ace'}
def __init__(self, rank, suit):
self.suit = suit
self.rank = rank
def __str__(self):
value = self.FACES.get(self.rank, self.rank)
return "{0} of {1}".format(value, self.suit)
def __lt__(self, other):
return self.rank < other.rank
现在,例如str(Card(13, 'Clubs')) == "King of Clubs"
。这样您就不会复制rank
中的value
和card
。
接下来,我认为Deck
应该将人口生成纳入__init__
;您可以为非标准套牌提供可选参数。我已经包含了两个实现;注释掉的版本是一个列表理解,使用itertools
在一行中完成相同的工作。我还提供了从n
中挑选self.deck
个不同随机卡的功能。
from itertools import product
import random
class Deck(object):
def __init__(self, ranks=None, suits=None):
if ranks is None:
ranks = range(2, 15)
if suits is None:
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
## self.deck = [Card(r, s) for r, s in product(ranks, suits)]
self.deck = []
for r in ranks:
for s in suits:
self.deck.append(Card(r, s))
def deal(self, n):
return random.sample(self.deck, n)
现在游戏很简单;你可以每手交易三张牌,并且由于比较方法,自然地比较牌(例如使用<
)。
deck = Deck()
hand = deck.deal(3)
print(" - ".join(map(str, hand)))
if min(hand[0], hand[1]) < hand[2] < max(hand[0], hand[1]):
print("Winner!")
else:
print("Loser.")
答案 1 :(得分:0)
正如@tobias_k已在评论中指出+我的一些想法
class Deck(object):
def __init__(self):
self.deck = []
self.dealt = [] #Prevents from dealing the same card
def PopulateDeck(self):
suits = ["Hearts", "Diamonds", "Clubs", "Spades"]
for suit in suits:
for rank in range(2, 15):
if rank == 11:
value = "Jack"
elif rank == 12:
value = "Queen"
elif rank == 13:
value = "King"
elif rank == 14:
value = "Ace"
else:
value = str(rank)
self.deck.append(Card(value, suit))
def deal(self):
#Randomly select card
remaining_cards = [card for card in self.deck if card not in self.dealt]
card_index = random.randrange(0, len(remaining_cards)-1)
card = remaining_cards[card_index]
self.dealt.append(card)
return card
def shuffle(self):
self.dealt = []
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
self.card = str(self.rank) + " " + str(self.suit)
def __eq__(self, other):
return self.rank == other.rank and self.suit == other.suit
def play():
deck = Deck()
card1 = deck.deal()
card2 = deck.deal()
card3 = deck.deal()
#And here you will compare the cards to see if the player wins or not. Not sure
#what exact criterion you're using.
deck.shuffle() #And leave your deck nicely shuffled for next game
play()
我没有运行此代码,它可能包含错误。但它说明了你能做些什么。
答案 2 :(得分:0)
我也在使用纸牌游戏学习 opps,因为我发现这是理解概念的最简单方法。我曾经遇到过这段代码,但不确定链接。我用一些有用的注释来纠缠这段代码。这可能会有所帮助。
from random import shuffle
class Card:
suits = ['spades', 'hearts', 'diamonds', 'clubs']
values = [None, None, '2','3','4','5','6','7','8','9','10','Jack', 'Queen', 'King', 'Ace']
def __init__(self, v, s):
'''suits + values are ints'''
self.value = v
self.suit = s
def __lt__(self, c2): # allows to compare two objects cards in this case
if self.value < c2.value:
return True
if self.value == c2.value: # value is what user is putting while creating object of class
if self.suit < c2.suit: # c2 is with what we are comapring
return True
else:
return False
return False
def __gt__(self, c2): # allows to compare two objects cards in this case,
if self.value > c2.value: # c2 is with what we are comapring
return True
if self.value == c2.value:
if self.suit > c2.suit: # suits comes into picture if values are same suit number is given importance
return True
else:
return False
return False
def __repr__(self):
v = self.values[self.value] + ' of ' + self.suits[self.suit]
return v
# defining the class which represent the deck of card
class Deck:
def __init__(self):
self.cards = []
for i in range(2,15):
for j in range(4):
self.cards.append(Card(i,j))
shuffle(self.cards)
def rm_card(self):
if len(self.cards) == 0:
return # if block it return to None object when condition is satisfied
return self.cards.pop()
class Player:
def __init__(self, name):
self.name = name # name of the player
self.card = None # current card player holding
self.wins = 0
class Game:
def __init__(self):
name1 = input('p1 name ')
name2 = input('p2 name ')
self.deck = Deck()
self.p1 = Player(name1)
self.p2 = Player(name2)
def wins(self, winner):
w = "{} wins this round"
w = w.format(winner)
print(w)
def draw(self, p1n, p1c, p2n, p2c):
d = "{} drew {} {} drew {}"
d = d.format(p1n, p1c, p2n, p2c)
print(d)
def play_game(self):
cards = self.deck.cards # self.deck = Deck() and cards = self.deck.cards is list of card
print('Beginning War!!!')
while len(cards) > 2:
m = 'q to quit. Any' + ' key to play'
response = input(m)
if response == 'q':
break
p1c = self.deck.rm_card() # removing first card from deck by player 1
p2c = self.deck.rm_card() # removing second card from deck by player 2
p1n = self.p1.name
p2n = self.p2.name
self.draw(p1n, p1c, p2n, p2c)
if p1c > p2c:
self.p1.wins +=1
self.wins(self.p1.name)
else:
self.p2.wins += 1
self.wins(self.p2.name)
win = self.winner(self.p1, self.p2)
print("War is over. {} wins".format(win))
def winner(self, p1, p2):
if p1.wins > p2.wins:
return p1.name
if p1.wins < p2.wins:
return p2.name
return 'Its Tie!'
game = Game()
game.play_game()