Created
October 31, 2025 17:46
-
-
Save vvb2060/28044ccc750b7f8f3f9916dcf23731c8 to your computer and use it in GitHub Desktop.
星塔旅人抽卡模拟
This file contains hidden or 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 numpy as np | |
| import matplotlib.pyplot as plt | |
| from tqdm import trange | |
| P = 0.01 # 抽中概率 | |
| GIFT_LIMIT = 120 # 领取阈值 | |
| GLOBAL_LIMIT = 160 # 全局保底 | |
| N_PERIODS = 500 # 模拟期数 | |
| TRIALS = 1000 # 重复次数 | |
| def simulate_period(strategy, g): | |
| pulls = 0 | |
| obtained = [False, False] | |
| pool_counts = [0, 0] | |
| while not all(obtained): | |
| for pid in range(2): # 每期两池 | |
| if obtained[pid]: | |
| continue | |
| if strategy == "single": # 顺序抽池, 一池出货后切换抽另一池 | |
| if pid == 1 and not obtained[0]: | |
| continue | |
| elif strategy == "alt": # 交替抽池, 轮流抽两池 | |
| pass | |
| elif strategy == "switch": # 切换抽池, 一池80抽不出货切换抽另一池,出货后再回来继续抽 | |
| if pool_counts[0] >= 80 and not obtained[1]: | |
| if pid == 0: | |
| continue | |
| elif pid == 1 and not obtained[0]: | |
| continue | |
| else: | |
| raise ValueError("Unknown strategy") | |
| pulls += 1 | |
| pool_counts[pid] += 1 | |
| g += 1 | |
| if random.random() < P or g >= GLOBAL_LIMIT: | |
| obtained[pid] = True | |
| g = 0 # 出货重置保底 | |
| elif pool_counts[pid] == GIFT_LIMIT: | |
| obtained[pid] = True # 领取不重置保底 | |
| # print(f"抽数: {pulls}, 保底计数: {g}, 池抽数: {pool_counts[0]} {pool_counts[1]}, 策略: {strategy}") | |
| return pulls, g | |
| def simulate(strategy, periods=N_PERIODS, trials=TRIALS): | |
| results = [] | |
| for _ in trange(trials, desc=f"{strategy}"): | |
| g = 0 | |
| total_pulls = 0 | |
| for _ in range(periods): | |
| pulls, g = simulate_period(strategy, g) | |
| total_pulls += pulls | |
| results.append(total_pulls/periods) | |
| return np.array(results) | |
| alt_results = simulate("alt") | |
| single_results = simulate("single") | |
| switch_results = simulate("switch") | |
| print(f"交替抽池 平均每期抽数: {alt_results.mean():.2f}") | |
| print(f"顺序抽池 平均每期抽数: {single_results.mean():.2f}") | |
| print(f"切换抽池 平均每期抽数: {switch_results.mean():.2f}") | |
| plt.rc('font',family='SimHei') | |
| plt.figure(figsize=(8,5)) | |
| plt.hist(alt_results, bins=50, alpha=0.6, label="交替抽池") | |
| plt.hist(single_results, bins=50, alpha=0.6, label="顺序抽池") | |
| # plt.hist(switch_results, bins=50, alpha=0.6, label="切换抽池") | |
| plt.xlabel("平均每期抽数") | |
| plt.ylabel("出现次数") | |
| plt.title(f"{N_PERIODS} 期模拟 ({TRIALS} 次重复)") | |
| plt.legend() | |
| plt.show() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
交替抽池 平均每期抽数: 125.10
顺序抽池 平均每期抽数: 123.15
切换抽池 平均每期抽数: 125.25
结论:在每期两池的情况下,应该在一池出货后再切换抽另一池,平均每个概率提升5星角色需要62抽