1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import simplegui
import random

# 初始化全局变量
# 引用游戏图画
CARD_SIZE = (73, 98)
CARD_CENTER = (36.5, 49)
card_images = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/cards.jfitz.png")

CARD_BACK_SIZE = (71, 96)
CARD_BACK_CENTER = (35.5, 48)
card_back = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/card_back.png")

# 初始化全局变量
in_play = False   #游戏状态
outcome = ""      #控制台输出
score = 0         #用户得分

# 定义纸牌花色、数字以及对应点数
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}

# 定义纸牌类
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.hand = []
    
    def __str__(self):
        sh = [str(card) for card in self.hand]
        return str(sh)

    def add_card(self, card):
        self.hand.append(card)

    def get_value(self):
        hand_value = 0
        for card in self.hand:
            hand_value += VALUES[card.get_rank()]
        for card in self.hand:
            if card.get_rank() == 'A' and hand_value + 10 <= 21:
                hand_value += 10
        return hand_value

    def draw(self, canvas, pos):
        i = 0
        for c in self.hand:
            c.draw(canvas, [pos[0] + i * (10 + CARD_SIZE[0]), pos[1]])
            i += 1

# 定义牌堆类
class Deck:
    def __init__(self):
        self.deck = [Card(s, r) for s in SUITS for r in RANKS]

    def shuffle(self):
        random.shuffle(self.deck)

    def deal_card(self):
        return self.deck.pop(self.deck.index(random.choice(self.deck)))
    
    def __str__(self):
        sd = [str(card) for card in self.deck]
        return str(sd)

# 定义开始按钮功能
def deal():
    global outcome, in_play, player, dealer, deck, score
    player = Hand()
    dealer = Hand()
    deck = Deck()          
    deck.shuffle()  #洗牌
    if in_play:     #若在游戏状态,点击开始则意味着放弃上局游戏,扣一分
        score -= 1
    else:
        outcome = "New Deal. Hit or Stand?"
    player.add_card(deck.deal_card())
    player.add_card(deck.deal_card())
    in_play = False                      #第一张庄家的牌,背面朝上
    dealer.add_card(deck.deal_card())
    in_play = True                       
    dealer.add_card(deck.deal_card())

def hit():
    global outcome, in_play, score, player, dealer, deck
    if in_play and player.get_value() <= 21:  
        if player.get_value() == 21:
            outcome = "BLACKJACK! You win! New deal?"
            score += 1
            in_play = False
        else:
            player.add_card(deck.deal_card())
            if player.get_value() > 21:
                outcome = "Player bust. You lose! New deal?"
                score -= 1
                in_play = False
            else:
                outcome = "Hit or Stand?"

def stand():
    global outcome, in_play, player, dealer, deck, score
    if in_play:
        in_play = False  #锁定游戏状态,庄家底牌摊开
        while dealer.get_value() < 17:  #庄家若点数小于17则继续发牌
            dealer.add_card(deck.deal_card())
        if dealer.get_value() > 21:     #庄家大于21点,爆牌
            score += 1
            outcome = "Dealer bust. You win! New deal?"
        elif dealer.get_value() >= player.get_value():  #庄家点数小于21且大于用户点数,判定为电脑获胜
            score -= 1
            outcome = "You lose! New deal?"
        else:    #庄家点数小于用户,判定为用户获胜
            score += 1
            outcome = "You win! New deal?"

# 作图主函数
def draw(canvas):
    dealer.draw(canvas, [25, 200])    #显示庄家牌
    player.draw(canvas, [25, 400])    #显示玩家牌
    if in_play:     #游戏中,庄家第一张底牌背面朝上,(画在第一张牌的正上方)
        canvas.draw_image(card_back, CARD_BACK_CENTER, CARD_BACK_SIZE, [61, 250], CARD_BACK_SIZE)
    elif not in_play:  #若游戏状态锁定,显示电脑得分
        canvas.draw_text("Card Count:  " + str(dealer.get_value()), [25, 325], 16, "White", "sans-serif")
    canvas.draw_text(outcome, [25, 100], 20, "Yellow", "sans-serif")
    canvas.draw_text("Card Count:  " + str(player.get_value()), [25, 525], 16, "White", "sans-serif")
    canvas.draw_text("Score:  " + str(score), [505, 35], 18, "White", "sans-serif")
    canvas.draw_text("Player", [25, 375], 28, "White", "sans-serif")
    canvas.draw_text("Dealer", [25, 175], 28, "White", "sans-serif")
    canvas.draw_text("Blackjack", [240, 40], 32, "White", "sans-serif")

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

# deal an initial hand
deal()

# start frame
frame.start()

游戏画面

Alt text