class Deck:
def __init__(self):
ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
suits = ['C', 'D', 'H', 'S']
self.cards = []
for s in suits:
for r in ranks:
self.cards.append(Card(r,s))
def __str__(self):
return str([str(card) for card in self.cards])
def draw(self):
return self.cards.pop()
def shuffle(self):
random.shuffle(self.cards)
def deal(self,n):
deal =[]
for i in range(n):
deal.append(self.cards.pop())
return deal
d=Deck()
print(d.deal(5))
output:
[<__main__.Card object at 0x0000013493F816D0>, <__main__.Card object at 0x0000013493F81100>, <__main__.Card object at 0x0000013493F82160>, <__main__.Card object at 0x0000013493F818B0>, <__main__.Card object at 0x0000013493F6FF40>]
My code prints data information..
I don't know where I did wrong in the code.
Also, is there a way to get a nicer output for deck?
I want my deck to be printed in the shell like this
nice and organized. Thank you in advance
2 C, 3 C, 4 C, 5 C, 6 C,
7 C, 8 C, 9 C, T C, J C,
....
J S, Q S, K S, A S
you can override the card str method like this
import random
class Card:
def __init__(self, r, s):
self.r = r
self.s = s
def __str__(self):
return "{} {}".format(self.r, self.s)
class Deck:
def __init__(self):
ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
suits = ["C", "D", "H", "S"]
self.cards = []
for s in suits:
for r in ranks:
self.cards.append(Card(r, s))
def __str__(self):
return str([str(card) for card in self.cards])
def draw(self):
return self.cards.pop()
def shuffle(self):
random.shuffle(self.cards)
def deal(self, n):
deal = []
for i in range(n):
deal.append(str(self.cards.pop()))
return deal
if __name__ == "__main__":
d = Deck()
print(", ".join(d.deal(5)))
Related
This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
How to print instances of a class using print()?
(12 answers)
Closed 6 months ago.
I copied a card game code online to Python and I'm trying to recreate the popular card game of War.
import random
class Card(object):
def __init__(self, suit, val):
self.suit = suit
self.value = val
def show(self):
print("{} of {}".format(self.value, self.suit))
class Deck:
def __init__(self):
self.cards = []
self.build()
def build(self):
for s in ["Spades", "Clubs", "Diamonds", "Hearts"]:
for v in {'2' : 0, '3' : 1, '4' : 2, '5' : 3, '6' : 4, '7' : 5, '8' : 6, '9' : 7 , '10' : 8, 'Jack' : 9, 'Queen' : 10, 'King' : 11, 'Ace' : 12}:
self.cards.append(Card(s,v))
def show(self):
for c in self.cards:
c.show()
def shuffle(self):
for i in range(len(self.cards)-1, 0, -1):
r = random.randint(0, i)
self.cards[i], self.cards[r] = self.cards[r], self.cards[i]
def drawCard(self):
return self.cards.pop()
class Player:
def __init__(self, name):
self.name = name
self.hand = []
def draw(self,deck):
self.hand.append(deck.drawCard())
return self
def showHand(self):
for card in self.hand:
print(self.name, "drew a ", card.show() , "!")
deck = Deck()
deck.shuffle()
peter = Player('Peter')
peter.draw(deck)
jessica = Player('Jessica')
jessica.draw(deck)
peter.showHand()
jessica.showHand()
In the Player.show_hand() method I want to print (name object) draws a (value of suit). However, instead, it prints the suit of value first, and then it says Player draws a None !. It kind of goes like this:
9 of Clubs
Peter drew a None!
It's mostly a simple error, but I want it so that the suit of value gets printed alongside the player, like this:
Peter drew a 9 of Clubs!
This is the method that results in a runtime error:
def showHand(self):
for card in self.hand:
print(self.name, "drew a ", card.show() , "!")
Your function Card.show(), prints and returns None.
I would implement a string dunder for the Card class as shown here. Then I would simply format print the Card class down below in the Player.showHand() function which will call the Card.__str__() dunder automatically.
import random
class Card(object):
def __init__(self, suit, val):
self.suit = suit
self.value = val
# this decides what string to return when using this class as a string.
def __str__(self):
return "{} of {}".format(self.value, self.suit)
def show(self):
print("{} of {}".format(self.value, self.suit))
class Deck:
def __init__(self):
self.cards = []
self.build()
def build(self):
for s in ["Spades", "Clubs", "Diamonds", "Hearts"]:
for v in {'2' : 0, '3' : 1, '4' : 2, '5' : 3, '6' : 4, '7' : 5, '8' : 6, '9' : 7 , '10' : 8, 'Jack' : 9, 'Queen' : 10, 'King' : 11, 'Ace' : 12}:
self.cards.append(Card(s,v))
def show(self):
for c in self.cards:
c.show()
def shuffle(self):
for i in range(len(self.cards)-1, 0, -1):
r = random.randint(0, i)
self.cards[i], self.cards[r] = self.cards[r], self.cards[i]
def drawCard(self):
return self.cards.pop()
class Player:
def __init__(self, name):
self.name = name
self.hand = []
def draw(self,deck):
self.hand.append(deck.drawCard())
return self
def showHand(self):
for card in self.hand:
# This line was changed:
print(f"{self.name} drew a {card}!")
deck = Deck()
deck.shuffle()
peter = Player('Peter')
peter.draw(deck)
jessica = Player('Jessica')
jessica.draw(deck)
peter.showHand()
jessica.showHand()
Execution:
[ttucker#zim stackoverflow]$ python war.py
Peter drew a 10 of Clubs!
Jessica drew a 10 of Hearts
I am trying the project from here: https://projects.raspberrypi.org/en/projects/deck-of-cards/7
I want the instance to be a associated as a list.
My code looks like this:
from card import Card
class Deck:
def __init__(self):
self._cards = []
self.populate()
def __repr__(self):
return self._cards
def populate(self):
suits = ["diamonds", "clubs", "spades", "hearts"]
numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
cards = []
for suit in suits:
for number in numbers:
cards.append(Card(suit, number))
self._cards = cards
def shuffle(self):
pass
my_deck = Deck()
print(my_deck)
I am new to objects, and programming in general. Please be as layman as possible.
I'm trying to start using objects properly, I've built a deck of cards which is my object. I want to be able shuffle and deal cards from it. However I can't figure out how to get the shuffle method to work correctly or even if this is the best way to do it.
import itertools
import random
class Deck:
'''Deck of cards to be used in a card game'''
def __init__(self):
self.faces = ['A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4','3', '2']
self.suits = ['c', 'd', 'h', 's']
self.cards = set(itertools.product(self.faces, self.suits))
def shuffle(self):
self.cards = random.shuffle(self.cards)
def deal(self):
card = self.cards.pop()
return card[0] + card[1]
Usage;
deck = Deck()
deck.shuffle()
deck.deal()
Sets are not ordered, you could use list() to obtain an ordered deck.
Furthermore random.shuffle(l) acts directly on the list and returns None, so you are overwriting the list with None.
import itertools
import random
class Deck:
'''Deck of cards to be used in a card game'''
def __init__(self):
self.faces = ['A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4','3', '2']
self.suits = ['c', 'd', 'h', 's']
self.cards = list(itertools.product(self.faces, self.suits)) # ordered deck
# self.cards = set(itertools.product(self.faces, self.suits)) # unordered deck
def shuffle(self):
random.shuffle(self.cards)
def deal(self):
card = self.cards.pop()
return card[0] + card[1]
I am currently learning about class inheritance in python. In the example below, the goal is to remove card pairs(any 2 cards with the same value and color, e.g 3 of hearts and 3 of diamonds) in a single hand containing 13 distinct, random cards.
It seems the error is at line 127: if match in self.cards: . This statement always returns true even if match is not in self.cards . The error is ValueError: list.remove(x): x not in list. Anyone has any idea how to achieve the intended goal? Thanks.
p.s learning through: How to Think Like a Computer Scientist.
class Card:
"""represents a card found in a standard deck with 52 cards."""
suits = ["Clubs", "Diamonds", "Hearts", "Spades"]
ranks = ["narf", "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King"]
def __init__(self, suit=0, rank=0):
self.suit = suit
self.rank = rank
def __str__(self):
return (self.ranks[self.rank] + ' of ' + self.suits[self.suit])
def cmp(self, other):
if self.suit > other.suit:
return 1
if self.suit < other.suit:
return -1
if self.rank < other.rank:
return 1
if self.rank < other.rank:
return -1
return 0
def __eq__(self, other):
return self.cmp(other) == 0
def __le__(self, other):
return self.cmp(other) <= 0
def __lt__(self, other):
return self.cmp(other) < 0
def __ge__(self, other):
return self.cmp(other) >= 0
def __gt__(self, other):
return self.cmp(other) > 0
def __ne__(self, other):
return self.cmp(other) != 0
class Deck:
"""Contains a list of cards as attribute and generates the 52 cards"""
def __init__(self):
self.cards = []
for suit in range(4):
for rank in range(1, 14):
self.cards.append(Card(suit, rank))
def __str__(self):
s = ""
for i in range(len(self.cards)):
s = s + " " * i + str(self.cards[i]) + "\n"
return s
def print_deck(self):
for card in self.cards:
print(card)
def shuffle(self):
"""shuffles the deck of cards randomly."""
import random
rng = random.Random()
rng.shuffle(self.cards)
def remove(self, card):
"""Removes a single specified card from the deck."""
if card in self.cards:
self.cards.remove(card)
return True
else:
return False
def pop(self):
"""Select a single card from the deck"""
return self.cards.pop()
def is_empty(self):
if self.cards == []:
return True
return False
def deal(self, hands, num_cards=52):
"""Deals cards from the deck to a list of hands.
If number of card to deal is not specified, the entire deck is dealt."""
for i in range(num_cards):
if self.cards == []:
break
card = self.pop()
hand = hands[i % len(hands)]
hand.add(card)
class Hand(Deck):
def __init__(self, name=''):
Deck.__init__(self)
self.cards = []
self.name = name
def __str__(self):
string = "The Hand " + self.name
if self.is_empty():
string += 'is empty.\n'
else:
string += ' contains:\n'
return string + Deck.__str__(self)
def add(self, card):
self.cards.append(card)
class CardGame:
def __init__(self):
self.deck = Deck()
self.deck.shuffle()
class OldMaidHand(Hand):
"""Creates a hand for a single player to play a game of Old Maid."""
def remove_matches(self):
cards = self.cards[:]
for card in cards:
match = Card(3 - card.suit, card.rank)
if match in self.cards:
self.cards.remove(card)
self.cards.remove(match)
print('Hand {0} removed {1} and {2}.'
.format(self.name, card, match))
game = CardGame()
player1 = OldMaidHand('test')
game.deck.deal([player1], 13)
player1.print_deck()
player1.remove_matches()
I'm learning Python 2 and I'm trying to create a blackjack game using OOP. Can someone please let me know why I can't do hand.hit() twice after running the code below? It only works once. Why?
Also, can someone please let me know how I can calculate the actual value of a player's hand?
Thanks!
import random
rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace']
suit = ['Diamonds', 'Clubs', 'Hearts', 'Spade']
card_val = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':1}
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __str__(self):
return str(self.rank) + ' of ' + str(self.suit)
def grab_suit(self):
return self.suit
def grab_rank(self):
return self.rank
def draw(self):
print(self.suit + self.rank)
class Deck(object):
def __init__(self):
self.cards = []
for i in rank:
for j in suit:
self.cards.append(Card(i,j))
def __str__(self):
return str([str(card) for card in self.cards])
def shuffle(self):
random.shuffle(self.cards)
def deal(self):
single_card = self.cards.pop()
return single_card
deck = Deck()
class PlayerHand(object):
def __init__(self):
self.value = []
def __str__(self):
return str([str(card) for card in self.value])
def hit(self):
self.hit = self.value.append(deck.deal())
return self.value
hand = PlayerHand()
Well the answer to the first question is pretty easy: You are overwriting your method with "None" (since self.value.append does not return anything).
So you need to change the line:
self.hit = self.value.append(deck.deal())
To
self.value.append(deck.deal())
Calculating the actual value of the hand has been asked already on stackoverflow, therefore I will only answer the first part of the question.