今回は簡易的なパチスロゲームを作って

自分の反応速度の限界にチャレンジしてみました。


解説動画はこちら

 

簡単パチスロアプリ

今回はStreamlitを用いて
簡単なパチスロアプリを作っていきます。

ローカルPCにstreamlitをインストールしたら
遊ぶことができると思います。
pip install streamlit 

必要なファイルは
main.py
game.py
の2つです。

コピペしてファイル作成して下さい。


main.py
from game import run_app

if __name__ == '__main__':
    run_app()




game.py
import streamlit as st
import random
import time
from typing import List, Tuple

# 絵柄の辞書と配当
SYMBOL_COUNTS = {
    'C': 6,
    'L': 5,
    'P': 3,
    'O': 3,
    'S': 2,
    'BAR': 1,
    '7': 1,
}

PAYOUT = {
    'C': 5,
    'L': 10,
    'P': 15,
    'O': 20,
    'S': 25,
    'BAR': 30,
    '7': 50,
}

# リールの数は21枚になること
TOTAL_PER_REEL = 21

def make_reel() -> List[str]:
    items = []
    for k, v in SYMBOL_COUNTS.items():
        items += [k] * v
    if len(items) != TOTAL_PER_REEL:
        raise ValueError(f"reel composition must be {TOTAL_PER_REEL}, got {len(items)}")
    random.shuffle(items)
    return items

def evaluate_result(s1: str, s2: str, s3: str) -> Tuple[int, str]:
    if s1 == s2 == s3:
        symbol = s1
        payout = PAYOUT.get(symbol, 0)
        return payout, f"{symbol} : + {payout} 枚"
    else:
        return 0, "揃わず"

def run_app():
    st.title('簡易パチスロ')

    # 初期化
    if 'medals' not in st.session_state:
        st.session_state['medals'] = 100
    if 'speed' not in st.session_state:
        st.session_state['speed'] = 0.1  # 秒
    if 'spinning' not in st.session_state:
        st.session_state['spinning'] = False
    # リール本体
    if 'reels' not in st.session_state:
        st.session_state['reels'] = [make_reel(), make_reel(), make_reel()]
    if 'indices' not in st.session_state:
        st.session_state['indices'] = [0, 0, 0]
    if 'stop_flags' not in st.session_state:
        st.session_state['stop_flags'] = [False, False, False]
    if 'last_message' not in st.session_state:
        st.session_state['last_message'] = ''

    # UI レイアウト
    col_top = st.columns([1, 1, 1])
    placeholders = [col_top[i].empty() for i in range(3)]
    for i in range(3):
        idx = st.session_state['indices'][i]
        symbol = st.session_state['reels'][i][idx]
        placeholders[i].markdown(f"### {symbol}")

    # 停止ボタン
    col_buttons = st.columns([1, 1, 1])
    if col_buttons[0].button('停止1'):
        st.session_state['stop_flags'][0] = True
    if col_buttons[1].button('停止2'):
        st.session_state['stop_flags'][1] = True
    if col_buttons[2].button('停止3'):
        st.session_state['stop_flags'][2] = True

    # メダル表示
    st.write(f"**メダル:** {st.session_state['medals']} 枚")

    # 停止スピード
    start_col, speed_col = st.columns([1, 1])
    if speed_col.slider('回転速度 (秒)', min_value=0.01, max_value=1.0, value=st.session_state['speed'], step=0.01, key='speed_input'):
        st.session_state['speed'] = st.session_state.pop('speed_input')

    # 開始ボタン
    if start_col.button('開始') and not st.session_state['spinning']:
        if st.session_state['medals'] < 5:
            st.warning('メダルが不足しています。')
        else:
            # 消費
            st.session_state['medals'] -= 5
            # 新しいリールを作る
            st.session_state['reels'] = [make_reel(), make_reel(), make_reel()]
            # indices をランダムに初期化
            st.session_state['indices'] = [random.randrange(TOTAL_PER_REEL) for _ in range(3)]
            st.session_state['stop_flags'] = [False, False, False]
            st.session_state['spinning'] = True
            st.session_state['last_message'] = ''
            st.rerun() 

    # 回転ループ
    if st.session_state['spinning']:
        while True:
            # まず停止していないリールのインデックスを進める
            for i in range(3):
                if not st.session_state['stop_flags'][i]:
                    st.session_state['indices'][i] = (
                        st.session_state['indices'][i] + 1
                    ) % TOTAL_PER_REEL

            # 表示更新
            for i in range(3):
                idx = st.session_state['indices'][i]
                symbol = st.session_state['reels'][i][idx]
                placeholders[i].markdown(f"### {symbol}")

            # 停止判定
            if all(st.session_state['stop_flags']):
                s1 = st.session_state['reels'][0][st.session_state['indices'][0]]
                s2 = st.session_state['reels'][1][st.session_state['indices'][1]]
                s3 = st.session_state['reels'][2][st.session_state['indices'][2]]
                payout, msg = evaluate_result(s1, s2, s3)
                if payout > 0:
                    st.session_state['medals'] += payout
                st.session_state['last_message'] = msg
                st.session_state['spinning'] = False
                st.rerun()
                break

            # 待機 → 再実行
            time.sleep(st.session_state['speed'])
            st.rerun()

    # 結果表示
    if st.session_state['last_message']:
        st.info(st.session_state['last_message'])




実行方法は main.py のある場所で
streamlit run main.py
です。


実行するとこんな画面になります。

スクリーンショット 2025-09-27 15.57.54

開始ボタンクリックでゲーム開始
停止ボタンをクリックしてリールを止め
3つ絵柄が揃うとコイン獲得です。

回転速度を変えると、変化のスピードを変えられます。

自分は1秒でないと絵柄を揃えられなかったので
だいぶ反応速度が落ちていますね

どこまで行けるか、チャレンジしてみて下さい。

それでは。