ブラックジャックを作る 6~10

ブラックジャックを作る-6

前回まででPlayerとdealerの最初に配布されたカードの合計が表示されました。 ただ、絵札の得点をゲーム用に修正が必要です。
ここでAは1か11、その他の絵札は全て10と計算するようにします。

 

     プログラムのcode  説明、コメント               Tak-2-3-list3
  1 import random #乱数発生用ライブラリー
  2   #SUITはトランプの種類(♠、♥など)
  3 RANK, SUIT = 0, 1 #RANKはトランプの数。 行7でcard[0]と書くより分かり易い
  4 def get_point(hand):  
  5     result = 0  #得点の初期値を零に初期化
* 6     ace_flag = False   
* 7     for card in hand: # 手にあるカード(card)のpoint全部numに格納
* 8         if card[RANK] ==1:  
* 9             ace_flag = True  
* 10         if card[RANK] > 10:  
* 11             num = 10  
* 12         else:  
* 13             num = card[RANK]  
* 14         result = result + num #カードの合計点数をresultに格納する
* 15     if ace_flag and result <= 11:  
* 16         result +=10  
  17     return result  
  18    
  19 def make_deck(): #カードを52枚作る関数
  20     suits = ['S', 'H', 'D', 'C'] #suitsは♠、♥、♦、♠、♧の4種類
  21     ranks = range(1, 14) #ranksはA~10、J、Q、Kの13個
  22     deck = [(x, y) for x in ranks for y in suits] #別項参照
  23     random.shuffle(deck) #作ったカードをシャッフルする(混ぜ合わせる)
  24     return deck #このdeckを後々他の関数で使用する
  25    
  26 def main(): #主な処理機能をmain()と云う関数に纏える
  27     turn = 1 #turnとはゲームの回数
  28     player_money = 100 #プレーヤの持ち金を100とする
  29     deck = make_deck() #3行目のmake_deck()を駆動する。
  30     print(deck) #そのdeck() 52枚を表示する
  31     while (player_money > 0): #持ち金がなくなったら、ゲームは完了する
  32         print('turn : ', turn) #何回目のゲームかを表示する
  33         print('players money is : ', player_money) #プレーヤの所持金を表示する
  34    
  35         player_hand = [] # プレイヤーの持ち札を格納するリスト
  36         dealer_hand = [] # ディーラーの持ち札を格納するリスト
  37         deck = make_deck() # ゲームに使うカードの山を作成
  38    
  39         for i in range(2): # カードをplayerとdealerに2回配布する
  40              player_hand.append(deck.pop())  
  41             dealer_hand.append(deck.pop())  
  42    
  43         print(player_hand) # playerの手札
* 44         print(get_point(player_hand)) # 上のplayer_handをget_hand()で合計を得る
  45         
  46         print(dealer_hand)  
* 47         print(get_point(dealer_hand))  
  48    
  49         turn += 1  
  50         input('next turn?') #ゲーム2へ行きますか?と確認している
  51     print('Game Over ! ') #プレーヤの所持金が切れたら、ゲームオーバー
  52    
  53  if __name__ == '__main__':  
  54    main()  

これをrunすると以下のように、エースは1点、その他の絵札は10点として合計得点が計算されております。

次回では、エースを1点とするか11点とするかを検討します。

ターン: 1
所持金: 100
[(6, 'D'), (12, 'S')]
16
[(1, 'D'), (1, 'H')]
12
次のターンへ

--------------------------------------------------------------------

ブラックジャックを作る-7

# タプルで表示されているプレーヤーカードを♥11などと表示する(GUIでカードを表示する時にも必要)
## タプルで表示されているディーラーカードはまだタプル表示のまま([(9, 'C'), (12, 'C')])

 

     プログラムのcode  説明、コメント              Tak-4-2-list1
  1 import random #乱数発生用ライブラリー
  2   #SUITはトランプの種類(♠、♥など)
  3 RANK, SUIT = 0, 1 #RANKはトランプの数。 行8のcard[0]より分かり易い
  4 def get_point(hand):  
  5     result = 0  #得点の初期値を零に初期化
  6     ace_flag = False   
  7     for card in hand: # 手にあるカード(card)のpoint全部numに格納
  8         if card[RANK] ==1:  
  9             ace_flag = True  
  10         if card[RANK] > 10:  
  11             num = 10  
  12         else:  
  13             num = card[RANK]  
  14         result = result + num #カードの合計点数をresultに格納する
  15     if ace_flag and result <= 11:  
  16         result +=10  
  17     return result  
  18    
  19 def make_deck(): #カードを52枚作る関数
  20     suits = ['S', 'H', 'D', 'C'] #suitsは♠、♥、♦、♠、♧の4種類
  21     ranks = range(1, 14) #ranksはA~10、J、Q、Kの13個
  22     deck = [(x, y) for x in ranks for y in suits] #別項参照
  23     random.shuffle(deck) #作ったカードをシャッフルする(混ぜ合わせる)
  24     return deck #このdeckを後々他の関数で使用する
  25    
