使用Flask制作罕见的gacha模拟器


昨天,我使用Python的Web框架Flask创建了一个简单的响应系统。仅此一项就太无聊了,因此我想使用NumPy制作一些我可以享受的东西。

" Gacha"是一种机制,使您可以通过为当今流行的社交游戏和在线游戏付费一次来随机获得物品等。 10个连续的gacha是一种在一次试验中抽取10个稀有gacha的机制。在声称是免费游戏的社交游戏中,这是一种通过此类物品计费获利的机制。

模拟的目的是检查管理方是否可以提供一种煽动赌博精神的gacha,该赌博精神使玩家想收取很多费用,并且玩家方投资了真实货币,即所谓的真实货币。一个目标,例如(通过结果冷却头部)或预先感觉成功的概率为多少。

到目前为止,我们已经使用推理统计和可视化方法从一些样本中估计了总体,但是尝试仅凭理论难以想象的部分也是值得的。

Gacha规格

要执行的gacha的规格如下。

型号和价格

有两种类型的嘎查,"稀有嘎查"和" 10个连续的稀有嘎查"。稀有gacha每次300日元,连续10次稀有gacha每次3000日元。每次抽奖您将获得一张卡。

稀有度

稀有度翻译为稀有度。稀有度越高,价值越高。

顺便说一句,稀有这个词似乎发音为宗教。

<表格>

类型

说明


<身体>

R

很少见。最不值钱的。

SR

超级稀有。该值原样很高。

UR

Ultimate Rare。它是最有价值的,也是玩家获得它的目的。


中奖概率3??769115

稀有嘎查的中奖概率如下。

<表格>

R

SR

UR


<身体>

94.85%

5.04%

0.12%


连续10个稀有小游戏的获胜概率如下。

<表格>

R

SR

UR


<身体>

90.28%

9.29%

0.45%


但是,在连续10个稀有gacha中,SR总是会赢得最后一个gacha作为奖励。乍一看,这似乎是一种优惠待遇,但反过来,这意味着UR将不会在最后一轮获胜。

另外,概率符号的总和不等于100%。这是因为有第三个小数位并且被"四舍五入"了。假设舍入而不是舍入的原因是10个站的总数为100.02%,但是如果假设将三种稀有性的小数点后第三位四舍五入,则无法获得这样的总值。不是。

奖励类型

用户的目的是获得UR。此UR有12种类型的卡,从赠品1到赠品12。如果UR获胜,这些奖赏之一将以同等的概率获得。

Gacha实施

随机数生成

NumPy使用Mersenne Twister生成随机数。在这里和这里都有一篇关于用NumPy生成随机数的日语文章。

目前,为每个稀有度创建一个提取函数。实施加权提取器,如下所示。

通过加权

弹出卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def turn_rare():
    """レアガチャを回す"""
    result = []
    # 小数点第三位を切り上げて 94.85%, 5.04%, 0.12%
    weight = [0.94849, 0.0504, 0.00111]
    result.append(pickup_rare(weight))
    return result

def turn_10rare():
    """10 連レアガチャを回す"""
    result = []
    # 小数点第三位を切り上げて 90.28%, 9.29%, 0.45%
    weight = [0.90278, 0.09281, 0.00441]
    # 9 回抽選する
    for v in range(0, 9):
        result.append(pickup_rare(weight))
    # 最後の 1 回は必ず SR が当選する
    result.append("SR")
    return result

以上假设四舍五入到小数点后第三位的值中对管理方最有利的值。

然后,描述根据给定重量弹出卡的过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def pickup_rare(weight):
    """重みに応じてレアガチャを排出する"""
    rarities = ["R", "SR", "UR"]
    picked_rarity = np.random.choice(rarities, p=weight)

    # UR が当選した場合はどの景品にするのか決定する
    if picked_rarity == "UR":
        picked_rarity = "".join((picked_rarity, "(", pickup_premium(), ")"))

    return picked_rarity

