ブラックジャックを作る 11~12 (完)

今回で無事完了です。
 
もしコピペで検証される場合は、code内に全角に変換された半角文字(” ‘ : () など)が
有りますので、editerで半角に修正してください。
 
根本的に修正するには、これはWordPressの標準機能をPHPで書替えが必要になります。

もっとレベルが上がったらchallengeしてみたいと思います。
 
**********************************************
 
 
ブラックジャックを作るー11
 
このcodeで次の処理を追加しました。
・playerがBJの場合は1.5倍の支払を受ける OK
・dealerの得点計算はOK
・ 勝敗判定も追加した
 
 1import random Tak-2-5-list23.py
 2  
 3RANK, SUIT = 0, 1 
 4  
 5def win_lose(dealer_hand, player_hand, bet ,player_money):#勝敗の判定
 6    player_point=get_point(player_hand) 
 7    dealer_point=get_point(dealer_hand) 
 8    if player_point <= 21: 
 9        if (player_point > dealer_point) or (dealer_point > 21) : 
 10            if player_point==21: 
 11                return (‘<<プレイヤーの勝ち>>’,player_money + int(bet*2.5))#BJの場合1.5倍計算
 12            else: 
 13                return (‘<<プレイヤーの勝ち>>’,player_money + 2*bet) 
 14        elif player_point == dealer_point: 
 15            return (‘<<プッシュ>>’,player_money + bet) 
 16        else: 
 17           return (‘<<プレイヤーの負け>>’,player_money) 
 18    else: 
 19        return (‘<<プレイヤーの負け>>’,player_money) 
 20  
 21def player_op(deck, player_hand, op): 
 22    ending = False 
 23    if op == ‘1’: 
 24        print(‘[ プレイヤー:スタンド ]’) 
 25        ending = True 
 26    elif op == ‘2’: 
 27        print(‘[ プレイヤー:ヒット ]’) 
 28        player_hand.append(deck.pop()) 
 29        print_player_hand(player_hand) 
 30        ending = False 
 31  
 32    if get_point(player_hand) > 21: #バスト判定
 33        print(‘[ プレイヤーはバストした! ]’) 
 34        ending = True 
 35    elif get_point(player_hand) == 21: 
 36        print (’21です!’) 
 37        ending = True 
 38  
 39    return ending 
 40  
 41def dealer_op(deck,player_hand,dealer_hand): 
 42    while get_point(player_hand) <= 21: 
 43        if get_point(dealer_hand) >= 17: 
 44            print(‘[ ディーラー:スタンド ]’) 
 45            break 
 46        else: 
 47            print(‘[ ディーラー:ヒット ]’) 
 48            dealer_hand.append(deck.pop()) 
 49        print_dealer_hand(dealer_hand, False) 
 50  
 51def get_point(hand): 
 52    result = 0 
 53    ace_flag = False 
 54    for card in hand: 
 55        if card[RANK] == 1: 
 56            ace_flag = True 
 57        if card[RANK] > 10: 
 58            num = 10 
 59        else: 
 60            num = card[RANK] 
 61        result = result + num 
 62    if ace_flag and result <= 11: 
 63        result += 10 
 64    return result 
 65  
 66# print_player_hand関数 
 67def print_player_hand(player_hand): 
 68    print(‘プレイヤー (‘, get_point(player_hand), ‘):     ‘) 
 69    for card in player_hand: 
 70        print(‘[‘, card[SUIT], card[RANK], ‘]’) 
 71    print() 
 72  
 73# print_dealer_hand関数 
 74def print_dealer_hand(dealer_hand, uncovered): 
 75    if uncovered : 
 76        print(‘ディーラー (‘, get_point(dealer_hand), ‘):     ‘) 
 77     
 78    #    print(‘ディーラー ( ?? ):     ‘)#表示させているので今は不要
 79    flag = True 
 80    for card in dealer_hand: 
 81        if flag or uncovered: 
 82            print(‘[‘ , card[SUIT], card[RANK], ‘]’) 
 83            flag = True 
 84        else: 
 85            print(‘[ * * ]’) 
 86    print() 
 87  
 88def make_deck(): 
 89    suits = [‘S’, ‘H’, ‘D’, ‘C’]     # スート(記号)の定義
 90    ranks = range(1, 14)             # ランク(数字)の定義
 91    deck = [(x,y) for x in ranks for y in suits] 
 92    random.shuffle(deck)             # シャッフルする
 93    return deck 
 94  
 95def main(): 
 96    turn = 1 
 97    player_money = 100 
 98    deck = make_deck()  
 99  
 100    while player_money > 0: 
 101        print(‘ターン:’, turn) 
 102        print(‘所持金:’, player_money) 
 103  
 104        player_hand = [] # プレイヤーの手札を格納するリスト
 105        dealer_hand = [] # ディーラーの手札を格納するリスト
 106  
 107        try: 
 108            bet = int(input(‘ベット額 > ‘)) 
 109        except: 
 110            print(‘整数で入力してください’) 
 111            continue 
 112  
 113        # 入力値が所持金を超えていたらやり直し 
 114        if bet > player_money: 
 115            print(‘所持金が不足しています’) 
 116            continue 
 117        # 入力値が0より小さかったらやり直し 
 118        elif bet <= 0: 
 119            print(‘ベットできる額は1以上です。’) 
 120            continue 
 121  
 122        player_money -= bet 
 123  
 124        # デッキの残りが10枚以下ならデッキを再構築&シャッフル 
 125        if len(deck) < 10: 
 126            deck = make_deck() 
 127  
 128        for i in range(2): # お互いに2枚ずつ引く 
 129            player_hand.append(deck.pop()) # デッキからプレイヤーの手札へ
 130            dealer_hand.append(deck.pop())# デッキからディーラーの手札へ
 131  
 132        #print(player_hand) 
 133        print_player_hand(player_hand) 
 134  
 135        #print(dealer_hand) 
 136        print_dealer_hand(dealer_hand, True)  #  本来はTrue(二枚目以降を隠す)
 137  
 138        #プレイヤーターン 
 139        while True: 
 140            op = input(‘スタンド : 1, ヒット : 2 > ‘) 
 141            ending = player_op(deck, player_hand, op) 
 142            if ending: 
 143                break 
 144  
 145        #ディーラーターン 
 146        dealer_op(deck,player_hand,dealer_hand) 
 147  
 148        message,player_money = win_lose(dealer_hand,player_hand,bet,player_money) 
 149        print(message) 
 150  
 151        turn += 1 
 152        input(‘次のターンへ’) 
 153    print(‘ゲームオーバー’) 
 154  
 155if __name__ == ‘__main__’: 
 156    main() 
    

 