* 26 #print_player_hand関数  
* 27 def print_player_hand(player_hand):  
* 28     print('player (', get_point(player_hand), ')    ')  
* 29     for card in player_hand:  
* 30         print('[', card[SUIT], card[RANK], ']')  
* 31     print()  
  32    
  33 def main(): #主な処理機能をmain()と云う関数に纏える
  34     turn = 1 #turnとはゲームの回数
  35     player_money = 100 #プレーヤの持ち金を100とする
  36     deck = make_deck() #3行目のmake_deck()を駆動する。
  37     print(deck) #そのdeck() 52枚を表示する
  38     while (player_money > 0): #持ち金がなくなったら、ゲームは完了する
  39         print('turn : ', turn) #何回目のゲームかを表示する
  40         print('players money is : ', player_money) #プレーヤの所持金を表示する
  41    
  42         player_hand = [] # プレイヤーの持ち札を格納するリスト
  43         dealer_hand = [] # ディーラーの持ち札を格納するリスト
  44         deck = make_deck() # ゲームに使うカードの山を作成
  45    
  46         for i in range(2): # カードをplayerとdealerに2回配布する
  47              player_hand.append(deck.pop())  
  48             dealer_hand.append(deck.pop())  
  49    
  50         print(player_hand) # playerの手札
  51         print(get_point(player_hand)) # ここで上のplayer_handをget_hand()に持っていき合計を得る  ** ここが一番わかり難いところです
  52         
  53         print(dealer_hand)  
  54         print(get_point(dealer_hand))  
  55    
  56         turn += 1  
  57         input('next turn?') #ゲーム2へ行きますか?と確認している
  58     print('Game Over ! ') #プレーヤの所持金が切れたら、ゲームオーバーと表示する
  59    
  60  if __name__ == '__main__': #main()と云う関数が直接実行された場合のみ実行できる。
  61    main()  

 

これをrunすると次の表示がでる。

player ( 18 )
[ C 13 ]
[ D 8 ]

18
[(6, 'H'), (3, 'H')]
9
次のターンへ

 

--------------------------------------------------------------------

ブラックジャックを作る-8

 

次はルールに従い、ディーラーの二枚目を隠します。

     プログラムのcode  説明、コメント              Tak-4-2-list2
  1 import random #乱数発生用ライブラリー
  2   #SUITはトランプの種類(♠、♥など)
  3 RANK, SUIT = 0, 1 #RANKはトランプの数。 行7でcard[0]と書くより分かり易い
  4 def get_point(hand):  
  5     result = 0  #得点の初期値を零に初期化
  6     ace_flag = False   
  7     for card in hand: # 手にあるカード(card)のpoint全部numに格納
  8         if card[RANK] ==1:  
  9             ace_flag = True  
  10         if card[RANK] > 10:  
  11             num = 10  
  12         else:  
  13             num = card[RANK]  
  14         result = result + num #カードの合計点数をresultに格納する
  15     if ace_flag and result <= 11:  
  16         result +=10  
  17     return result  
  18    
  19 def make_deck(): #カードを52枚作る関数
  20     suits = ['S', 'H', 'D', 'C'] #suitsは♠、♥、♦、♠、♧の4種類
  21     ranks = range(1, 14) #ranksはA~10、J、Q、Kの13個
  22     deck = [(x, y) for x in ranks for y in suits] #別項参照
  23     random.shuffle(deck) #作ったカードをシャッフルする(混ぜ合わせる)
  24     return deck #このdeckを後々他の関数で使用する
  25    
  26 #print_player_hand関数  
  27 def print_player_hand(player_hand):  
  28     print('player (', get_point(player_hand), ')    ')  
  29     for card in player_hand:  
  30         print('[', card[SUIT], card[RANK], ']')  
  31     print()  
  32    
