ガチャ

簡単なガチャの実装について考える

More than 1 year has passed since last update.

これはガチャ勉強会で発表した資料である。

勉強会資料に使うので自己紹介付き。



自己紹介

icon


  • なかやん・ゆーき / ぺんぎん / もみあげ / ぽけば


  • @pocketberserker / id:pocketberserker

  • その辺で倒れているプログラマ



今回の想定


  • ガチャの対象となるアイテムは1種類


    • "武器"、”防具”という複数ではなく”カード”みたいな単一のもの

    • 複雑になることを避ける

    • 世の中の大半は1種類なので問題ないはず



  • ガチャはモジュールとして分離可能


    • テストを容易にする

    • クライアントのことは考えない



  • データベースにいれることを想定


    • 特に深い意味はない

    • メンテナンスツールを考えると必要か?

    • メモリに全部のせる富豪的なノリでも問題ない?



  • 汎用的な作りにする


    • 凝ったものは面倒





ガチャシステム(?)に要求されること


  • ガチャ一覧の取得

  • 各ガチャで提供されるアイテム一覧


    • 何が入手できるのア重要な要素である



  • 価格

  • 提供割合(オプション)


    • 最近増えてきた



  • 提供時期

  • 何個アイテムを手に入れられるか


    • n連というやつ



  • 履歴



テーブル

必要そうなものをささっと書いてみる。



ガチャ

カラム
概要

ガチャId
一意に識別できる何か

説明文
プレイヤーがじゃぶじゃぶ(検閲されました)

価格
一回回すのに必要なお金

個数
n連(nは1以上の自然数)

開始日時

終了日時



レート

カラム
概要

ガチャId

アイテムId

確率
重みづけ



履歴

カラム
概要

ユーザId

ガチャId

アイテムId

入手日時



アイテム(参考)

カラム
概要

アイテムId

名前

説明文

レア度



提供割合を算出する

各アイテムにはレア度が設定されていると仮定する。


  1. レア度でgroupBy

  2. 各レア度ごとにsum

これで各レア度の重みがわかる。



アイテムを選択する(C++11)

C++11にはstd::discrete_distributionという関数がある。

指定した確率テーブルを基にインデックスを返すので、インデックスに対応するアイテムを取得すればよい。



n連

forとかで回せば良い。



テスト

時間とメモリが潤沢なら、n連ガチャ(nは大きな数)を用意して実行し、各アイテムの出現率が誤差範囲内に収まれば良い。



ガチャを実装することの問題点


  • レアのありがたみが無くなる


    • 百万連ガチャをつくればだいたい全部引ける

    • ↑はたしてそれはガチャなのか……?





まとめ


  • ガチャは簡単に実装できる(簡単なものなら)


    • 複雑なガチャもあるらしい

    • ユーザの入手履歴を見ながら出現率を制御するのはコストに見合わないのではないか



  • 問題はだいたいガチャを引く以外の部分だと思う


    • 価格問題

    • 確率表示

    • n回引いてレアがでなければ1個確実に提供