これをrunすると下記となり、ここまでは上手く動作しているようです。

ターン: 1
所持金: 100
ベット額 > 10
プレイヤー ( 21 ):
[ D 1 ]
[ S 10 ]

ディーラー ( 11 ):
[ H 7 ]
[ H 4 ]

スタンド : 1, ヒット : 2 > 1
[ プレイヤー:スタンド ]
21です!
[ ディーラー:ヒット ]
[ H 7 ]
[ H 4 ]
[ S 4 ]

[ ディーラー:ヒット ]
[ H 7 ]
[ H 4 ]
[ S 4 ]
[ H 2 ]

[ ディーラー:スタンド ]
<<プレイヤーの勝ち>>
次のターンへ

 

————————————————-

ブラックジャックを作るー12 これで完了。

# ダブル機能追加, 最終勝敗判定追加 
 
1import random  Tak-BJ 2-5list23.py
2  
3RANK, SUIT = 0, 1 
4  
5#勝敗判定 判定結果と計算後の持ちチップを返す。 
6def win_lose(dealer_hand, player_hand, bet ,player_money): 
7    player_point=get_point(player_hand) 
8    dealer_point=get_point(dealer_hand) 
9    if player_point <= 21: 
10        if (player_point > dealer_point) or (dealer_point > 21) : 
11            if player_point==21: 
12                return (‘<<プレイヤーの勝ち>>’,player_money + int(bet*2.5)) 
13            else: 
14                return (‘<<プレイヤーの勝ち>>’,player_money + 2*bet) 
15        elif player_point == dealer_point: 
16            return (‘<<プッシュ>>’,player_money + bet) 
17        else: 
18           return (‘<<プレイヤーの負け>>’,player_money) 
19    else: 
20        return (‘<<プレイヤーの負け>>’,player_money) 
21  
22#プレイヤーの操作 
23def player_op(deck, player_hand, op): 
24    doubled, ending = False, False 
25    if op == ‘1’: 
26        print(‘[ プレイヤー:スタンド ]’) 
27        doubled, ending = False, True 
28    elif op == ‘2’: 
29        print(‘[ プレイヤー:ヒット ]’) 
30        player_hand.append(deck.pop()) 
31        print_player_hand(player_hand) 
32        doubled, ending = False, False 
33    elif op == ‘3’: 
34        if len(player_hand) == 2: 
35            print(‘[プレイヤー:ダブル]’) 
36            player_hand.append(deck.pop()) 
37            print_player_hand(player_hand) 
38            doubled, ending = True, True 
39        else: 
40            print(‘( ダブルはできません。 )’) 
41  
42    if get_point(player_hand) > 21: #バスト判定 
43        print(‘[ プレイヤーはバストした! ]’) 
44        ending = True 
45    elif get_point(player_hand) == 21: 
46        print (’21です!’) 
47        ending = True 
48  
49    return doubled, ending 
50  
51#ディーラーの操作 
52def dealer_op(deck,player_hand,dealer_hand): 
53    while get_point(player_hand) <= 21: 
54        if get_point(dealer_hand) >= 17: 
55            print(‘[ ディーラー:スタンド ]’) 
56            break 
57        else: 
58            print(‘[ ディーラー:ヒット ]’) 
59            dealer_hand.append(deck.pop()) 
60        print_dealer_hand(dealer_hand, False) 
61  
62#手札のポイントを計算する 
63def get_point(hand): 
64    result = 0 
65    ace_flag = False 
66    for card in hand: 
67        if card[RANK] == 1: 
68            ace_flag = True 
69        if card[RANK] > 10: 
70            num = 10 
71        else: 
72            num = card[RANK] 
73        result = result + num 
74    if ace_flag and result <= 11: 
75        result += 10 
76    #print(result) 
77    return result 
78  
79#プレイヤーの手札を表示する 
80def print_player_hand(player_hand): 
81    print(‘プレイヤー (‘, get_point(player_hand), ‘):     ‘) 
82    for card in player_hand: 
83        print(‘[‘, card[SUIT], card[RANK], ‘]’) 
84    print() 
85  
86#ディーラーの手札を表示する 
87def print_dealer_hand(dealer_hand, uncovered): 
88    if uncovered : 
89        print(‘ディーラー (‘, get_point(dealer_hand), ‘):     ‘) 
90    else: 
91        print(‘ディーラー ( ?? ):     ‘) 
92    flag = True 
93    for card in dealer_hand: 
94        if flag or uncovered: 
95            print(‘[‘ , card[SUIT], card[RANK], ‘]’) 
96            flag = False 
97        else: 
98            print(‘[ * * ]’) 
99    print() 
100  
101#デッキの作成 
102def make_deck(): 
103    suits = [‘S’, ‘H’, ‘D’, ‘C’]                  #スートの定義 
104    ranks = range(1, 14)                          #ランクの定義 
105    deck = [(x,y) for x in ranks for y in suits] 
106    random.shuffle(deck)                          #シャッフルする 
107    return deck 
108  
109def main(): 
110    turn = 1 
111    player_money = 100 
112    deck = make_deck() 
113  
114    while player_money > 0: 
115  
116        #ターンの初めにターン数と所持金の情報を表示 
117        print(‘-‘*20) #区切り線を作る。’-‘を20個表示。 
118        print(‘ターン:’, turn) 
119        print(‘所持金:’, player_money) 
120        print(‘-‘*20) 
121  
122        player_hand = [] 
123        dealer_hand = [] 
124  
125        try: 
126            bet = int(input(‘ベット額 > ‘)) 
127        except: 
128            print(‘整数で入力してください’) 
129            continue 
130  
131        if bet > player_money: 
132            print(‘所持金が不足しています’) 
133            continue 
134        elif bet <= 0: 
135            print(‘ベットできる額は1以上です。’) 
136            continue 
137  
138        player_money -= bet 
139  
140        if len(deck) < 10: 
141            deck = make_deck() 
142  
143        for i in range(2): #お互いに2枚ずつ引く 
144            player_hand.append(deck.pop()) #デッキからプレイヤーの手札へ 
145            dealer_hand.append(deck.pop()) #デッキからディーラーの手札へ 
146  
147        print(‘-‘*20) # 手札の情報を表示 
148        print_player_hand(player_hand) 
149        print_dealer_hand(dealer_hand, False) 
150        print(‘-‘*20) 
151  
152        #プレイヤーターン 
153        while True: 
154            op = input(‘スタンド : 1, ヒット : 2, ダブル : 3 > ‘) 
155            doubled, ending = player_op(deck, player_hand, op) 
156            if doubled: 
157                player_money -= bet 
158                bet += bet 
159            if ending: 
160                break 
161  
162        #ディーラーターン 
163        dealer_op(deck,player_hand,dealer_hand) 
164  
165        print(‘-‘*20) # 手札の情報を表示 
166        print_player_hand(player_hand) 
167        print_dealer_hand(dealer_hand, True) #ゲーム終了時は、ディーラーの手札全て表示 
168        print(‘-‘*20) 
169  
170        message,player_money = win_lose(dealer_hand,player_hand,bet,player_money) 
171        print(message) 
172  
173        turn += 1 
174        input(‘次のターンへ’) 
175  
176    print(‘ゲームオーバー’) 
177  
178if __name__ == ‘__main__’: 
179    main() 