* 33 #print_dealer_hand関数  
* 34 def print_dealer_hand(dealer_hand, uncovered):  
* 35     if uncovered:  
* 36         print('dealer (', get_point(dealer_hand), '):    ')  
* 37     else:  
* 38         print(' dealer (??):    ')  
* 39     flag = True  
* 40     for card in dealer_hand:  
* 41         if falg or uncovered:  
* 42             print('[', card[SUIT], card[RANK], ']')  
* 43             flag = False  
* 44         else:  
* 45             print('[**]')  
* 46     print() #見やすくするため一行空ける
  47    
  48 def main(): #主な処理機能をmain()と云う関数に纏える
  49     turn = 1 #turnとはゲームの回数
  50     player_money = 100 #プレーヤの持ち金を100とする
  51     deck = make_deck() #3行目のmake_deck()を駆動する。出来たdeckを持ち帰る
  52     print(deck) #そのdeck() 52枚を表示する
  53     while (player_money > 0): #持ち金がなくなったら、ゲームは完了する
  54         print('turn : ', turn) #何回目のゲームかを表示する
  55         print('players money is : ', player_money) #プレーヤの所持金を表示する
  56    
  57         player_hand = [] # プレイヤーの持ち札を格納するリスト
  58         dealer_hand = [] # ディーラーの持ち札を格納するリスト
  59         deck = make_deck() # ゲームに使うカードの山を作成
  60    
  61         for i in range(2): # カードをplayerとdealerに2回配布する
  62              player_hand.append(deck.pop())  
  63             dealer_hand.append(deck.pop())  
  64    
  65         print_player_hand(player_hand) # playerの手札
  66    
  67    
  67         print(dealer_hand)  
  68         print(get_point(dealer_hand, False)) # dealerの二枚目のカードを伏せたままにする
  69    
  70         turn += 1  
  71         input('next turn?') #ゲーム2へ行きますか?と確認している
  72     print('Game Over ! ') #プレーヤの所持金が切れたら、ゲームオーバーと表示する
  73    
  74  if __name__ == '__main__': #main()と云う関数が直接実行された場合のみ実行できる。
  75    main()  

これをrunすると、dealerの二枚目は**と表示されて、playerには分からないようになっている。

