配布したカードの中からペアのカードを除外しよう
前回は53枚のカードを3人に配布するプログラムを作成しました。
今回は配布したカードの中から同じ数字のカードが2枚あったら除外するプログラムを作ります。
なお、同じ数字のカードが3枚あった場合は、2枚だけを除外して1枚は残すこととします。
ペアの存在を確認する処理
ペアの存在を確認する処理は、大きく3つのループからなっていて、下図のような構造になっています。
変数kを使ったループでペアが見つかった場合、ただちにそのループを抜けて、変数jを使ったループに戻ります。
配布したカードの中からペアのカードを除外するプログラム
配布したカードの中からペアのカードを除外するプログラムは、以下のようになります。
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 |
### インポート import numpy as np ### 定数 PLAYER = ['山田','鈴木','佐藤'] # プレイヤー名 MEMBER = len(PLAYER) # 人数 ### 初期カード配列 CARD = ['CA','C2','C3','C4','C5','C6','C7','C8','C9','CT','CJ','CQ','CK', 'DA','D2','D3','D4','D5','D6','D7','D8','D9','DT','DJ','DQ','DK', 'HA','H2','H3','H4','H5','H6','H7','H8','H9','HT','HJ','HQ','HK', 'SA','S2','S3','S4','S5','S6','S7','S8','S9','ST','SJ','SQ','SK', 'JK'] ### 元の配列を退避 tmp_card = CARD ### カードの総数を人数で割る number = int(len(CARD)/MEMBER) ### カードをランダムで取得 cards = np.random.choice(CARD, [MEMBER,number], False).tolist() ### 二次元配列をフラットにしてループ for x in np.ravel(cards): ### 取得したカードを配列から除外 tmp_card = [tmp for tmp in tmp_card if tmp != x] ### 残ったカードを追加 for i,card in enumerate(tmp_card): cards[i].append(card) ### カードの内容を画面表示 print('### 配布したカード') for i,name in enumerate(PLAYER): print(name, cards[i]) ### 配布した人数分ループ for i in range(len(cards)): ### 削除確認用配列初期化 arr_del = [0 for pos in range(len(cards[i]))] ### ジョーカーの場合2を設定 for pos in range(len(cards[i])): if cards[i][pos] == 'JK': arr_del[pos] = 2 ### 配列の先頭から比較 for j in range(len(cards[i])): ### 除外済みまたはジョーカーの場合処理を飛ばす if arr_del[j] != 0: continue ### ペアの存在を確認 for k in range(j+1, len(cards[i])): ### 除外済みまたはジョーカーの場合処理を飛ばす if arr_del[k] != 0: continue ### 同じ数字の場合 if cards[i][j][1] == cards[i][k][1]: ### 削除確認用配列に1を設定 arr_del[j] = arr_del[k] = 1 ### 一番内側のループを抜ける break ### 一時配列作成 arr_tmp = [tmp for tmp in cards[i]] ### ペアを配列から削除 for j in range(len(arr_del)): if arr_del[j] == 1: cards[i].remove(arr_tmp[j]) ### カードの内容を画面表示 print('\n### ペアのカードを除外') for i,name in enumerate(PLAYER): print(name, cards[i]) |
40行目
人数分ループします。
今回は3人に配布するので、3回ループします。
43行目
ペアを配布されたカードから除外するため、その位置を保存する配列をarr_delとして作成します。
要素の初期値は0にします。
46~48行目
カードがジョーカー(JK)の場合は、配列arr_delの該当する位置に2を設定します。
51行目
基準位置を変数jとして、配列の先頭から開始します。
54、55行目
配列arr_delを参照して、変数jの位置の値が0以外(除外済みorジョーカー)の場合は、処理を飛ばします。
58行目
比較対象の位置を変数kとして、変数jの次の位置から順番に比較していきます。
61、62行目
配列arr_delを参照して、変数kの位置の値が0以外(除外済みorジョーカー)の場合は、処理を飛ばします。
65~71行目
変数jと変数kの位置の数字が同じだった場合は、配列arr_delの変数jと変数kの位置に1を設定してループを終了します。
74行目
処理をしている配列の要素を配列arr_tmpにコピーします。
77~79行目
配列arr_delが1になっている位置の要素を、元の配列(cards)からremove()メソッドを使って削除します。
削除対象は要素の値を指定しています。
プログラムを実行すると、以下のように数字が同じペアのカードが除外されます。
実行例
C:\>python card6-1.py
### 配布したカード
山田 ['SK', 'C8', 'C2', 'DT', 'S3', 'CT', 'H2', 'HJ', 'ST', 'D4', 'JK', 'D2', 'D7', 'S5', 'SA', 'H4', 'DQ', 'HT']
鈴木 ['H5', 'CA', 'C4', 'H9', 'CJ', 'H6', 'DA', 'C6', 'CK', 'D5', 'S4', 'S2', 'HK', 'H8', 'C9', 'CQ', 'S8', 'S7']
佐藤 ['SQ', 'C7', 'D9', 'C3', 'H3', 'H7', 'SJ', 'DK', 'D8', 'S6', 'HA', 'C5', 'D3', 'HQ', 'DJ', 'D6', 'S9']
### ペアのカードを除外
山田 ['SK', 'C8', 'S3', 'HJ', 'JK', 'D2', 'D7', 'S5', 'SA', 'DQ']
鈴木 ['CJ', 'S2', 'CQ', 'S7']
佐藤 ['DK', 'D8', 'HA', 'C5', 'D3']