リボライブ!

MikuHatsune2014-03-10

スクフェスで課金してURカード66枚をすべてコンプリートするのに140万円かかったという話。課金しまくることをリボライブ!というらしい。
https://twitter.com/yamato_s0816/statuses/442476514005618689
 
先行研究としてはガチャとは心の所作を見てほしい。
 
ソーシャルゲームのカードの特徴として、同じカードを2枚合成すると進化する(覚醒という)。スクフェスのガチャ設定として、50個のラブカストーン(課金して得られる)を使って11人セットのガチャが引ける。ラブカストーンはアプリ内課金で購入でき、たくさん買うと割引されるので、86個5000円セットを考える。
ガチャコンプ問題で、レアカードはある程度のまともな確率設定をしましょう、となったらしいので、UR(最上級レアカード)の出現確率は1%とスクフェスは明記している。
というわけで、確率1%で引くことができる66枚のURカードを2枚ずつ揃えるのに、いくらリボライブ!が必要かを考える。URカード当たり判定がきたときに、66枚のどのURカードがくるかは一様分布にしたがってサンプリングすることにする。これが、揃ってないURカードに偏って増えるとか減るとかなったら変動するので、興味のある人はシミュレーション設定を変えてみてほしい。
 
URカードが出る確率が一様分布であれば、最低でもコンプリートに680万かかるようなので、たぶん出ていないURカードがそこそこ優先的に出るような分布で調整されているような気がする。ディリクレ分布あたりでシミュレーションし直したい。

UR_p <- 0.01                      # URカードを引く確率
UR_n <- 66                        # URカードの総数
loveca_50 <- 11                   # 50個のラブカストーン消費で引けるカード数
stone_yen <- 5000 / 86            # ラブカストーン1個の単価
niter <- 8000                     # 50個消費で66枚*2 揃うまで引く十分な試行回数
UR_card <- matrix(0, niter, UR_n) # どのURカードを引いたか格納
miter <- 10000                    # シミュレーション回数
res <- rep(0, miter)              # コンプまでにかかったガチャ回数
for(j in seq(miter)){
	pb <- txtProgressBar(min=1, max=niter, style=3)
	setTxtProgressBar(pb, j)
	UR_card <- matrix(0, niter, UR_n)
	for(i in seq(niter)){
		one_trial <- sample(0:1, size=loveca_50, prob=c(1-UR_p, UR_p), replace=TRUE) # URカードを引くか
		hit <- sample(seq(UR_n), size=sum(one_trial), replace=TRUE)                  # どのURカードが選ばれるかは一様分布
		UR_card[i, hit] <- UR_card[i, hit] + 1
	}
	# すべてのカードが2枚揃うとき
	idx <- head(which(apply(apply(UR_card, 2, cumsum) >= 2, 1, all)), 1)
	res[j] <- idx
}

kakin <- res * 50 * stone_yen # ガチャ回数を金額に変換
hist(kakin, nclass=50, xaxt="n", xlab="課金額(百万円)", main="", col=5)
axis(1, at=seq(6.8e6, 2.3e7, length=6), labels=seq(6.8, 23, length=6))
quantile(kakin, 0.025)
   2.5% 
8058576 


 
ガチャをやったけれども、URカードどころかSRカードすら1枚も出ない状況をドブライブ!というらしい。
ドブライブ!になる状況は30%くらいある。4枚以上は統計学的に厳しい。

UR_p <- 0.01
one_trial <- replicate(miter, sample(0:1, size=loveca_50, prob=c(1-UR_p, UR_p), replace=TRUE))
dobu <- colSums(one_trial)
barplot(prop.table(table(dobu)), xlab="レアカード枚数", ylab="確率")
prop.table(table(dobu))
     0      1      2      3      4      5      6 
0.3073 0.3894 0.2125 0.0722 0.0164 0.0019 0.0003