2025.08.01(更新日: 2025.08.01)
穴を開ける
はじめに
前回、Python製のビンゴゲームについて解説した。
現状、番号を引いてもカードに穴が開かない。

カードに穴を空けるには
処理の流れを追う。
1. ゲームスタートから以下の画面が表示されるまで

1-1. play_bingo関数が発火
# ゲームを開始
play_bingo()
1-2. BingoCardクラスのインスタンス生成
def play_bingo():
card = BingoCard()
1-3. カードとマークの初期化
import random
class BingoCard:
def __init__(self):
self.card = self.generate_card()
self.marked = [[False] * 5 for _ in range(5)] # 数字のマーク状態を保持
def generate_card(self):
# 各列 (B, I, N, G, O) ごとに範囲内のランダムな数字を選ぶ
card = []
ranges = [(1, 15), (16, 30), (31, 45), (46, 60), (61, 75)]
for start, end in ranges:
column = random.sample(range(start, end + 1), 5)
card.append(column)
card[2][2] = "FREE" # 中央のフリー枠
return card
1-4. カードを表示
def play_bingo():
card.display_card()
class BingoCard:
def display_card(self):
print("\nB I N G O")
for i in range(5):
for j in range(5):
value = self.card[j][i] # 列ごとに表示
if isinstance(value, int):
print(f"{value:2d}", end=" ")
else:
print(f"{value:>2}", end=" ")
print()
1-5. すでに引いたカードの集合を作成
def play_bingo():
drawn_numbers = set()
1-6. 無限ループ突入→番号を引かせる
while True:
input("Enterで次の番号を引きます...")
2. ユーザが番号を引く → その番号が表示される

2-1. 数字をランダム生成
import random
def play_bingo():
while True:
number = random.randint(1, 75)
2-2. 重複防止処理
while number in drawn_numbers: # 重複しないようにする
number = random.randint(1, 75)
2-3. 集合に追加
def play_bingo():
drawn_numbers = set()
while True:
drawn_numbers.add(number)
2-4. 引かれた番号を出力
print(f"引かれた番号: {number}")
3. マークに穴を開ける処理

3-1. mark_number関数の発火
card.mark_number(number)
3-2. 二重for文で引いた数字があるかカードのすべての番号を確認
def mark_number(self, number):
for i in range(5):
for j in range(5):
if self.card[i][j] == number:
self.marked[i][j] = True
3-3. 一致していれば、markedの該当箇所をTrueにする
def mark_number(self, number):
for i in range(5):
for j in range(5):
if self.card[i][j] == number:
self.marked[i][j] = True
変更する箇所は、mark_numberメソッド
以下の赤字部分を変更する。
def mark_number(self, number):
for i in range(5):
for j in range(5):
if self.card[i][j] == number:
self.marked[i][j] = True
以下の赤字部分を変更した。
def mark_number(self, number):
for i in range(5):
for j in range(5):
if self.card[i][j] == number:
self.card[i][j] = "✖️"
引かれた番号のカードが「✖️」になった。

問題点発生 – ビンゴにならない –
先程の画像を見てもらえればわかるが、Bの縦列が揃っているのにビンゴにならない。

最終的には、1 ~ 75までの一意の番号がなくなってしまった。

今の処理がどうなっているのか?
1. mark_numberメソッドで引かれた番号がカードにあれば「✖️」にする。
def play_bingo():
card = BingoCard()
card.mark_number(number)
class BingoCard:
def mark_number(self, number):
for i in range(5):
for j in range(5):
if self.card[i][j] == number:
self.card[i][j] = "✖️"
card.display_card()

2. check_bingoメソッドでビンゴ判定
if card.check_bingo():
print("ビンゴ!おめでとうございます!")
break
def check_bingo(self):
# 行と列でビンゴかどうかをチェック
for i in range(5):
if all(self.marked[i]): # 行のビンゴ
return True
if all([self.marked[j][i] for j in range(5)]): # 列のビンゴ
return True
# 対角線のビンゴをチェック
if all([self.marked[i][i] for i in range(5)]): # 左上から右下
return True
if all([self.marked[i][4 - i] for i in range(5)]): # 右上から左下
return True
return False
ここで判定条件をmarkedにしているのが原因。
解決方法
check_bingoメソッドの中身を「marked → card」に変更する。
もしくは、mark_numberメソッドでmarkedの状態を変更できるようにする。
後者の方が簡単。
以下の太字部分を追加した(元々あった)
def mark_number(self, number):
for i in range(5):
for j in range(5):
if self.card[i][j] == number:
self.card[i][j] = "✖️"
self.marked[i][j] = True
ビンゴ!

コメントを残す