"""
player ( 13 )
[ D 3 ]
[ S 12 ]

dealer (??):
[ D 5 ]
[ * * ]

--------------------------------------------------------------------------------

次回はplayerがcardを要求するか(Hit)、ここで勝負するか(Stand)を決めます。

ブラックジャックを作る-9

・プレイヤーの次の処理(待つかもう一枚引くか)を追加
・プレイヤーの合計が21を超えた時点で勝負は負け決定を追加

  1 import random
  説明、コメント   Tak-BJ 2-5list9.py
  2    
  3 RANK, SUIT = 0, 1  
  4    
  5    
  6 def player_op(deck, player_hand, op): playerの行動の処理
  7     ending = False endingはplayerカードの変数。
  8     if op == '1': '1' : カードを引かない(Stand)
  9         print('[ プレイヤー:スタンド ]')  
  10         ending = True 変数をTrueにする
  11     elif op == '2': '2' : カードを引く(Hit)
  12         print('[ プレイヤー:ヒット ]')  
  13         player_hand.append(deck.pop())  
  14         print_player_hand(player_hand)  
  15         ending = False  
  16    
  17     if get_point(player_hand) > 21:  # バスト判定 playerのカード合計が21を越した場合
  18         print('[ プレイヤーはバストした! ]')  
  19         ending = True playerの行動は終わり(ending=True)
  20     elif get_point(player_hand) == 21: playerがBlackJackの時
  21         print('21です!')  
  22         ending = True  playerの行動は終わり(ending=True)
  23    
  24     return ending  
  25    
  26    
  27 def get_point(hand): カードがAの時の処理
  28     result = 0  
  29     ace_flag = False  
  30     for card in hand:  
  31         if card[RANK] == 1:  # カードがAか? # カードがAか?
  32             ace_flag = True  
  33         if card[RANK] > 10:  
  34             num = 10  
  35         else:  
  36             num = card[RANK]  
  37         result = result + num  
  38     if ace_flag and result <= 11:  # Aが含まれていて、合計が11以下か?
  39         result += 10  # Aを11と考え、resultに10を加える  
  40     return result  
  41    
  42 # print_player_hand関数  
  43    
  44    
  45 def print_player_hand(player_hand):  
  46     print('プレイヤー (', get_point(player_hand), '):     ')  
  47     for card in player_hand:  
  48         print('[', card[SUIT], card[RANK], ']')  
  49     print()  
  50    
  51 # print_dealer_hand関数  
  52 def print_dealer_hand(dealer_hand, uncovered):  
  53     if uncovered:  
  54         print('ディーラー (', get_point(dealer_hand), '):     ')  
  55     else:  
  56         print('ディーラー ( ?? ):     ')  
  57     flag = True  
  58     for card in dealer_hand:  
  59         if flag or uncovered:  
  60             print('[', card[SUIT], card[RANK], ']')  
  61             flag = True #本番ではカード2を隠す(False)
  62         else:  
  63             print('[ * * ]')  
  64     print()  
  65    
  66    
  67 def make_deck():  
  68     suits = ['S', 'H', 'D', 'C']     # スート(記号)の定義  
  69     ranks = range(1, 14)             # ランク(数字)の定義  
  70     deck = [(x, y) for x in ranks for y in suits] # xとyを入れ替えると、♥KがK♥などと変わる
  71     random.shuffle(deck)              # シャッフルする
  72     return deck  
  73    
  74    
  75 def main():  
  76     turn = 1  
  77     player_money = 100  
  78     while player_money > 0:  
  79         print('ターン:', turn)  
  80         print('所持金:', player_money)  
  81    
  82         player_hand = []   
  83         dealer_hand = []    
  84         deck = make_deck()  
  85         bet = 10  
  86         player_money -= bet  
  87    
  88         for i in range(2):  # お互いに2枚ずつ引く  
  89             player_hand.append(deck.pop())    
  90             dealer_hand.append(deck.pop())    
  91    
  92         #print(player_hand)  
  93         print_player_hand(player_hand)  
  94    
  95         #print(dealer_hand)  
  96         print_dealer_hand(dealer_hand, False)   # 作成中なのでFalseにしておく
  97    
  98         #プレイヤーターン  
  99         while True:  
  100             op = input('スタンド : 1, ヒット : 2 > ') カードを引かないなら1、引くなら2
  101             ending = player_op(deck, player_hand, op)  
  102    
  103         turn += 1  
  104         input('次のターンへ')  
  105     print('ゲームオーバー')  
  106    
  107    
  108 if __name__ == '__main__':  
  109     main()  

 

これをrunしたときの一例
・ディーラーの得点は??となっているが、ここでは二枚目も表示している
・プレーヤーがカードを引かないときは1を、引くときは2をenterする

"""
ターン: 1
所持金: 100
プレイヤー ( 12 ):
[ S 9 ]
[ H 3 ]

ディーラー ( ?? ):
[ D 9 ]
[ H 5 ]

スタンド : 1, ヒット : 2 > 1
[ プレイヤー:スタンド ]
スタンド : 1, ヒット : 2 > 2
[ プレイヤー:ヒット ]
プレイヤー ( 16 ):
[ S 9 ]
[ H 3 ]
[ C 4 ]

スタンド : 1, ヒット : 2 >
 
------------------------------------------------------------------
 
ブラックジャックを作る-10
 
今回はプレーヤーがカードを引かないとした後の、ディーラーのカードの動きをのcodeを作ります。
ディーラーは合計が17以上になるまで自動的にカードが配られます。
 
