Hi. i am trying to create deck of cards for uno game. i need to create draw and undraw functions for each card class. i dont know how to do this..
Thanks !
What have you tried? What worked? What didn't? Do you have a specific question?
class StandardCards:
def __init__(self,c,n):
self.color = c
self.number = n
def as_string(self):
return self.color + " " + str(self.number)
class WildCard:
def __init__(self):
self.is_draw_4 = False
def as_string(self):
if self.is_draw_4 == False:
return "Wild"
else:
return "Wild Draw 4"
class ReversCard:
def __init__(self,c):
self.color = c
def as_string(self):
return self.color + "Reverse"
class SkipCard:
def __init__(self,c):
self.color = c
def as_string(self):
return self.color + "Skip"
class DrawCard:
def __init__(self,c):
DrawCard.color = c
def as_string(self):
return self.color + " Draw 2 "
class player:
def as_string(self,name,pid):
self.name = name
self.pid = pid
self.cards = []
def as_string(self):
results = self.name
for card in self.cards:
results = results+ " " +self.card[0].as_string()
return results
def create_deck():
deck = []
for i in range(10):
for color in ['blue','green','red','yellow']:
if i == 0:
card = StandardCards(color,i)
deck.append(card)
else:
card = StandardCards(color,i)
deck.append(card)
card = StandardCards(color,i)
deck.append(card)
# makes the wild card
for i in range(4):
card = WildCard()
deck.append(card)
#makes wild card that is a draw 4
for i in range(4):
cards = WildCard()
card.is_draw_4 = True
deck.append(card)
return deck
def deal_one_card(p,deck):
if len(deck)==0:
return
i = randint(0,len(deck)-1)
p.cards.append(deck[i])
deck.remove(deck[i])
def create_discard_pile(deck):
discard_pile = []
i = randint(0,len(deck)-1)
discard_pile.append(deck[i])
deck.remove(deck[i])
return discard_pile
def deal(p1,p2,p3,p4,deck):
for i in range(7):
deal_one_card(p1,deck)
deal_one_card(p2,deck)
deal_one_card(p3,deck)
deal_one_card(p4,deck)
p1 = Player("Jim",1)
p2 = Player("John",2)
p3 = Player("sean",3)
p4 = Player("james",4)
deck = create_deck()
deal(p1,p2,p3,p4,deck)
discard_pile = create_discard_pile(deck)
print(p1.as_atring())
print(p2.as_String())
print(p3.as_string())
print(p4.as_atring())
print(discard_pile(-1).as_string())
this is what i tried so far. it keeps saying player is not defined. i want to modify the deck of cards too.
Python doesn't allow overloading functions the way you're trying to do it at lines 44 and 49 (use *args or **kwargs to provide default trailing parameters: http://docs.python.org/tutorial/controlflow.html#default-argument-values
Your player class should be spelled with a capital 'P' to avoid confusion (http://www.python.org/dev/peps/pep-0008/)
I don't see anything else obvious just looking.
Next time do some effort to debug basic things that interpreter complains about. Here quick clean up:
from random import randint
class StandardCards:
def __init__(self,c,n):
self.color = c
self.number = n
def __str__(self):
return self.color + " " + str(self.number)
__repr__ = __str__
class WildCard:
def __init__(self):
self.is_draw_4 = False
def __str__(self):
if self.is_draw_4 == False:
return "Wild"
else:
return "Wild Draw 4"
__repr__ = __str__
# never used card
class ReversCard:
def __init__(self,c):
self.color = c
def __str__(self):
return self.color + "Reverse"
__repr__ = __str__
class SkipCard:
def __init__(self,c):
self.color = c
def __str__(self):
return self.color + "Skip"
__repr__ = __str__
class DrawCard:
def __init__(self,c):
DrawCard.color = c
def __str__(self):
return self.color + " Draw 2 "
__repr__ = __str__
class Player:
def __init__(self,name,pid):
self.name = name
self.pid = pid
self.cards = []
def __str__(self):
return '%s: %s' % (self.name, ', '.join(str(card) for card in self.cards))
__repr__ = __str__
def create_deck():
deck = []
for i in range(10):
for color in ['blue','green','red','yellow']:
if i == 0:
card = StandardCards(color,i)
deck.append(card)
else:
card = StandardCards(color,i)
deck.append(card)
card = StandardCards(color,i)
deck.append(card)
# makes the wild card
for i in range(4):
card = WildCard()
deck.append(card)
#makes wild card that is a draw 4
for i in range(4):
cards = WildCard() # never used
card.is_draw_4 = True
deck.append(card)
return deck
def deal_one_card(p,deck):
if len(deck)==0:
return
i = randint(0,len(deck)-1)
p.cards.append(deck[i])
deck.remove(deck[i])
def create_discard_pile(deck):
discard_pile = []
i = randint(0,len(deck)-1)
discard_pile.append(deck[i])
deck.remove(deck[i])
return discard_pile
def deal(p1,p2,p3,p4,deck):
for i in range(7):
deal_one_card(p1,deck)
deal_one_card(p2,deck)
deal_one_card(p3,deck)
deal_one_card(p4,deck)
if __name__ == '__main__':
p1 = Player("Jim",1)
p2 = Player("John",2)
p3 = Player("sean",3)
p4 = Player("james",4)
deck = create_deck()
deal(p1,p2,p3,p4,deck)
discard_pile = create_discard_pile(deck)
print(p1)
print(p2)
print(p3)
print(p4)
print(discard_pile[-1])
Thank you that looks much better :)
it gives me error for p1 = Player("jimm",1)
it says object.__new__() takes n parameters...
I do not get error:
Python 3.2.1
Jim: blue 6, red 9, red 4, Wild, blue 5, green 7, red 1
John: Wild, yellow 5, yellow 6, blue 7, red 6, green 6, green 2
sean: green 4, green 8, green 5, yellow 2, blue 9, red 6, red 5
james: yellow 3, red 7, yellow 5, yellow 9, green 0, blue 1, yellow 4
blue 8
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Jim: red 9, blue 9, red 1, blue 7, blue 1, green 3, blue 6
John: red 2, green 9, green 4, green 7, Wild, blue 2, red 4
sean: yellow 4, green 6, yellow 5, red 0, red 5, green 6, red 3
james: yellow 1, blue 3, green 2, green 3, yellow 9, Wild Draw 4, green 1
blue 3
>>>
from random import randint
class StandardCards:
def __init__(self,c,n):
self.color = c
self.number = n
def __str__(self):
return self.color + " " +str(self.number)
__repr__ = __str__
class WildCard:
def __init__(self):
self.draw4 = False
def __str__(self):
if self.draw4 == False:
return "Wild"
else:
return "Wild Draw4"
__repr__ = __str__
# never used card
class ReverseCard:
def __init__(self,c):
self.color = c
def __str__(self):
return self.color + "Reverse"
__repr__ = __str__
class SkipCard:
def __init__(self,c):
self.color = c
def __str__(self):
return self.color + "Skip"
__repr__ = __str__
class DrawCard:
def __init__(self,c):
DrawCard.color = c
def __str__(self):
return self.color + "Draw 2"
__repr__ = __str__
class Player:
def __init__(self,name,pid):
self.name = name
self.pid = pid
self.cards = []
def __str__(self):
return '%s: %s' % (self.name, ', '.join(str(card) for card in self.cards))
__repr__ = __str__
def create_deck():
deck = []
for i in range(10):
for color in ['blue','green','red','yellow']:
if i == 0:
card = StandardCards(color,i)
deck.append(card)
else:
card = StandardCards(color,i)
deck.append(card)
card = StandardCards(color,i)
deck.append(card)
#makes wild card
for i in range(4):
cards = WildCard()
card.draw4 = True
deck.append(card)
return deck
def deal_one_card(p,deck):
if len(deck)==0:
return
i = randint(0,len(deck)-1)
p.cards.append(deck[i])
deck.remove(deck[i])
def create_discard_pile(deck):
discard_pile = []
i = randint(0,len(deck)-1)
discard_pile.append(deck[i])
deck.remove(deck[i])
return discard_pile
def deal(p1,p2,p3,p4,deck):
for i in range(7):
deal_one_card(p1,deck)
deal_one_card(p2,deck)
deal_one_card(p3,deck)
deal_one_card(p4,deck)
if __name__=='__main__':
p1 = Player("jim",1)
p2 = Player("John",2)
p3 = Player("sean",3)
p4 = Player("james",4)
deck = create_deck()
deal(p1,p2,p3,p4,deck)
discard_pile = create_discard_pile(deck)
print(p1)
print(p2)
print(p3)
print(p4)
print(discard_pile[-1])
my code. and the error is :
Traceback (most recent call last):
File "C:/Users/Pelin/Desktop/unodeck2.py", line 123, in <module>
discard_pile = create_discard_pile(deck)
File "C:/Users/Pelin/Desktop/unodeck2.py", line 103, in create_discard_pile
i = randint(0,len(deck)-1)
File "C:\Python32\lib\random.py", line 215, in randint
return self.randrange(a, b+1)
File "C:\Python32\lib\random.py", line 193, in randrange
raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (0,0, 0)
lines 88-92 and 126- are indented wrong, cards variable is never used. Draw card init is wrong (now not used yet, as reverse and skip also)
i fixed that but the error is on 97 ,123,67
Traceback (most recent call last):
File "C:\Users\Pelin\Desktop\unodeck2.py", line 127, in <module>
discard_pile = create_discard_pile(deck)
File "C:\Users\Pelin\Desktop\unodeck2.py", line 107, in create_discard_pile
i = randint(0,len(deck)-1)
File "C:\Python32\lib\random.py", line 215, in randint
return self.randrange(a, b+1)
File "C:\Python32\lib\random.py", line 193, in randrange
raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (0,0, 0)
how come yours is working but not mine it is the same code.
you are still returning inside for.
No, your code is different, compare indention (difficult to see as you have extra blank lines inside if.)
i dont know i couldnt see. Thanks Though
i finished it thans alot ! i just needed to fix return function like you said
def create_deck():
deck = []
for i in range(10):
for color in ['blue','green','red','yellow']:
if i == 0:
card = StandardCards(color,i)
deck.append(card)
else:
card = StandardCards(color,i)
deck.append(card)
card = StandardCards(color,i)
deck.append(card)
You create 1 + 2*9 cards for each of the colors=76 cards, plus the wild cards.
The deck consists of a total of 108 cards of four colors: red, green, blue, and yellow. The ranks in each color are 0-9, with two of each number per color, except 0 which only appears once per color. There are two each of three "action" cards in each color, labeled "skip", "draw two", and "reverse". There are also special black action cards, "wild" and "wild draw four", of which there are four each. In older versions, only the 6 is underlined to distinguish it from the 9, which is not marked; newer versions have both the 6 and the 9 underlined to further distinguish the two ranks.(wikipedia)
So adding the 8 wild cards, which it appears is what the code is trying to do, makes 84, so the problem is in the wild cards which should be 32 to make 108 cards, but so far we only have info on 14 more cards, 6 action cards + 8 black action cards. Are there 2 sets of 9 more cards or 6 sets of 3 more cards? In any case, the OP is not finished with the code if a complete deck is the desired result. But the deck may also be simplified for this exercise. We won't know unless the OP posts back.
yeah its not complete yet. I download the uno graphics. now i have to modify the draw and undraw functions. Adding colors and drawing cards. i tried many things but the only think i could do really was to change the back ground of the little box. i dont know how to draw those cards
class Draw2Card:
def __init__(self,c):
self.color = c
self.number = -1
self.drawn = False
def draw(self,win):
if self.drawn:
return
self.rect = Rectangle(Point(0,0),Point(CARD_WIDTH,CARD_HEIGHT))
self.rect.draw(win)
self.rect.setFill(self.color)
self.text = Text(Point(CARD_WIDTH/2,CARD_HEIGHT/2),self.number)
self.text.draw(win)
self.drawn = True
of course the code itself is very long but if i could understand how to draw add colors or shapes i can modify others aswell
I do not know exactly, what you want, but here is how I used your code modified to draw 3 cards:
from graphics import *
CARD_WIDTH, CARD_HEIGHT = 60, 100
class Draw2Card:
def __init__(self, win, c, number):
self.color = c
self.number = number
self.parent = win
self.draw(self.parent)
def draw(self, win):
self.rect = Rectangle(Point(0, 0), Point(CARD_WIDTH, CARD_HEIGHT))
self.rect.draw(win)
self.rect.setFill(self.color)
self.text = Text(Point(CARD_WIDTH / 2, CARD_HEIGHT / 2), self.number)
self.text.draw(win)
def move(self, x=1, y=0):
self.rect.move(x * CARD_WIDTH, y * CARD_WIDTH)
self.text.move(x * CARD_WIDTH, y * CARD_WIDTH)
win = GraphWin("Uno")
cards = []
for number, card in enumerate((Draw2Card(win, 'red', 2),
Draw2Card(win, 'yellow', 5),
Draw2Card(win, 'green', 1))):
card.move(number)
cards.append(card)
win.getMouse()
win.close()
is there anything wrong here ? the numbers inside the uno cards do not appear.
class WildCard:
def __init__(self):
self.is_draw_4 = False
self.color = "black"
self.number = -1
self.drawn = False
def draw(self,win):
if self.drawn:
return
self.rect = Rectangle(Point(0,0),Point(CARD_WIDTH,CARD_HEIGHT))
self.rect.draw(win)
self.rect.setFill(self.color)
self.text = Text(Point(CARD_WIDTH/2,CARD_HEIGHT/2),self.number)
self.text.draw(win)
self.text.setFill("white")
self.drawn = True
self.oval = Oval(Point(CARD_WIDTH/2,CARD_HEIGHT/2))
self.oval.setFill("red")
self.oval.draw(win)
self.text.setSize(5)
def undraw(self):
self.rect.undraw()
self.text.undraw()
self.oval.undraw()
def move_to(self,x,y):
center = self.rect.getCenter()
dx = x - center.getX()
dy = y - center.getY()
self.move(dx,dy)
def move(self,dx,dy):
self.text.move(dx,dy)
self.rect.move(dx,dy)
self.oval.move(dx,dy)
def is_clicked(self,p):
center = self.rect.getCenter()
x1 = center.getX() - CARD_WIDTH/2
x2 = center.getX() + CARD_WIDTH/2
y1 = center.getY() - CARD_HEIGHT/2
y2 = center.getY() + CARD_HEIGHT/2
x = p.getX()
y = p.getY()
if x >= x1 and x <= x2 and y >= y1 and y <= y2:
return True
else:
return False
def as_string(self):
if self.is_draw_4 == False:
return "wild"
else:
return "wild draw 4"
from graphics import *
CARD_WIDTH, CARD_HEIGHT = 60, 100
class Draw2Card:
def __init__(self, win, c, number):
self.color = c
self.number = number
self.parent = win
self.draw(self.parent)
def draw(self, win):
self.rect = Rectangle(Point(0, 0), Point(CARD_WIDTH, CARD_HEIGHT))
self.rect.draw(win)
self.rect.setFill(self.color)
self.text = Text(Point(CARD_WIDTH / 2, CARD_HEIGHT / 2), self.number)
self.text.draw(win)
def move(self, x=1, y=0):
self.rect.move(x * CARD_WIDTH, y * CARD_WIDTH)
self.text.move(x * CARD_WIDTH, y * CARD_WIDTH)
def __str__(self):
return self.color + " " + str(self.number)
__repr__ = __str__
class WildCard:
def __init__(self, parent):
self.is_draw_4 = False
self.color = "black"
self.number = "wild"
self.draw(parent)
def draw(self,win):
self.rect = Rectangle(Point(0,0),Point(CARD_WIDTH,CARD_HEIGHT))
self.rect.draw(win)
self.rect.setFill(self.color)
self.oval = Oval(Point(CARD_WIDTH,CARD_HEIGHT), Point(0,0))
self.oval.setFill("red")
self.oval.draw(win)
self.text = Text(Point(CARD_WIDTH/2,CARD_HEIGHT/2),self.number)
self.text.draw(win)
self.text.setFill("white")
self.drawn = True
self.text.setSize(15)
def undraw(self):
self.rect.undraw()
self.text.undraw()
self.oval.undraw()
def move_to(self,x,y):
center = self.rect.getCenter()
dx = x - center.getX()
dy = y - center.getY()
self.move(dx,dy)
def move(self,dx,dy):
self.text.move(dx,dy)
self.rect.move(dx,dy)
self.oval.move(dx,dy)
def is_clicked(self,p):
center = self.rect.getCenter()
x1 = center.getX() - CARD_WIDTH/2
x2 = center.getX() + CARD_WIDTH/2
y1 = center.getY() - CARD_HEIGHT/2
y2 = center.getY() + CARD_HEIGHT/2
x = p.getX()
y = p.getY()
if x >= x1 and x <= x2 and y >= y1 and y <= y2:
return True
else:
return False
def __str__(self):
if self.is_draw_4 == False:
return "wild"
else:
return "wild draw 4"
__repr__ = __str__
win = GraphWin("Uno")
cards = []
for number, card in enumerate((Draw2Card(win, 'red', 2),
Draw2Card(win, 'yellow', 5),
Draw2Card(win, 'green', 1))):
card.move(number)
cards.append(card)
wild = WildCard(win)
wild.move(0, CARD_HEIGHT)
cards.append(wild)
print(cards)
win.getMouse()
win.close()
How can i change as_string() to __str__ in this code ?
def play_a_card(self,color,number):
for i in range(len(self.cards)):
if (self.cards[i].as_string().find(color) and
self.cards[i].as_string().find(str(number)) and
self.cards[i].as_string().find("draw")== -1):
self.cards.remove(card)
return card
i did something like this but now it gives me error for >==0 part.
if (self.cards[i].__str__.find(color)>== 0 and
self.cards[i].__str__.find(str(number))>==0 and
self.cards[i].__str__.find("draw")== -1):
self.cards.remove(card)
return card
__repr__ = __str__
How can i change as_string() to __str__ in this code ?
def play_a_card(self,color,number): for i in range(len(self.cards)): if (self.cards[i].as_string().find(color) and self.cards[i].as_string().find(str(number)) and self.cards[i].as_string().find("draw")== -1): self.cards.remove(card) return card
color in str(card)
if you iterate cards instead of indexing them (otherwise card is undefined in return) You should however use correct value from card (card.color == color ...) as you can not separate '1', '0' and '10'.
Can you give an example i am still not clear
I have given much too much already, it is your homework.
lol
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.