今回は年末の飲み会の余興で
よく用いられる「ビンゴゲーム」
にまつわるものを検証してみました。
解説動画はこちら
ビンゴゲームとは
知らない方は少ないと思いますが
ゲームマスターが数字を選び
手持ちの紙の数値が合えば穴を開ける
プログラム上で75個の数値から
25個を選んで、並べてあげれば
ビンゴ用紙(風の出力)の完成です。
13, 25, 50, 12, 63, 11, 73, 22, 20, 36, 32, 51, 2]
23 24 4 64 71
29 19 6 58 70
33 68 13 25 50
12 63 11 73 22
20 36 32 51 2
もっとたくさん作りたい人向けには
画像化するコードをお送りします。
こんな感じで真ん中フリーポケットの
ランダム数字がかかれた用紙が出来るので
あとはそれをプリントすれば良いですね。
お金をかけたく無い人には
丁度良いかもしれません。
2.ビンゴゲームにおける色々な数字
プログラムでは組み合わせや
順列の数を求める事ができます。
とてつも無い桁になりますね
ビンゴカードを全通りプリントするのは
辞めた方が良さそうです。
順列数は多すぎるので全通りは実験出来ません。
代わりにビンゴシミュレーターで
100万回試行してみました。
実行するのにすごく時間が掛かります。
これを描画してみましょう。
だいたい
1つづつ穴を開けていくと
穴の組み合わせが多すぎるため大変です。
ビンゴ用紙に25個穴が空いた状態から穴を塞いで
48 53130
結果として
穴が20個まではビンゴにならずに
開けられるパターンが存在します。
そんなに穴が開いた状態になった人
いるんでしょうかねえ
逆にめちゃくちゃ運が悪い方を
決めることが出来ます。
シミュレーション結果を用いれば
どれくらいでプレゼントが捌けるのか
計算しやすくなると思いますので
幹事の方は逆算してみると
捗るかも知れません。
今回はビンゴゲームについての
数値検証でした。
それでは。
よく用いられる「ビンゴゲーム」
にまつわるものを検証してみました。
解説動画はこちら
ビンゴゲームとは
知らない方は少ないと思いますが
飲み会の余興などで行われる
安易なパーティーゲームの一種です。
ルールや遊び方は
安易なパーティーゲームの一種です。
ルールや遊び方は
5行x5列のマス目に
1 - 75までの数字が書かれた紙が配られ
1 - 75までの数字が書かれた紙が配られ
ゲームマスターが数字を選び
手持ちの紙の数値が合えば穴を開ける
縦・横・斜めで5マス分の穴が空いたらクリア
というものです。
真ん中のマス目はFreeポケットになっていて
最初から開けられる物も有ります。
そんなビンゴゲームのアルアルを
色々考えてみました。
1. ビンゴ用紙を作ってみる
真ん中のマス目はFreeポケットになっていて
最初から開けられる物も有ります。
そんなビンゴゲームのアルアルを
色々考えてみました。
1. ビンゴ用紙を作ってみる
プログラム上で75個の数値から
25個を選んで、並べてあげれば
ビンゴ用紙(風の出力)の完成です。
import random numbers = [i for i in range(1,76)] # ランダムで数値を25個取得する select = random.sample(numbers,25) print(select) print() for i,n in enumerate(select): if i%5==0: print() print(n,end="\t")[23, 24, 4, 64, 71, 29, 19, 6, 58, 70, 33, 68,
13, 25, 50, 12, 63, 11, 73, 22, 20, 36, 32, 51, 2]
23 24 4 64 71
29 19 6 58 70
33 68 13 25 50
12 63 11 73 22
20 36 32 51 2
import numpy as np import pandas as pd df = pd.DataFrame(np.reshape(select,[5, 5])) print(df.to_string(index=False,header=False,col_space=8))pandasで綺麗に描画するとこんなコードです。
もっとたくさん作りたい人向けには
画像化するコードをお送りします。
import random from PIL import Image, ImageDraw, ImageFont import matplotlib.pyplot as plt font = ImageFont.truetype('Arial.ttf', 32) numbers = [i for i in range(1,76)] # 作る個数を指定する n = 2 for i in range(n): select = random.sample(numbers,25) im = Image.new('RGB', (500, 500), "silver") draw = ImageDraw.Draw(im) count = 0 for x in range(5): for y in range(5): x0,x1,y0,y1 = x*100, x*100+100, y*100, y*100+100 draw.rectangle((x0, y0, x1, y1), fill="white", outline="black", width=4) if count!=12: draw.text((x0+32, y0+32), "{0:02}".format(select[count]), (0, 0, 0), font=font, align='center') else: draw.text((x0+32, y0+32), "●", (0, 0, 0), font=font, align='center') count+=1 plt.imshow(im) plt.axis("off") plt.show()
こんな感じで真ん中フリーポケットの
ランダム数字がかかれた用紙が出来るので
あとはそれをプリントすれば良いですね。
お金をかけたく無い人には
丁度良いかもしれません。
2.ビンゴゲームにおける色々な数字
2-1.25マスの数値の並びの組み合わせ
75 個の数字から
25 個取り出して並べる順列の総数は
こんな感じの数式で表せます。
25 個取り出して並べる順列の総数は
こんな感じの数式で表せます。
プログラムでは組み合わせや
順列の数を求める事ができます。
import math n = 75 k = 25 # p = n! / (n - k)! p = math.perm(n, k) print(p) print("{:,}".format(p))
815712000579973729423615859451974909952000000
815,712,000,579,973,729,423,615,859,451,974,909,952,000,000
とてつも無い桁になりますね
ビンゴカードを全通りプリントするのは
辞めた方が良さそうです。
2-2.何回くらいでビンゴになるのか
順列数は多すぎるので全通りは実験出来ません。
代わりにビンゴシミュレーターで
100万回試行してみました。
# ビンゴの場合True , ビンゴでない場合はFalse def check_bingo(b): # 横 for i in range(5): if sum(b[i*5:i*5+5])==0: return True # 縦 for i in range(5): b1,b2,b3,b4,b5 = b[i],b[i+5],b[i+10],b[i+15],b[i+20] if sum([b1,b2,b3,b4,b5])==0: return True # 斜め d1 = [b[d*6] for d in range(5)] d2 = [b[d*4] for d in range(1,6)] if sum(d1)==0 or sum(d2)==0: return True return False # リストの中に数値がある場合はインデックスを、ない場合は-1を返す def find_index(b,x): return b.index(x) if x in b else -1 # 何ターンでビンゴしたかをカウントする def bingo_count(bingo,numbers): count=0 for num in numbers: index = find_index(bingo,num) if index!=-1: bingo[index] = 0 count+=1 if check_bingo(bingo): return count else: continue return count
import random numbers = [i for i in range(1,76)] random.shuffle(numbers) n = 1000000 calc = {k:0 for k in range(1,76)} for i in range(n): # ランダムで数値を25個取得してビンゴ用紙を作る bingo = random.sample(numbers,25) # 真ん中は開ける(数値0は穴開き) bingo[12] = 0 ans = bingo_count(bingo,numbers) calc[ans]+=1 # 結果 print("総回数 : {0}回".format(n)) tmp = [] for k,v in calc.items(): r = v / n * 100 print("{0:02} 回目, : {1:06}回 , {2:.05}%".format(k,v,r)) tmp.append([k,v,r])
実行するのにすごく時間が掛かります。
これを描画してみましょう。
# 描画 import matplotlib.pyplot as plt import pandas as pd df_b = pd.DataFrame(tmp,columns=["num","count","rate"]) df_b["cumsum"] = df_b["rate"].cumsum() fig, ax1 = plt.subplots(figsize=(16,8)) ax2 = ax1.twinx() ax1.bar(df_b["num"],df_b["rate"]) ax2.plot(df_b["cumsum"],color="red") plt.show()
16回くらいやれば、10%くらいの人がビンゴ
41回くらいやれば、半分くらいの人がビンゴ
49回くらいやれば、80%くらいの人がビンゴ
になるようです。
になるようです。
2-3.ビンゴにならずに開けられる数の最大数
1つづつ穴を開けていくと
穴の組み合わせが多すぎるため大変です。
ビンゴ用紙に25個穴が空いた状態から穴を塞いで
ビンゴにならないかどうかを判定して
測定する形にしました。
・・・・測定する形にしました。
# 結果のプリント用 def print_bingo(bingo): for i,b in enumerate(bingo): if i%5==0: print() print(b,end="\t") print() # ビンゴでない場合True , ビンゴの場合はFalse def check_bingo(b): # 横 for i in range(5): if sum(b[i*5:i*5+5])==5: return False # 縦 for i in range(5): b1,b2,b3,b4,b5 = b[i],b[i+5],b[i+10],b[i+15],b[i+20] if sum([b1,b2,b3,b4,b5])==5: return False # 斜め d1 = [b[d*6] for d in range(5)] d2 = [b[d*4] for d in range(1,6)] if sum(d1)==5 or sum(d2)==5: return False return True
count = 0 all_count = 0 seq = [i for i in range(0,25)] combi = list(itertools.combinations(seq,5)) for c in combi: all_count +=1 # ビンゴを用意(1==穴あき) bingo = [1] * 25 # 穴なしに戻す(0==穴なし) for i in c: bingo[i]=0 # ビンゴでないかどうかの判定 if check_bingo(bingo): print(c) print_bingo(bingo) print() count +=1 print(count,all_count)
(0, 6, 12, 18, 24)
0 1 1 1 1
1 0 1 1 1
1 1 0 1 1
1 1 1 0 1
1 1 1 1 0
48 53130
結果として
穴が20個まではビンゴにならずに
開けられるパターンが存在します。
そんなに穴が開いた状態になった人
いるんでしょうかねえ
逆にめちゃくちゃ運が悪い方を
決めることが出来ます。
シミュレーション結果を用いれば
どれくらいでプレゼントが捌けるのか
計算しやすくなると思いますので
幹事の方は逆算してみると
捗るかも知れません。
今回はビンゴゲームについての
数値検証でした。
それでは。