当然21を超すこともあり得ますので、プレーヤーはそこをどう判断するかがブラックジャックの面白いところです。
 
 
1 import random 説明、コメント   Tak-BJ 2-5list11.py
2    
3 RANK, SUIT = 0, 1  
4    
5 def player_op(deck, player_hand, op):  
6     ending = False  
7     if op == '1':  
8         print('[ プレイヤー:スタンド ]')  
9         ending = True  
10     elif op == '2':  
11         print('[ プレイヤー:ヒット ]')  
12         player_hand.append(deck.pop())  
13         print_player_hand(player_hand)  
14         ending = False  
15    
16     if get_point(player_hand) > 21: #バスト判定  
17         print('[ プレイヤーはバストした! ]')  
18         ending = True  
19     elif get_point(player_hand) == 21:  
20         print ('21です!')  
21         ending = True  
22    
23     return ending  
24    
25 def get_point(hand):  
26     result = 0  
27     ace_flag = False  
28     for card in hand:  
29         if card[RANK] == 1:  
30             ace_flag = True  
31         if card[RANK] > 10:  
32             num = 10  
33         else:  
34             num = card[RANK]  
35         result = result + num  
36     if ace_flag and result <= 11:  
37         result += 10  
38     return result  
39    
40 # print_player_hand関数  
41 def print_player_hand(player_hand):  
42     print('プレイヤー (', get_point(player_hand), '):     ')  
43     for card in player_hand:  
44         print('[', card[SUIT], card[RANK], ']')  
45     print()  
46    
47 # print_dealer_hand関数  
48 def print_dealer_hand(dealer_hand, uncovered):  
49     if uncovered :  
50         print('ディーラー (', get_point(dealer_hand), '):     ')  
51     else:  
52         print('ディーラー ( ?? ):     ')  
53     flag = True  
54     for card in dealer_hand:  
55         if flag or uncovered:  
56             print('[' , card[SUIT], card[RANK], ']')  
57             flag = True  
58         else:  
59             print('[ * * ]')  
60     print()  
61    
62 def make_deck():  
63     suits = ['S', 'H', 'D', 'C']     # スート(記号)の定義  
64     ranks = range(1, 14)             # ランク(数字)の定義  
65     deck = [(x,y) for x in ranks for y in suits]  
66     random.shuffle(deck)             # シャッフルする  
67     return deck  
68    
69 def main():  
70     turn = 1  
71     player_money = 100  
72     while player_money > 0:  
73         print('ターン:', turn)  
74         print('所持金:', player_money)  
75    
76         player_hand = [] # プレイヤーの手札を格納するリスト  
77         dealer_hand = [] # ディーラーの手札を格納するリスト  
78         deck = make_deck()  
79         bet = 10  
80         player_money -= bet  
81    
82         for i in range(2): # お互いに2枚ずつ引く  
83             player_hand.append(deck.pop()) # デッキからプレイヤーの手札へ  
84             dealer_hand.append(deck.pop()) # デッキからディーラーの手札へ  
85    
86         #print(player_hand)  
87         print_player_hand(player_hand)  
88    
89         #get_point(dealer_hand)  
90         print_dealer_hand(dealer_hand, True) # 本来はFalseだが、ここではTrueにしておく  
91    
92         #プレイヤーターン  
93         while True:  
94             op = input('スタンド : 1, ヒット : 2, ---> ')  
95             ending = player_op(deck, player_hand, op)  
96             if ending:  
97                 break  
98    
99         #ディーラーターン  
100         while get_point(player_hand) <= 21 :  
101             if get_point(dealer_hand) >= 17 :  
102                 print('[ ディーラー:スタンド ]')  
103                 break  
104             else:  
105                 print('[ ディーラー:ヒット ]')  
106                 dealer_hand.append(deck.pop())  
107             print_dealer_hand(dealer_hand, False)  
108         print("-------------------------")  
109    
110         turn += 1  
111    
112         input('次のターンへ')  
113    
114     print('ゲームオーバー')  
115    
116 if __name__ == '__main__':  
117     main()  

 

runすると次のようになりました(一例)。

プレーヤーは最初の二枚の合計が8でしたので、更に一枚引いて18でstopしました。
その後、ディーラーは既に18でしたので、そこで一回目の勝負は終わりです。
プレーヤー 18、ディーラー 20 ---> ディラーの勝ちですがまだ勝負のプログラムは出来ていません。
続きます。

ターン: 1
所持金: 100
プレイヤー ( 8 ):
[ C 6 ]
[ C 2 ]

ディーラー ( 20 ):
[ D 1 ]
[ D 9 ]

スタンド : 1, ヒット : 2, ---> 2
[ プレイヤー:ヒット ]
プレイヤー ( 18 ):
[ C 6 ]
[ C 2 ]
[ C 12 ]

スタンド : 1, ヒット : 2, ---> 1
[ プレイヤー:スタンド ]
[ ディーラー:スタンド ]
-------------------------
次のターンへ

 

稿を変えて続きます。

 

1-10までは終了、完了ではありません。

 

 

 

Python別館
Python別館 目次

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

Python別館
Q&A テンプレート GUI編

良く英単語アプリなどを作る時に似たようなアプリになりますので、すぐ真似できるようにテンプレートらしき …

Python別館
文字列の配置

ラベル、テキストボックスなどで、文字列の配置が微妙に異なります。 いつも迷うので基本的なものを挙げて …