An Introduction to Interactive Programming in Python (Part 2) week 6 (Classes and Tied images)

Objects, classes and their terminology — Object-oriented programming
  • All data entities in Python are objects. Compound objects consist of multiple pieces of data.
  • New types of compound objects can be defined using the keyword class. For example, a class for card decks could be created using the definition statement class Deck:
  • The data for objects in the class are contained in user-defined fields. For example, the Deck class could include a cards field that corresponds to a list of cards.
  • Functions defined inside the class definition are methods.  These method create and manipulate the object and the data in corresponding fields. For example, the Deck class might include a shuffle method that shuffles a Deck object.
  • Lecture examples - Character, Ball
  • More examples - Class Structure, Class Errors
  • Python does not support Overload
Create and working with objects — Object-oriented programming
  • The class initializer __init__ generates instances of class objects. In Python, this initializer can be called via the expression class_name(...). For example, an instance of the Deck class can be created via the statement my_deck = Deck(...).
  • The first parameter to class methods is, by convention, always named self. This name refers to the object being acted on by the method.
  • Class fields for an object are defined/modified in class methods via self.class_field = ... For example, self.cards = [] would assign an empty list to the cards field in a class method for a Deck object.
  • Class methods can be applied to a class object via class_object.class_method(...). For example, a shuffle method could be applied to a deck via the statement my_deck.shuffle().
  • Objects for user-defined classes are mutable. In particular, modification of a field in an object via a class method mutates the object.
  • Lecture examples - Character, Diffusing Particles Blackjack Template
  • More examples - Class Structure, Class Errors, Bubbles, Flowers
  • Each Python class has a hidden constructor method that

    • constructs (makes) the object,
    • calls __init__ to initialize the object,
    • then returns this object.
    • so return statement is no needed in __init__

    # This is the special method that initializes the object
    #	that is being created.
    def __init__(self):
        pass
        
    # This method runs whenever an object is printed.
    def __str__(self):
        pass



Tiled images — Tiled images
  • A tiled image is a single image that consists of a set of smaller images laid out in a regular grid.
  • Tield images are useful since loading a single large image is faster than loading many small images.
  • Small images in the tiled image can be drawn by specifying the appropriate source rectangle for draw_image using the size of the small image and its position in the grid.
  • Lecture examples - Tiled Images
  • More examples - Bunny Emotions
  • Tips: replace www by dl while using dropbox. dl specifies that the file is for download
card_images = simplegui.load_image("http://storage.googleapis.com/codeskulptor-assets/cards_jfitz.png")


Programming Tips Week 6, Prime Numbers (while loops)
# while loop introduction
# while test:
#	body

def get_primes(text):
    if int(text) <= 1:
        print "Please input number bigger than 1"
        return []
    nums = range(2, int(text) + 1)
    ans = []
    # The loop continues until all composite numbers
    #	have been removed from nums and all prime
    #	numbers have been transferred to ans.
    while len(nums) > 0:
        x = nums[0]
        ans.append(nums[0])
        for n in list(nums):
            if n % x == 0:
                nums.remove(n)
    print "Prime numbers in range:", ans
    return ans

Mini-project # 6 - Blackjack

http://www.codeskulptor.org/#user39_y2HWRg78AU_0.py

# Mini-project #6 - Blackjack

import simplegui
import random

# load card sprite - 936x384 - source: jfitz.com
CARD_SIZE = (72, 96)
CARD_CENTER = (36, 48)
card_images = simplegui.load_image("http://storage.googleapis.com/codeskulptor-assets/cards_jfitz.png")

CARD_BACK_SIZE = (72, 96)
CARD_BACK_CENTER = (36, 48)
card_back = simplegui.load_image("http://storage.googleapis.com/codeskulptor-assets/card_jfitz_back.png")    

OFFSET = 40
FONT = "serif"
# initialize some useful global variables
in_play = False
outcome = ""
score = 0

