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

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

もっとレベルが上がったらchallengeしてみたいと思います。
 
**********************************************
 
 
ブラックジャックを作るー11
 
このcodeで次の処理を追加しました。
・playerがBJの場合は1.5倍の支払を受ける OK
・dealerの得点計算はOK
・ 勝敗判定も追加した
 
  1 import random  Tak-2-5-list23.py
  2    
  3 RANK, SUIT = 0, 1  
  4    
  5 def 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    
  21 def 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    
  41 def 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    
  51 def 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関数  
  67 def 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関数  
  74 def 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    
  88 def 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    
  95 def 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    
  155 if __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 これで完了。

# ダブル機能追加, 最終勝敗判定追加 
 
1 import random   Tak-BJ 2-5list23.py
2    
3 RANK, SUIT = 0, 1  
4    
5 #勝敗判定 判定結果と計算後の持ちチップを返す。  
6 def 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 #プレイヤーの操作  
23 def 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 #ディーラーの操作  
52 def 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 #手札のポイントを計算する  
63 def 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 #プレイヤーの手札を表示する  
80 def 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 #ディーラーの手札を表示する  
87 def 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 #デッキの作成  
102 def 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    
109 def 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    
178 if __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小学館
クラスへの移行練習-① ②

先人のプログラムを利用させて頂くには、やはりクラス(特に継承機能)を理解する必要が有ります。 そこで …

Python別館
Python別館 目次

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

Python小学館
csvファイルの呼び込み その二

textファイルでもcsvファイルでも読めるように、読込機能だけのcodeをアップしておきます。 # …