Yesterday created a simple response system with the Python web framework Flask. This alone is too boring, so I'd like to use NumPy to make something that I can enjoy a little.
"Gacha" is a mechanism that allows you to randomly obtain items, etc. by paying once for social games and online games that are popular these days. 10 consecutive gachas is a mechanism to draw 10 rare gachas in one trial. In social games that claim to be free-to-play, it is a mechanism to make a profit by such item billing.
The purpose of the simulation is to check if the gacha can be provided, as the management side incites the gambling spirit that makes the player want to charge a lot. the side there is the aim, such as felt or to succeed in advance how much of probability before turning on the real money so-called real money (the result by cooling the head).
Until now, the population has been selected from some samples using Inference Statistics and Visualization. I've been guessing, but it's also worth trying out the parts that can't be imagined by theory alone.
The specifications of the gacha to be implemented are as follows.
There are two types of gacha, "rare gacha" and "10 consecutive rare gacha". Rare gacha is 300 yen each time, and 10 consecutive rare gacha is 3,000 yen each time. You will get one card for each draw.
Rarity is translated as rarity. The higher the rarity, the higher the value.
As an aside, the word rarity seems to be pronounced more accurately.
type | Description |
---|---|
R | Just rare. The least valuable. |
SR | Super rare. The value is high as it is. |
UR | Ultimate rare. It is the most valuable and it is the player's purpose to obtain it. |
The winning probability of rare gacha is as follows.
R | SR | UR |
---|---|---|
94.85% | 5.04% | 0.12% |
The winning probability of 10 consecutive rare gachas is as follows.
R | SR | UR |
---|---|---|
90.28% | 9.29% | 0.45% |
However, in 10 consecutive rare gachas, SR will always win the last one as a bonus. At first glance this seems like a preferential treatment, but conversely it means that the UR will never win in the final round.
Also, the probability notation does not add up to 100 percent. This is because there is a third decimal place and it is "rounded up". The reason for assuming rounding up instead of rounding is that the total of 10 stations is 100.02%, but if it is assumed that the third decimal place of the three types of rarity is rounded off, such a total value cannot be obtained. Because there isn't.
The purpose of the user is to obtain the UR. There are 12 types of cards for this UR, from giveaway 1 to giveaway 12. If the UR wins, one of these prizes will be [equal probability](http://en.wikipedia.org/wiki/%E7%AD%89%E7%A2%BA%E7%8E%87% It shall be available at E3% 81% AE% E5% 8E% 9F% E7% 90% 86).
NumPy generates random numbers by Mersenne Twister. Random number generation with NumPy is here And here has an article in Japanese.
For the time being, create an extraction function for each rarity. Implement the weighted extractor as follows.
def turn_rare():
"""Turn the rare gacha"""
result = []
#Round up to the third decimal place 94.85%, 5.04%, 0.12%
weight = [0.94849, 0.0504, 0.00111]
result.append(pickup_rare(weight))
return result
def turn_10rare():
"""Turn 10 consecutive rare gachas"""
result = []
#Round up the third decimal place to 90.28%, 9.29%, 0.45%
weight = [0.90278, 0.09281, 0.00441]
#9 lottery
for v in range(0, 9):
result.append(pickup_rare(weight))
#SR always wins the last one
result.append("SR")
return result
The above assumes the value that is most advantageous to the management side among the values rounded up to the third decimal place.
After that, describe the process of ejecting the card according to the given weight.
def pickup_rare(weight):
"""Eject rare gacha according to weight"""
rarities = ["R", "SR", "UR"]
picked_rarity = np.random.choice(rarities, p=weight)
#If the UR wins, decide which prize to give
if picked_rarity == "UR":
picked_rarity = "".join((picked_rarity, "(", pickup_premium(), ")"))
return picked_rarity
def pickup_premium():
"""Discharge UR prizes assuming equal probability"""
ur = ["Freebie 1", "Freebie 2", "Freebie 3", "Freebie 4", "Freebie 5", "Freebie 6", "Freebie 7",
"Freebie 8", "Freebie 9", "Freebie 10", "Freebie 11", "Freebie 12"]
return np.random.choice(ur)
A value object is an object that holds a value.
This time, we will keep the number of times the gacha was turned and the amount charged. It's a hassle, so combine them into one object.
class VO(object):
def __init__(self):
self._count = 0 #Number of times
self._price = 0 #Billing amount
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)
Now we'll implement Flask's routing.
@app.route('/')
def index():
title = "Welcome"
message = "Click the button to turn the gacha"
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 = "I turned the gacha!"
vo.price = vo.price + 300
vo.count = vo.count + 1
result = turn_rare()
if '10rare' in request.form:
title = "I turned the gacha!"
vo.price = vo.price + 3000
vo.count = vo.count + 1
result = turn_10rare()
if 'reset' in request.form:
title = "Reset"
vo.price = 0
vo.count = 0
result = ""
message = "Reset"
return render_template('index.html',
result=result, title=title,
time=time, vo=vo,
message=message)
else:
return redirect(url_for('index'))
Finally, prepare the screen.
<div class="form">
<div class="container">
<div class="row">
<div class="col-md-12">
<p class="lead">
{% if result %}
{{ time }}I turned the gacha!<br>
{{ vo.count }}Total amount of money{{ vo.price }}Circle<br>
Result is
{% for v in result %}
{{ v }}
{% endfor %}
was!
{% else %}
{{ message }}
{% endif %}
</p>
<form action="/post" method="post" name="rare" class="form-inline">
<button type="submit" name="rare" class="btn btn-default">Turn rare gacha</button>
</form>
<form action="/post" method="post" name="10rare" class="form-inline">
<button type="submit" name="10rare" class="btn btn-default">Turn 10 consecutive rare gachas</button>
</form>
<form action="/post" method="post" name="reset" class="form-inline">
<button type="submit" name="reset" class="btn btn-default">Reset</button>
</form>
</div>
</div>
</div>
</div>
That's all there is to it.
Start the application as python app.py as in Last time.
Access port 5000 on localhost in your browser.
In this state, if you press the rare gacha, you can pay 300 yen, and if you press the 10-series rare gacha, you can pay 3,000 yen to spin the gacha. When I pressed 10 stations as a trial, I got 2 SRs as shown below.
How many trials can you get the UR? Please give it a try.
By the way, in this simulation, I was able to obtain UR for 10 consecutive rare gachas 16 times for a total charge of 48,000 yen.
It's a good idea to reconsider whether this charge is really worth the prize.
Previously [Comp Gacha](http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%97%E3%83%AA%E3%83%BC%E3 % 83% 88% E3% 82% AC% E3% 83% 81% E3% 83% A3) was a problem, but for example, in order to use this simulation to prepare all 12 types of Gacha URs. It may be interesting to try how much it will cost.
The probability of gacha posted this time is a value set arbitrarily and has nothing to do with the actual service.
This time, I used the social game gacha as a theme, but it is very meaningful to be able to easily verify the calculation based on ** economic theory ** in this way.
Economic theory, for example, in microeconomic theory, is hypothetically derived about human behavior. To objectively verify that the theory explains the real economy well, use mathematical formulas to build a ** economic model **.
The quantified model is called the ** econometric model ** and is subject to empirical analysis.
The combination of Python + Flask, which makes it easy and highly functional to implement a simulation system, will be a powerful help in advancing empirical analysis.
The source code of this article is available at here.
Recommended Posts