# define globals for cards
SUITS = ('C', 'S', 'H', 'D')
RANKS = ('A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K')
VALUES = {'A':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':10, 'Q':10, 'K':10}


# define card class
class Card:
    def __init__(self, suit, rank):
        if (suit in SUITS) and (rank in RANKS):
            self.suit = suit
            self.rank = rank
        else:
            self.suit = None
            self.rank = None
            print "Invalid card: ", suit, rank

    def __str__(self):
        return self.suit + self.rank

    def get_suit(self):
        return self.suit

    def get_rank(self):
        return self.rank

    def draw(self, canvas, pos):
        card_loc = (CARD_CENTER[0] + CARD_SIZE[0] * RANKS.index(self.rank), 
                    CARD_CENTER[1] + CARD_SIZE[1] * SUITS.index(self.suit))
        canvas.draw_image(card_images, card_loc, CARD_SIZE, [pos[0] + CARD_CENTER[0], pos[1] + CARD_CENTER[1]], CARD_SIZE)
        
# define hand class
class Hand:
    def __init__(self):
        # create Hand object
        self._cards = []

    def __str__(self):
        # return a string representation of a hand
        _str_cards = ""
        for idx in range(len(self._cards)):
            _str_cards += (self._cards[idx].get_suit() + self._cards[idx].get_rank() + " ")
        return "Hand contains " + _str_cards

    def add_card(self, card):
        # add a card object to a hand
        self._cards.append(card)

    def get_value(self):
        # count aces as 1, if the hand has an ace, then add 10 to hand value if it doesn't bust
        # compute the value of the hand, see Blackjack video
        self._value = 0
        _ace_count = 0
        for idx in range(len(self._cards)):
            self._value += VALUES[self._cards[idx].get_rank()]
            if self._cards[idx].get_rank() == "A":
                _ace_count += 1
        if self._value + 10 <= 21 and _ace_count:
            return self._value + 10
        else:
            return self._value
   
    def draw(self, canvas, pos):
        # draw a hand on the canvas, use the draw method for cards
        for idx in range(len(self._cards)):
            self._cards[idx].draw(canvas, [pos[0] + idx * (CARD_SIZE[0] + OFFSET), pos[1]])
        
# define deck class 
class Deck:
    def __init__(self):
        # create a Deck object
        self._cards = [Card(suit, rank) for suit in SUITS for rank in RANKS]

    def shuffle(self):
        # shuffle the deck 
        # use random.shuffle()
        random.shuffle(self._cards)

    def deal_card(self):
        # deal a card object from the deck
        return self._cards.pop()
    
    def __str__(self):
        # return a string representing the deck
        _str_cards = ""
        for idx in range(len(self._cards)):
            _str_cards += (self._cards[idx].get_suit() + self._cards[idx].get_rank() + " ")
        return "Deck contains " +_str_cards


#define event handlers for buttons
def deal():
    global outcome, in_play, status, score
    # Player lose if Deal button is clicked during the middle of a round
    if in_play:
        score -= 1
        status = "You Give up."
        outcome = "New deal?"
        in_play = False
        return

    # Create a blackjack deck and Shuffle
    global bj_deck
    bj_deck = Deck()
    bj_deck.shuffle()
    
    # Create player and dealer hands and add two cards to each hand
    global player_hand, dealer_hand
    player_hand = Hand()
    dealer_hand = Hand()
    
    for dummy_idx in range(2):
        player_hand.add_card(bj_deck.deal_card())
        dealer_hand.add_card(bj_deck.deal_card())
    
    status = ""
    outcome = "Hit or stand?" 
    in_play = True

def hit(): 
    global score, player_hand, bj_deck, in_play, outcome, status
    # if the hand is in play, hit the player
    if player_hand.get_value() <= 21 and in_play:
        player_hand.add_card(bj_deck.deal_card())
    # if busted, assign a message to outcome, update in_play and score
        if player_hand.get_value() > 21:
            in_play = False
            score -= 1
            status = "You have busted and lose" 
            outcome = "New deal?"
        else:
            outcome = "Hit or stand?"
    
def stand():
    global score, player_hand, dealer_hand, bj_deck, in_play, outcome, status
    # if hand is in play, repeatedly hit dealer until his hand has value 17 or more
    if player_hand.get_value() <= 21 and in_play:
        while dealer_hand.get_value() < 17:
            dealer_hand.add_card(bj_deck.deal_card())
    # assign a message to outcome, update in_play and score
        if dealer_hand.get_value() > 21:
            score += 1
            status = "Dealer has busted. You win"
            outcome = "New deal?"
        elif dealer_hand.get_value() >= player_hand.get_value():
            score -= 1
            status = "You Lose."
            outcome = "New deal?"
        elif dealer_hand.get_value() < player_hand.get_value():
            score += 1
            status = "You Win!" 
            outcome = "New deal?"
        in_play = False

# draw handler    
def draw(canvas):
    # test to make sure that card.draw works, replace with your code below
    global score, player_hand, dealer_hand, outcome, in_play
    
    # Draw text
    canvas.draw_text("Blackjack", [120, 100], 50, "Blue", FONT)
    canvas.draw_text("Score  " + str(score), [400, 100], 35, "White", FONT)
    canvas.draw_text("Dealer", [40, 170], 30, "Black", FONT)
    canvas.draw_text(status,  [200, 170], 30, "Navy", FONT)
    canvas.draw_text("Player", [40, 370], 30, "Black", FONT)
    canvas.draw_text(outcome, [200, 370], 30, "Navy", FONT)
    
    # Draw player and dealer hand
    player_hand.draw(canvas, [40, 400])
    dealer_hand.draw(canvas, [40, 200])
    
    if in_play:
        canvas.draw_image(card_back, CARD_BACK_CENTER, CARD_SIZE, 
                          [CARD_BACK_CENTER[0] + 40, CARD_BACK_CENTER[1] + 200], CARD_SIZE)


# initialization frame
frame = simplegui.create_frame("Blackjack", 600, 600)
frame.set_canvas_background("Green")

#create buttons and canvas callback
frame.add_button("Deal", deal, 200)
frame.add_button("Hit",  hit, 200)
frame.add_button("Stand", stand, 200)
frame.set_draw_handler(draw)


# get things rolling
deal()
frame.start()


# remember to review the gradic rubric




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值