Files
roll-room/pyground/sugar/SugarRushSimulator.py
2026-04-23 16:58:11 +08:00

174 lines
5.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import random
from typing import List, Dict, Tuple, Optional
import time
from SugarRush1000 import SugarRush1000
"""
此程序主要模拟用户使用过程中的体验指标
返奖率 RTP = 总赢 / 总投注
中奖率/级联率
平均多久一次获取一次连线 = 带连线的旋转次数 / 总旋转次数
免费旋转率
平均多久一次获取一次免费旋转 = 命中免费旋转次数 / 总旋转次数(不算免费旋转)
平均免费旋转次数 = 总免费旋转次数 / 总旋转次数
"""
class SugarRushSimulator:
def __init__(self, buy_type: Optional[str] = None):
self.buy_type = buy_type
self.f = open(
f"simulator_log_{'normal' if buy_type is None else buy_type}_{time.time()}.log",
"w",
)
def simulate_batch(self, weights, scotter_counts_weights, spins: int) -> Dict:
"""
模拟指定次数的旋转
:param spins: 模拟次数
:param buy_type: None=普通混合模式, 'standard'=只测买普通, 'super'=只测买超级
:return: 统计结果
"""
begin_balance = 1_0000_0000
game = SugarRush1000(
balance=begin_balance,
weights=weights,
scotter_counts_weights=scotter_counts_weights,
)
total_bet = 0.0
total_win = 0.0
game_spins = []
for index in range(spins):
spin = {
"gid": index + 1,
"score": 0,
"count": 0,
"feature": "normal" if self.buy_type is None else self.buy_type,
"extra_free": 0,
"steps": [],
}
game_spins.append(spin)
if self.buy_type and self.buy_type != "normal":
r = game.buy_free_spins(self.buy_type)
total_bet += r["cost"]
can_spins = 1
free_spind_id = 0
aes = 0
while can_spins > 0:
can_spins -= 1
res = game.doSpin()
game.mock_grid = None
if res["error"]:
raise Exception("模拟器异常", res["error"])
if res["free_spins_remaining"] >= 0:
can_spins = res["free_spins_remaining"]
actual_cost = res["actual_bet"]
if actual_cost > 0:
total_bet += actual_cost
free_spind_id += 1
for step in res["steps"]:
step["gid"] = spin["gid"]
step["free_spin_id"] = free_spind_id
step["aes"] = aes
aes += 1
spin["steps"].append(step)
if res["extra_free"]:
spin["extra_free"] += 1
spin["score"] = res["spin_total_win"]
spin["count"] = len(spin["steps"])
total_win += spin["score"]
if len(game_spins) >= 100:
self.write_log(game_spins)
game_spins = []
if len(game_spins) > 0:
self.write_log(game_spins)
game_spins = []
print(f"旋转{spins}RTP {(total_win / total_bet) * 100}")
return {}
def write_log(self, games):
buf = ""
for game in games:
buf += json.dumps(game, ensure_ascii=False) + "\n"
self.f.write(buf)
self.f.flush()
if __name__ == "__main__":
scotter_count_weights = {
"3": 7.26421894353717,
"4": 4.1724734692682395,
"5": 0.8119106579617028,
"6": 0.20313929837878217,
"7": 0.04857599989214818,
}
batchs = [
# {
# "buy_type": "normal",
# "spins": 20000,
# "weights": {
# "A": 16.559326336631095,
# "B": 17.242437197138468,
# "C": 23.794844051571708,
# "D": 24.480364769888073,
# "E": 31.29327382410323,
# "F": 38.17160528628571,
# "G": 17.242437197138468,
# "S": 2.2546844695944754,
# },
# "scotter_count_weights": scotter_count_weights,
# },
{
"buy_type": "standard",
"spins": 5000,
"weights": {
"A": 18.92167765262542,
"B": 21.106974838197058,
"C": 31.250953223681833,
"D": 34.54623003651251,
"E": 47.52175529241897,
"F": 62.474728710698884,
"G": 21.106974838197058,
"S": 2.666109542063759,
},
"scotter_count_weights": scotter_count_weights,
},
# {
# "buy_type": "super",
# "spins": 5000,
# "weights": {
# "A": 19.015957779792195,
# "B": 21.291015318701493,
# "C": 31.66660200727613,
# "D": 35.193596023259865,
# "E": 48.7122724047052,
# "F": 64.49005324700025,
# "G": 21.291015318701493,
# "S": 2.6840958157151236,
# },
# "scotter_count_weights": scotter_count_weights,
# },
]
for batch in batchs:
sim = SugarRushSimulator(buy_type=batch["buy_type"])
sim.simulate_batch(
batch["weights"], batch["scotter_count_weights"], batch["spins"]
)