def pickup_premium():
    """UR の景品を等確率を仮定して排出する"""
    ur = ["景品1", "景品2", "景品3", "景品4", "景品5", "景品6", "景品7",
          "景品8", "景品9", "景品10", "景品11", "景品12"]
    return np.random.choice(ur)

持有价格和次数的价值对象

值对象是保存值的对象。

这一次,我们将保留gacha旋转的次数和收费金额。这很麻烦,因此将它们组合成一个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class VO(object):
    def __init__(self):
        self._count = 0 # 回数
        self._price = 0 # 課金額

    def getcount(self):
        return self._count

    def setcount(self, count):
        self._count = count

    def getprice(self):
        return self._price

    def setprice(self, price):
        self._price = price

    count = property(getcount, setcount)
    price = property(getprice, setprice)

加工gacha

的工艺路线

然后实现Flask的路由。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@app.route('/')
def index():
    title = "ようこそ"
    message = "ガチャを回すにはボタンをクリックしてください"
    return render_template('index.html',
                           message=message, title=title)

@app.route('/post', methods=['POST', 'GET'])
def post():
    time = datetime.datetime.today().strftime("%H:%M:%S")
    message = ""
    if request.method == 'POST':
        result = []
        if 'rare' in request.form:
            title = "ガチャを回しました!"
            vo.price = vo.price + 300
            vo.count = vo.count + 1
            result = turn_rare()
        if '10rare' in request.form:
            title = "ガチャを回しました!"
            vo.price = vo.price + 3000
            vo.count = vo.count + 1
            result = turn_10rare()
        if 'reset' in request.form:
            title = "リセットしました"
            vo.price = 0
            vo.count = 0
            result = ""
            message = "リセットしました"
        return render_template('index.html',
                               result=result, title=title,
                               time=time, vo=vo,
                               message=message)
    else:
        return redirect(url_for('index'))

查看

最后,准备屏幕。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div class="form">
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <p class="lead">
          {% if result %}
            {{ time }} ガチャを回しました!<br>
            {{ vo.count }} 回目 合計金額 {{ vo.price }} 円<br>
            結果は
            {% for v in result %}
              {{ v }}
            {% endfor %}
            でした!
          {% else %}
            {{ message }}
          {% endif %}
        </p>
        <form action="/post" method="post" name="rare" class="form-inline">
          <button type="submit" name="rare" class="btn btn-default">レアガチャを回す</button>
        </form>
        <form action="/post" method="post" name="10rare" class="form-inline">
          <button type="submit" name="10rare" class="btn btn-default">10 連レアガチャを回す</button>
        </form>
        <form action="/post" method="post" name="reset" class="form-inline">
          <button type="submit" name="reset" class="btn btn-default">リセットする</button>
        </form>
      </div>
    </div>
  </div>
</div>

完成。

尝试转动gacha

像以前一样以python app.py的形式启动应用程序。

使用浏览器访问本地主机端口5000。

1.png

在这种状态下,如果按稀有gacha,则可以支付300日元;如果连续按10个稀有gacha,则可以支付3000日元来旋转该gacha。当我按10个电台进行试用时,得到了2个SR,如下所示。

2.png

可以获得多少次UR?请试一试。

顺便说一下,在此模拟中,我能够连续16次获得UR连续16次的UR,总费用为48,000日元。

3.png

重新考虑这笔费用是否真的值得奖是一个好主意。

以前,完整的gacha存在问题,但是尝试使用此模拟可能会很有趣,例如,查看准备所有12种类型的gacha UR需要花费多少。

这次发布的gacha概率是一个任意设置的值,与实际服务无关。

摘要

这次的主题是社交游戏gacha的玩法,但是以这种方式轻松验证基于经济理论的计算非常有意义。

假设在微观经济学理论中,经济学理论是关于人类行为的。为了客观地验证该理论是否能很好地解释实体经济,我们使用数学公式构建了经济模型。

量化模型称为计量经济学模型,它是经验分析的主题。

Python Flask的组合可以轻松,高效地实现仿真系统,这将为推进经验分析提供强大的帮助。

本文的源代码在这里。