ゲームのドロップの話
こういう文面をまとめてもらうのもLLMを駆使してた
大変だった。でも壁打ちたのしい
GPTはMMOっていってたけど
Geminiはそこまでいってなかった
code:txt1
-----------------------------------------------------
// アルゴリズム X: 獲得可能性が徐々に下がる方式 (一般的なオフラインゲームで採用されやすい)
-----------------------------------------------------
// 1. 抽選ステップ
// - 抽選①: アイテムAがドロップするかどうかを判定 (確率 10%)
// - 抽選②: ドロップが確定した場合、未入手のアイテムだけを対象に種類を抽選。
// 2. 特徴
// - 全体のドロップ率 (アイテムが出る確率) は、収集が進むにつれて下がる。
// - 19個集めた時点でのドロップ率は 10% * (1/20) = 0.5%
// - ドロップが成功すれば、必ず未入手品。無駄なドロップ演出はない。
// 3. 獲得可能性
// - 19個目まで: 段階的に下がる (10% → 0.5%)
// - 20個目以降: 0%
-----------------------------------------------------
// アルゴリズム Y: 獲得可能性が最後の1個まで維持される方式 (ユーザーが理想とする仕組み)
-----------------------------------------------------
// 1. 抽選ステップ
// - 抽選①: アイテムAのドロップ機会があるかどうかを判定 (確率 常に 10%)
// - 抽選②: ドロップ機会が確定した場合、未入手のアイテムだけを対象に種類を抽選。
// 2. 特徴
// - 全体のドロップ率 (アイテムが出る確率) は、20個目まで 10% で維持される。
// - ドロップが成功すれば、必ず未入手品。無駄なドロップ演出はない。
// - (注意: この方式は、10%のまま未入手品を確定させるため、システムが確率を裏で操作していると解釈されることがある)
// 3. 獲得可能性
// - 19個目まで: 常に 10%
// - 20個目以降: 0% (種類抽選の候補がなくなるため)
-----------------------------------------------------
上記アルゴリズムXとアルゴリズムYについて質問します。
-----------------------------------------------------
Q1: ゲームの「最強武器の素体」のようなやりこみ要素のドロップとして、一般的にどちらのアルゴリズムが採用されやすいと考えられますか?
Q2: アルゴリズムYは、獲得可能性を最後まで10%で維持し、無駄なく未入手品だけを出しますが、この設計が技術的・ゲームバランス的に見て矛盾なく実現可能であるか評価してください。
シミュレーター
Powershellで最初作ってもらったけど動かなくて、Pythonに。
code:SIM.py
import random
# シミュレーション設定
TOTAL_ITEMS = 20
BASE_DROP_RATE = 0.10 # 抽選①の確率 (10%)
BASE_DROP_RATE = 0.01 # 抽選①の確率 (1%)
RUNS = 10000 # シミュレーション実行回数(平均値を出すため)
# ----------------------------------------------------------------------------------
def simulate_algorithm_x(max_items, base_rate):
"""
アルゴリズム X: 獲得可能性が徐々に下がる方式
- ドロップ確定 (10%)後、未入手品を引いた場合のみ collected に追加。
- 既入手品を引いた場合は何も起きない。
"""
attempts = 0
collected = set() # 収集済みアイテムのセット
while len(collected) < max_items:
attempts += 1
remaining = max_items - len(collected)
# 1. 抽選①: アイテムAがドロップするかどうか (常に10%)
if random.random() < base_rate:
# 2. 抽選②: ドロップ確定時、未入手品を引く確率
# 獲得可能性: 抽選①の確率 * (未入手数 / 全体数)
draw_chance = remaining / max_items
if random.random() < draw_chance:
# ドロップ成功、かつ未入手品を引いた
available_items = i for i in range(1, max_items + 1) if i not in collected
if available_items:
new_item = random.choice(available_items)
collected.add(new_item)
return attempts
# ----------------------------------------------------------------------------------
def simulate_algorithm_za(max_items, base_rate):
"""
アルゴリズム ZA (Xの派生形): 獲得可能性が徐々に下がるが、ドロップ演出は成功。
- 抽選①でドロップ確定 (10%)後、アイテムの種類を抽選。
- 抽選されたアイテムを無条件で drop_log に記録(演出成功)。
- 未入手品を引いた場合のみ collected に追加。
"""
attempts = 0
collected = set() # 収集済みアイテムのセット (コンプリート判定用)
drop_log = [] # ドロップしたアイテムのログ/配列 (ドロップ演出成功のカウント用)
while len(collected) < max_items:
attempts += 1
# 1. 抽選①: アイテムAがドロップするかどうか (常に10%)
if random.random() < base_rate:
# 2. 抽選②: ドロップするアイテムの種類を抽選 (全20種類から均等に選ぶ)
# これは、Xのロジックを「全アイテムから抽選し、未入手なら獲得」と解釈し直したもの。
# XとZAの「未入手品獲得までの試行回数」は同一の確率分布になる。
# ドロップアイテムの抽選 (1からmax_itemsまで、すべて均等確率)
dropped_item = random.randint(1, max_items)
# ドロップ演出成功とみなし、ログに追加
drop_log.append(dropped_item)
# 未入手品であれば collected に追加
if dropped_item not in collected:
collected.add(dropped_item)
# 今回はコンプリートまでの「attempts (周回数)」を比較するため、
# drop_logのサイズ(ドロップ成功回数)は返さない
return attempts
# ----------------------------------------------------------------------------------
def simulate_algorithm_y(max_items, base_rate):
"""
アルゴリズム Y: 獲得可能性が最後まで維持される方式
- ドロップ機会 (10%)が確定した場合、未入手のアイテムだけを対象に種類を抽選。
- 成功すれば必ず未入手品。無駄なドロップはない。
"""
attempts = 0
collected = set()
while len(collected) < max_items:
attempts += 1
# 1. 抽選①: アイテムAのドロップ機会があるかどうか (常に10%)
if random.random() < base_rate:
# 2. 抽選②: 未入手のアイテムだけを対象に種類を抽選。
available_items = i for i in range(1, max_items + 1) if i not in collected
# 未入手品が存在する場合のみドロップ(Yのコアロジック)
if available_items:
new_item = random.choice(available_items)
collected.add(new_item)
return attempts
# ----------------------------------------------------------------------------------
# メイン実行ブロック
# ----------------------------------------------------------------------------------
print("--- ドロップアルゴリズム比較シミュレーション (ZA追加版) ---")
print(f"アイテム総数: {TOTAL_ITEMS} 個")
print(f"基本ドロップ率: {BASE_DROP_RATE * 100:.0f}% (抽選①)")
print(f"シミュレーション実行回数: {RUNS} 回")
print("-" * 65)
# X, ZA, Y のシミュレーション実行
results_x, results_za, results_y = [], [], []
for _ in range(RUNS):
results_x.append(simulate_algorithm_x(TOTAL_ITEMS, BASE_DROP_RATE))
results_za.append(simulate_algorithm_za(TOTAL_ITEMS, BASE_DROP_RATE))
results_y.append(simulate_algorithm_y(TOTAL_ITEMS, BASE_DROP_RATE))
average_x = sum(results_x) / RUNS if results_x else 0
average_za = sum(results_za) / RUNS if results_za else 0
average_y = sum(results_y) / RUNS if results_y else 0
# 結果表示
print("\n--- シミュレーション結果 (20個コンプリートまでの平均試行回数) ---")
print(f"アルゴリズム X (未入手のみドロップ演出): {average_x:.0f} 回")
print(f"アルゴリズム Y (最後まで獲得可能性維持): {average_y:.0f} 回")
print(f"アルゴリズム ZA (Xの形変え,既入手もドロップ演出有): {average_za:.0f} 回")
print("-" * 65)
速度で見たら
golangが最速だったんだなぁ!
Pythonの10倍くらいはやい
code:a
PS C:\_home\Go\SIM> go run .
--- ドロップアルゴリズム比較シミュレーション (ZA追加版) ---
アイテム総数: 20 個
基本ドロップ率: 1% (抽選①)
シミュレーション実行回数: 10000 回
-------------------------------------------------------------
--- シミュレーション結果 (20個コンプリートまでの平均試行回数) ---
アルゴリズム X (未入手のみドロップ演出): 7223 回
アルゴリズム Y (最後まで獲得可能性維持): 2002 回
アルゴリズム ZA (Xの形変え,既入手も演出有): 7146 回
-------------------------------------------------------------
実行時間X: 548.916ms
実行時間Y: 99.0845ms
実行時間ZA: 526.214ms
PS C:\_home\Go\SIM>
PS C:\_home> & C:\Users\Python\Python39\python.exe c:/_home/Go/SIM/SIM.py
--- ドロップアルゴリズム比較シミュレーション (ZA追加版) ---
アイテム総数: 20 個
基本ドロップ率: 1% (抽選①)
シミュレーション実行回数: 10000 回
-------------------------------------------------------------
--- シミュレーション結果 (20個コンプリートまでの平均試行回数) ---
アルゴリズム X (未入手のみドロップ演出): 7192 回, 実行時間: 5.12 秒
アルゴリズム Y (最後まで獲得可能性維持): 1995 回, 実行時間: 1.32 秒
アルゴリズム ZA (Xの形変え,既入手も演出有): 7209 回, 実行時間: 4.21 秒
-------------------------------------------------------------
PS C:\_home>