莱斯大学交互式编程练习——BlackJack

本课程为莱斯大学在cousera上Python网课的课后作业
链接:Python交互式程序设计入门
二十一点是一种扑克牌游戏,起源于法国,参加者尽量使手中牌的总点数达到21点,或是接近21点,但不能超过,再和庄家比较总点数的大小以定输赢。游戏截图如下:

在这里插入图片描述
该交互式程序使用了SimpleGUI库进行界面设计,具体代码如下:

import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
import random

# Mini-project #6 - Blackjack
# 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") 

# 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):
        self.cards = [] # create Hand object
        
    def __str__(self):
        return [str(card) for card in self.cards]
        
    def add_card(self, card):
        self.cards.append(card) # add a card object to a hand

     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
        value = 0
        A_exist = False
        for card in self.cards:        # compute the value of the hand, see Blackjack video
            if isinstance(card, Card):
                value += VALUES[card.get_rank()]
                if card.get_rank() == 'A':
                    A_exist = True

        if A_exist and value + 10 <= 21:
            value += 10
        return value

    def draw(self, canvas, pos):
        for card_index in range(len(self.cards)): # draw a hand on the canvas, use the draw method for cards
            if card_index <= 4:
                self.cards[card_index].draw(canvas, pos[card_index])

# define deck class 
class Deck:
    def __init__(self):
        self.cards = [Card(suit, rank) for suit in SUITS for rank in RANKS]# create a Deck object

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

    def deal_card(self):
        return self.cards.pop() # deal a card object from the deck

    def __str__(self):
        return [str(card) for card in self.cards]

#define event handlers for buttons
def timer_handler():
    global outcome, timer
    outcome = ''
    timer.stop()

def deal():
    global outcome, in_play, player, dealer, dec, score, timer
    if not in_play:
        outcome = ''      
    else:
        score -= 1
        outcome = 'dealer wins'
        timer = simplegui.create_timer(1000, timer_handler)
        timer.start()

    dealer, player = Hand(), Hand()
    dec = Deck()
    dec.shuffle()
    dealer.add_card(dec.deal_card())
    dealer.add_card(dec.deal_card())
    player.add_card(dec.deal_card())
    player.add_card(dec.deal_card())
    in_play = True

def hit():
    global outcome, in_play, player, dealer, dec, score
    # if the hand is in play, hit the player
    if in_play:
        player.add_card(dec.deal_card())
    # if busted, assign a message to outcome, update in_play and score
        if player.get_value() > 21:
            in_play = False
            score -= 1
            outcome = 'player went bust, dealer wins'

def stand():
    global outcome, in_play, player, dealer, dec, score
    # if hand is in play, repeatedly hit dealer until his hand has value 17 or more
    if in_play:
        while dealer.get_value() < 17:
            dealer.add_card(dec.deal_card())
    # assign a message to outcome, update in_play and score
        if dealer.get_value() > 21:
            in_play = False
            score += 1
            outcome = 'dealer went bust, player wins'
        else:
            if dealer.get_value() >= player.get_value():
                in_play = False
                score -= 1
                outcome = 'dealer wins'
            else:
                in_play = False
                score += 1
                outcome = 'player wins'

# draw handler    
def draw(canvas):
    # test to make sure that card.draw works, replace with your code below
    pos_player = [[84, 420], [174, 420], [264, 420], [354, 420], [444, 420]]
    pos_dealer = [[84, 172], [174, 172], [264, 172], [354, 172], [444, 172]]
    canvas.draw_text('Score = %d'%score, [495, 20], 20, 'White')
    canvas.draw_text(outcome, [250, 150], 30, 'Red')
    canvas.draw_text('Dealer', [80, 150], 30, 'White')
    canvas.draw_text('Player', [80, 400], 30, 'White')
    canvas.draw_text('Blackjack', [80, 80], 50, 'Black')
    if in_play:
        canvas.draw_image(card_back, CARD_CENTER, CARD_SIZE, [120, 220], CARD_BACK_SIZE)
        dealer.cards[1].draw(canvas, pos_dealer[1])
        canvas.draw_text('Hit or stand?', [250, 400], 30, 'White')
    else:
        dealer.draw(canvas, pos_dealer)
        canvas.draw_text('New deal?', [250, 400], 30, 'White')
    player.draw(canvas, pos_player)

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

详细作业要求参考课程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值