これで勝負してみましょう。

一回目:
プレイヤー:16
ディーラー:21  —> ディーラーの勝ち

二回目:
プレイヤー:16
ディーラー:21  —> ディーラーの勝ち

所持金がなくなりましたので、これで終了です。

ラスベガスでいつもやられてきたが、Pythonのゲームでも同じになりました。 Sigh!

 

———————————
ターン: 1
所持金: 100
——————–
ベット額 > 50
——————–
プレイヤー ( 16 ):
[ D 13 ]
[ C 6 ]

ディーラー ( ?? ):
[ H 1 ]
[ * * ]

——————–
スタンド : 1, ヒット : 2, ダブル : 3 > 1
[ プレイヤー:スタンド ]
[ ディーラー:スタンド ]
——————–
プレイヤー ( 16 ):
[ D 13 ]
[ C 6 ]

ディーラー ( 21 ):
[ H 1 ]
[ H 13 ]


<<プレイヤーの負け>>

*******************************


次のターンへ
————————————-
ターン: 2
所持金: 50
——————–
ベット額 >
整数で入力してください
——————–
ベット額 > 50
——————–
プレイヤー ( 8 ):
[ S 3 ]
[ D 5 ]

ディーラー ( ?? ):
[ H 10 ]
[ * * ]

——————–
スタンド : 1, ヒット : 2, ダブル : 3 > 2
[ プレイヤー:ヒット ]
プレイヤー ( 10 ):
[ S 3 ]
[ D 5 ]
[ H 2 ]

スタンド : 1, ヒット : 2, ダブル : 3 > 2
[ プレイヤー:ヒット ]
プレイヤー ( 14 ):
[ S 3 ]
[ D 5 ]
[ H 2 ]
[ C 4 ]

スタンド : 1, ヒット : 2, ダブル : 3 > 1
[ プレイヤー:スタンド ]
[ ディーラー:スタンド ]
——————–
プレイヤー ( 14 ):
[ S 3 ]
[ D 5 ]
[ H 2 ]
[ C 4 ]

ディーラー ( 17 ):
[ H 10 ]
[ H 7 ]


<<プレイヤーの負け>>
次のターンへ
ゲームオーバー

Python別館
listboxにスクロールバーを付ける

listboxを使用するのは簡単ですが、選択要素が増えるとスクロールボタンが必要になります。これが結 …

Python小学館
どのデータを呼び込むかをアプリ立ち上げ時に決める

どのデータを呼び込むか或いはそのデータ内のどこを使用するかなどを、アプリを動作させる前に選択できるよ …

Python別館
Python別館 目次

Pythonで作成したアプリ関連の記事は「Python別館」に、widgetやその使用方法・それを使 …