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

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

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

 

   プログラムのcode 説明、コメント               Tak-2-3-list3
 1import random#乱数発生用ライブラリー
 2 #SUITはトランプの種類(♠、♥など)
 3RANK, SUIT = 0, 1#RANKはトランプの数。 行7でcard[0]と書くより分かり易い
 4def 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  
 19def 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  
 26def 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
 1import random#乱数発生用ライブラリー
 2 #SUITはトランプの種類(♠、♥など)
 3RANK, SUIT = 0, 1#RANKはトランプの数。 行8のcard[0]より分かり易い
 4def 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  
 19def 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関数 
*27def 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  
 33def 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
 1import random#乱数発生用ライブラリー
 2 #SUITはトランプの種類(♠、♥など)
 3RANK, SUIT = 0, 1#RANKはトランプの数。 行7でcard[0]と書くより分かり易い
 4def 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  
 19def 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関数 
 27def 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関数 
*34def 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  
 48def 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を超えた時点で勝負は負け決定を追加

 1import random
  説明、コメント   Tak-BJ 2-5list9.py
 2  
 3RANK, SUIT = 0, 1 
 4  
 5  
 6def player_op(deck, player_hand, op):playerの行動の処理
 7    ending = Falseendingは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 = Trueplayerの行動は終わり(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  
 27def 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  
 45def 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関数 
 52def 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  
 67def 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  
 75def 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  
 108if __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を超すこともあり得ますので、プレーヤーはそこをどう判断するかがブラックジャックの面白いところです。
 
 
1import random説明、コメント   Tak-BJ 2-5list11.py
2  
3RANK, SUIT = 0, 1 
4  
5def 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  
25def 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関数 
41def 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関数 
48def 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  
62def 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  
69def 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  
116if __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別館
英語学習アプリ ①

別項の「今日の脳トレ」で間違えたものや調べたものなどをこのアプリで学習しております。自分には随分と難 …

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

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