from time import time import json import random from typing import List, Dict, Tuple, Optional import time from SugarRush1000 import SugarRush1000 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 check_target_score(self, score, target_scores): for i in range(len(target_scores)): if score[i] < target_scores[i][2]: return False return True def getIndex(self, score, target_scores): for i in range(len(target_scores)): if score > target_scores[i][0] and score <= target_scores[i][1]: return i return -1 def simulate_batch( self, weights, scotter_counts_weights, target_scores: List[Tuple[int, int, int]] ) -> Dict: """ 模拟指定次数的旋转 :param target_scores: 模拟目标分数范围 :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 = [] index = 0 real_score_counts = [0 for _ in target_scores] while True: if self.check_target_score(real_score_counts, target_scores): break spin = { "gid": index + 1, "score": 0, "count": 0, "feature": "normal" if self.buy_type is None else self.buy_type, "extra_free": 0, "steps": [], } bet = 0 if self.buy_type and self.buy_type != "normal": r = game.buy_free_spins(self.buy_type) 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: 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"]) range_index = self.getIndex(spin["score"], target_scores) if ( range_index < 0 or real_score_counts[range_index] >= target_scores[range_index][2] ): continue real_score_counts[range_index] += 1 total_win += spin["score"] total_bet += bet game_spins.append(spin) if len(game_spins) >= 100: self.write_log(game_spins) game_spins = [] index += 1 if len(game_spins) > 0: self.write_log(game_spins) game_spins = [] print(f"旋转{index} 次,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", # "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, # }, # "target_score": [(0,1, 500), # (1,5, 500), # (5,10, 500), # (10,20, 500)], # "scotter_count_weights": scotter_count_weights, # }, # { # "buy_type": "standard", # "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, # "target_score": [(20, 30, 500), # (30, 50, 500), # (50, 100, 500), # (100, 200, 500), # (200, 300, 500), # (300, 400, 500), # (400, 500, 500), # ], # }, { "buy_type": "super", "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, "target_score": [ (80, 120, 500), (120, 200, 500), (200, 400, 500), (400, 600, 500), (800, 1000, 500), (1000, 1200, 500), (1200, 1400, 200), (1400, 1600, 200), (1600, 1800, 200), (1800, 2000, 200), ], }, ] for batch in batchs: sim = SugarRushSimulator(buy_type=batch["buy_type"]) sim.simulate_batch( batch["weights"], batch["scotter_count_weights"], batch["target_score"] )