Im trying to make a blackjack game that uses a graphical interface, it executes just fine and my IDE isn't giving any error reports which is making it really difficult to finish it. I posted some of my worries about why it won't operate. Any help, general comments, or wise words of learning wisdom would be greatly appriciated even if it won't get the program running.

import random as random
from graphics import *

class DeckOfCards(object):
    def __init__(self, *cards):
        """Make a deck of cards with variable suit and value"""
        if not cards:
            self.make_deck()
            random.shuffle(self.deck)
        else:
            self.deck = cards
        
    def deal(self, num=1):
        for count in range(num):
            yield self.deck.pop(0)
        
    def make_deck(self):
        """Prepare deck"""
        self.values=["1","2","3","4","5","6","7","8","9","10","j","q","k"]
        self.suits = ["h","s","d","c"]

        self.deck = [(value, suit)
                     for value in self.values
                     for suit in self.suits]

    def get_deck(self):
        return self.deck

class Button:

    """A button is a labeled rectangle in a window.
    It is activated or deactivated with the activate()
    and deactivate() methods. The clicked(p) method
    returns true if the button is active and p is inside it."""

    def __init__(self, win, center, width, height, label):
        """ Creates a rectangular button, eg:
        qb = Button(myWin, centerPoint, width, height, 'Quit') """ 

        w,h = width/2.0, height/2.0
        x,y = center.getX(), center.getY()
        self.xmax, self.xmin = x+w, x-w
        self.ymax, self.ymin = y+h, y-h
        p1 = Point(self.xmin, self.ymin)
        p2 = Point(self.xmax, self.ymax)
        self.rect = Rectangle(p1,p2)
        self.rect.setFill('lightgray')
        self.rect.draw(win)
        self.label = Text(center, label)
        self.label.draw(win)
        self.deactivate()

    def clicked(self, p):
        "Returns true if button active and p is inside"
        return (self.active and
                self.xmin <= p.getX() <= self.xmax and
                self.ymin <= p.getY() <= self.ymax)

    def getLabel(self):
        "Returns the label string of this button."
        return self.label.getText()

    def activate(self):
        "Sets this button to 'active'."
        self.label.setFill('black')
        self.rect.setWidth(2)
        self.active = True

    def deactivate(self):
        "Sets this button to 'inactive'."
        self.label.setFill('darkgrey')
        self.rect.setWidth(1)
        self.active = False

