Last active
November 9, 2022 08:03
-
-
Save haowen-xu/f7700b397f8932453928cf8024b7e897 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import click | |
import numpy as np | |
import seaborn as sns | |
from matplotlib import pyplot as plt | |
角色概率 = np.array( | |
[0.006] * 73 + # 1 ~ 73 | |
[ | |
0.066, 0.126, 0.186, 0.246, 0.306, 0.366, 0.426, # 74 ~ 80 | |
0.486, 0.546, 0.606, 0.666, 0.726, 0.786, 0.846, 0.906, 0.966, 1.0 # 81 ~ 90 | |
] | |
) | |
武器概率 = np.array( | |
[0.007] * 62 + # 1 ~ 62 | |
[ | |
0.077, 0.147, 0.217, 0.287, 0.357, 0.427, 0.497, 0.567, # 63 ~ 70 | |
0.637, 0.707, 0.777, 0.847, 0.917, 0.987, 0.998, 0.999, 1.0 # 71 ~ 80 | |
] | |
) | |
def 出金次数(probs, N=1): | |
K = len(probs) | |
dice = np.random.random(size=[N, len(probs)]) | |
counts = [K] * N | |
for i in range(N): | |
for k, p in enumerate(probs): | |
if dice[i, k] <= p: | |
counts[i] = k + 1 | |
break | |
if len(counts) == 1: | |
return counts[0] | |
return np.array(counts) | |
def 限定角色次数(N=1): | |
counts = [None] * N | |
for i in range(N): | |
c = 0 | |
for _ in range(2): | |
c += 出金次数(角色概率) | |
if random.random() < 0.5: | |
break | |
counts[i] = c | |
if len(counts) == 1: | |
return counts[0] | |
return np.array(counts) | |
def 限定武器次数(N=1): | |
counts = [None] * N | |
for i in range(N): | |
c = 0 | |
last_is_up = True | |
for _ in range(3): | |
c += 出金次数(武器概率) | |
if last_is_up: | |
a = random.random() | |
if a < 0.75: | |
# 75% 概率是 up 武器 | |
last_is_up = True | |
if a < 0.75 * 0.5: | |
# 1/2 概率抽中定轨 | |
break | |
else: | |
last_is_up = False | |
else: | |
# 一定是 UP 武器 | |
last_is_up = True | |
if random.random() < 0.5: | |
# 1/2 概率抽中定轨 | |
break | |
counts[i] = c | |
if len(counts) == 1: | |
return counts[0] | |
return np.array(counts) | |
def 角色命座抽数(k=0, N=1): | |
if k < 0: | |
return np.zeros([N]) | |
counts = 限定角色次数(N * (k + 1)).reshape([-1, (k + 1)]).sum(-1) | |
return counts | |
def 武器精炼抽数(k=0, N=1): | |
if k < 1: | |
return np.zeros([N]) | |
counts = 限定武器次数(N * k).reshape([-1, k]).sum(-1) | |
return counts | |
def plot_counts(counts): | |
sns.ecdfplot( | |
counts, | |
stat='proportion' | |
) | |
plt.grid() | |
ax2 = plt.twinx() | |
sns.histplot( | |
counts, | |
stat='density', | |
discrete=True, | |
alpha=.4, | |
ax=ax2 | |
) | |
# sns.ecdfplot(counts, stat='count') | |
print('平均次数: ', np.mean(counts)) | |
plt.show() | |
@click.command() | |
@click.option('-c', 'character', type=int, default=0, help='角色命座。') | |
@click.option('-w', 'weapon', type=int, default=0, help='武器精炼。') | |
@click.option('-N', 'repeat', type=int, default=10000, help='模拟次数。') | |
def main(character, weapon, repeat): | |
counts = 角色命座抽数(k=character, N=repeat) + 武器精炼抽数(k=weapon, N=repeat) | |
print(f'{character}命{weapon}精抽卡次数概率') | |
plot_counts(counts) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment