2024年のパリオリンピックの柔道団体で使用されたルーレットをPythonで再現してみました。
柔道団体のルール
まずパリオリンピックの柔道団体のルール説明です。
各チームは男女3名ずつ、合計6名で構成されます。階級は男子が73kg以下、90kg以下、90kg超、女子が57kg以下、70kg以下、70kg。
チーム戦全体で3勝3敗になった場合、代表者戦(各チームから1名ずつ選ばれる)を行い、勝者がチームの勝利を決定します。
今回は決勝の日本vsフランスで結果が3勝3敗になった為に各チームから1名ずつ選ばれる方式が取られました。
なんと、その選手が選ばれる方法は電子ルーレットによって決定される方式だったため、不正が行われるのではないかと物議を醸しました。
実際には、5大会連続でメダルを獲得しているフランスの英雄、テディ・リネール選手が選ばれた結果、フランスに有利な条件で最後の試合が行われ、その結果、フランスが優勝しました。
実際に電子のルーレットでは不正する事ができるのか可能なのか自分でコードを書いてみました。
ソースコード
import tkinter as tk
from tkinter import ttk
import random
class RouletteApp:
def __init__(self, root):
self.root = root
self.root.title("ルーレット")
self.root.geometry("300x400")
self.choices = ["女子-57kg", "女子-70kg", "女子+70kg", "男子-73kg", "男子-90kg", "男子+90kg"]
self.fixed_choice = None
self.labels = []
self.create_widgets()
self.running = False
def create_widgets(self):
self.frame = tk.Frame(self.root)
self.frame.pack(expand=True)
self.arrow_label = tk.Label(self.frame, text="→", font=("Helvetica", 24))
self.arrow_label.grid(row=2, column=0, padx=(10, 0)) # 矢印を固定の位置に配置
for i in range(len(self.choices)):
label = tk.Label(self.frame, text="", font=("Helvetica", 18))
label.grid(row=i, column=1, pady=5)
self.labels.append(label)
self.start_button = ttk.Button(self.root, text="スタート", command=self.start_roulette)
self.start_button.pack(side="left", padx=10, pady=10)
self.stop_button = ttk.Button(self.root, text="ストップ", command=self.stop_roulette, state="disabled")
self.stop_button.pack(side="right", padx=10, pady=10)
def start_roulette(self):
self.running = True
self.start_button.config(state="disabled")
self.stop_button.config(state="normal")
self.scroll_labels()
def scroll_labels(self):
if self.running:
self.choices = self.choices[1:] + self.choices[:1] # リストのアイテムを回転させる
for i, label in enumerate(self.labels):
label.config(text=self.choices[i])
self.scroll_animation = self.root.after(100, self.scroll_labels)
def stop_roulette(self):
if self.running:
self.running = False
if self.scroll_animation:
self.root.after_cancel(self.scroll_animation)
self.select_result()
def select_result(self):
if self.fixed_choice and self.fixed_choice in self.choices:
# 指定された結果が出るようにリストを調整
while self.labels[2].cget("text") != self.fixed_choice:
self.choices = self.choices[1:] + self.choices[:1]
for i, label in enumerate(self.labels):
label.config(text=self.choices[i])
else:
# ランダムな結果を表示
random.shuffle(self.choices)
for i, label in enumerate(self.labels):
label.config(text=self.choices[i])
self.start_button.config(state="normal")
self.stop_button.config(state="disabled")
if __name__ == "__main__":
root = tk.Tk()
app = RouletteApp(root)
# 固定したい結果を指定する(ランダムにしたい場合はNone)
app.fixed_choice = "男子+90kg" # 指定された結果を表示
# app.fixed_choice = None # ランダムな結果を表示
root.mainloop()
書く前から結果はわかっていましたが、簡単に結果を操作する事が可能です。
app.fixed_choice = "男子+90kg" # 指定された結果を表示
上記の変数を変更する事でルーレットの結果は自在に操る事ができます。
私のようなプログラミングの素人でも簡単に書けたので、プロであれば1時間もあれば今回オリンピックで使用されたものと全く同じ物は作れるではないかと思います。
さいごに
実際にフランスが不正を行った証拠はありませんが、電子のルーレットでフランスの有利な条件になった以上、疑われても仕方がないと思います。
次回からは、公平性があるアナログのくじ引きのような物で抽選方式が取られる事を祈っています。
フランスのようにルーレットを使用して不正をしたい方はこの記事で紹介したコードを参考にしてみて下さい。