class GUIcards:
    def __init__(self,deck):
        """This carries out the main program and the graphics interface"""
        self.win=GraphWin("Game Board",400,400)
        self.win.setCoords(-2,-2,2,2)
        self.win.setBackground("blue")
        self.gameDeck=deck
        self.cardCount=0
        self.turn=3
        self.player_points=0
        self.player_aces=0
        self.dealer_points=0
        self.dealer_aces=0
        
    def drawInitCards(self):
        """Draw and count the first two drawn cards"""
        p=Point(1,1)
        for x in range(1,3):
            #drawing backside cards for the dealer
            value,suit=self.gameDeck[self.cardCount]
            Image(p,"b1fv.gif").draw(self.win)
            p=Point(1-x*(.2),1)
            self.cardCount+=1
            points,ace=value_card(value)
            #Test for ace, add 11 or 1
            if ace:
                self.dealer_aces+=1
                if 21-self.dealer_points<=10:
                    self.dealer_points+=11
    
                else:
                    self.dealer_points+=1

            else:
                self.dealer_points+=points

        #draw and count player cards
        p=Point(-1,-1)
        for x in range(1,3):
            value,suit=self.gameDeck[self.cardCount]
            Image(p,"{0}{1}.gif".format(suit,value)).draw(self.win)
            p=Point(-1+x*(.2),-1)
            self.cardCount+=1
            points,ace=value_card(value)
            #Test for ace, add 11 or 1
            if ace:
                self.player_aces+=1
                if 21-self.player_points<=10:
                    self.player_points+=11
    
                else:
                    self.player_points+=1

            else:
                self.player_points+=points

    def runGame(self):
        """Main call function, test for game over arguements and carries out the turns,
        I think my problem is that the turns are wrote to be the entire counting process,
        and game_over is wrote to be per turn, would be a big help for help on this part"""
        while self.game_over() and cardCount>52:
            ButtList=self.buttons()
            self.drawInitCards()
            
            self.player_turn()
            self.dealer_turn()

        self.win.close()
        
    def player_turn(self):        
        #player turn
        Turn=1
        while Turn:
            HasAce=False
            #Test for mouse click
            p=self.win.getMouse()
            for x in ButtList:
                test=x.clicked(p)
                if test:
                    test=x.getLabel()
                
                #Test for button clicking
                if test=="Quit":
                    self.win.close()

                elif test=="Hit":
                    p=Point(-1,-1)
                    value,suit=self.gameDeck[self.cardCount]
                    Image(p,"{0}{1}.gif".format(suit,value)).draw(self.win)
                    p=Point(-1+self.turn*(.2),-1)
                    self.cardCount+=1

                    points,ace=value_card(value)
                    #Test for ace, add 11 or 1
                    if ace:
                        self.player_aces+=1
                        if 21-self.dealer_points<=10:
                            self.player_points+=11
            
                        else:
                            self.player_points+=1

                    else:
                        self.player_points+=points

                elif self.player_points>21:
                    Turn=0
                    
                else:
                    Turn=0
                    
    def dealer_turn(self):
        p=Point(1,1)
        HasAce=False
        if self.dealer_points<17:
            value,suit=self.gameDeck[self.cardCount]
            Image(p,"b1fv.gif").draw(self.win)
            p=Point(1+self.turn*(.2),1)
            self.cardCount+=1
            #Set card value
            points,ace=value_card(value)
            #Test for ace, add 11 or 1
            if ace:
                if 21-self.dealer_points<=10:
                    self.dealer_points+=11
    
                else:
                    self.dealer_points+=1

            else:
                self.dealer_points+=points


    def value_card(self,value):
        """Test the value of the cards to make code clearer"""
        if value=="j" or value=="q" or value=="k":
            points = 10

        elif value==("1"):
            ace=True

        else:
            points=eval(value)

        return points,ace

    def game_over(self):
        """Test the game if someone went over 21(breaking) and add aces to the most efficent amount"""
        test_break=0
        while self.dealer_points>21 or self.player_points>21:
            while self.player_aces and test_break<=21:
                if test_break==test_break+self.player_points+11<=21:
                    self.player_aces-=1
                    test_break+=self.player_points+11<=21
                    return True

                else:
                    self.player_points+=1
                    self.player_aces-=1
                    test_break+=self.player_points+1

        if self.player_points>21:
            Text(Point(0,0),"Dealer wins!").draw(self.win)
            return False
                
        while self.dealer_aces and test_break<=21:
            if test_break==test_break+self.dealer_points+11<=21:
                self.dealer_aces-=1
                test_break+=self.dealer_points+11<=21

            else:
                self.dealer_points+=1
                self.player_aces-=1
                test_break+=self.dealer_points+1

        if self.dealer_points>21 and self.player_points<=21:
            Text(Point(0,0),"You win!").draw(self.win)
            return False

        else:
            Text(Point(0,0),"Dealer wins!").draw(self.win)
            return False

        return True

                
    def buttons(self):
        ButtList=[]
        b=Button(self.win,Point(1.75,-1.75),.5,.4,"Quit")
        ButtList.append(b)
        b=Button(self.win,Point(1.75,-1.3),.5,.4,"Pass")
        ButtList.append(b)
        b=Button(self.win,Point(1.75,-.85),.5,.4,"Hit")
        ButtList.append(b)
        for x in ButtList:
            x.activate()

        return ButtList


blackjack=GUIcards(DeckOfCards().get_deck())
blackjack.runGame()

I used a tracer module and got the following output

0. GUIcards.runGame(): # call, line 280 in blackjack.py
  1. GUIcards.game_over(): # call, line 135 in blackjack.py
    return False
  return None

So what happened is that your first call to game_over() returned False at line 135 and the body of the while was not executed.

If you want to use my (home made) tracer module (called tracepect), you must first download and install the aspects module from here http://www.cs.tut.fi/~ask/aspects/download.shtml, then unzip the attached file tracepect.py
and put it on the python path, finally, replace the 2 last lines of your program by

if __name__ == "__main__":
    from tracepect import Tracer
    t = Tracer()
    t.wrap_classes(GUIcards)
    blackjack=GUIcards(DeckOfCards().get_deck())
    blackjack.runGame()

Edited 6 Years Ago by Gribouillis: n/a

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