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 !

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.

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])

Edited 5 Years Ago by pyTony: n/a

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
>>>

Edited 5 Years Ago by pyTony: n/a

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)

Edited 5 Years Ago by pyTony: n/a

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.)

Edited 5 Years Ago by pyTony: n/a

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.

Edited 5 Years Ago by woooee: n/a

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)

Edited 5 Years Ago by pyTony: n/a

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()

Edited 5 Years Ago by pyTony: n/a

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'.

Edited 4 Years Ago by pyTony: n/a

This article has been dead for over six months. Start a new discussion instead.