Skip to content

Commit

Permalink
修复卡池问题
Browse files Browse the repository at this point in the history
修复卡池问题
  • Loading branch information
H-K-Y committed Nov 23, 2021
1 parent 8fa46ec commit 89f162b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 48 deletions.
71 changes: 57 additions & 14 deletions gacha/gacha.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from PIL import Image
from io import BytesIO
from .pool_data import POOL ,UP_PROBABILITY,POOL_PROBABILITY,DISTANCE_FREQUENCY
from .pool_data import POOL

import os
import random
Expand All @@ -12,7 +12,7 @@



DEFAULT_POOL = "角色up池" # 默认卡池
DEFAULT_POOL = "常驻" # 默认卡池



Expand Down Expand Up @@ -53,6 +53,11 @@ def __init__(self,_pool = DEFAULT_POOL):
# 记录抽卡每个角色或装备各抽到多少
self.gacha_all_statistics = {}

self.up_probability = self.get_up_probability()
self._5_star_basic_probability = self.get_5_star_basic_probability()
self._4_star_basic_probability = self.get_4_star_basic_probability()
self.distance_frequency = self.get_distance_frequency()


@staticmethod
def get_png_path(name):
Expand Down Expand Up @@ -170,19 +175,53 @@ def get_most_arms(self):
return {"name":key,"most":value}



def get_up_probability(self):
# 获取上一次抽卡抽到5星 UP 时,再次获取5星概率是多少
if self.pool == '武器':
return 0.75

return 0.5


def get_5_star_basic_probability(self):
# 获取5星的基础概率
if self.pool == '武器':
return 0.007

return 0.006

def get_4_star_basic_probability(self):
# 获取4星的基础概率
if self.pool == '武器':
return 0.060

return 0.051


def get_distance_frequency(self):
# 获取当前卡池的保底抽卡次数
if self.pool == '武器':
return 80

return 90




def get_5_star(self):
# 先检查上次5星是否是UP,不是UP本次抽取必定是 UP,
# 如果上次是UP,角色UP池本次有50%的概率还是 UP,50%概率非 UP,
# 武器UP池本次有75%的概率还是 UP,25%概率非 UP,详情看UP_PROBABILITY

# 先看是不是常驻池
if self.pool == '常驻池':
if self.pool == '常驻':
return random.choice(POOL[self.pool]['5_star_not_UP'])

# 下边是角色或武器的UP
if self.is_up(self.last_time_5):

if random.random() < UP_PROBABILITY[self.pool]:
if random.random() < self.up_probability:
return random.choice(POOL[self.pool]['5_star_UP'])
else:
return random.choice(POOL[self.pool]['5_star_not_UP'])
Expand All @@ -197,12 +236,12 @@ def get_4_star(self):
# 武器UP池本次有75%的概率还是UP,25%概率非 UP,详情看UP_PROBABILITY

# 先看是不是常驻池
if self.pool == '常驻池':
if self.pool == '常驻':
return random.choice(POOL[self.pool]['4_star_not_UP'])

# 下边是角色或武器的UP
if self.is_up(self.last_time_4):
if random.random() < UP_PROBABILITY[self.pool]:
if random.random() < self.up_probability:
return random.choice(POOL[self.pool]['4_star_UP'])
else:
return random.choice(POOL[self.pool]['4_star_not_UP'])
Expand All @@ -211,21 +250,20 @@ def get_4_star(self):

def get_5_star_probability(self):
# 获取本次抽5星的概率是多少
basic_probability = POOL_PROBABILITY[self.pool]["5"]

if self.pool == '武器up池':
if self.pool == '武器':
# 这是武器up池5星概率
if self.distance_5_star <= 62:
return basic_probability
return self._5_star_basic_probability
else:
return basic_probability + 0.056 * (self.distance_5_star - 62)
return self._5_star_basic_probability + 0.056 * (self.distance_5_star - 62)
else:
# 下边是常驻池和角色UP池
# 这两个保底和概率是相同的所以放在一起
if self.distance_5_star <= 73:
return basic_probability
return self._5_star_basic_probability
else:
return basic_probability + 0.06 * (self.distance_5_star - 73)
return self._5_star_basic_probability + 0.06 * (self.distance_5_star - 73)


def gacha_one(self):
Expand All @@ -241,7 +279,7 @@ def gacha_one(self):
r = random.random()

# 先检查是不是保底5星
if self.distance_5_star % DISTANCE_FREQUENCY[self.pool] == 0:
if self.distance_5_star % self.distance_frequency == 0:
self.gacha_rarity_statistics["5星"] += 1
self.distance_5_star = 0 # 重置保底计数
self.last_time_5 = self.get_5_star() # 抽一次卡,把结果赋值留给下一次抽卡判断
Expand All @@ -263,7 +301,7 @@ def gacha_one(self):

# 检查是不是概率4星
# 由于是先判断5星的概率出货,所以4星的实际概率是4星原概率加上5星的概率
if r < (_5_star_probability + POOL_PROBABILITY[self.pool]["4"]):
if r < (self._5_star_basic_probability + self._4_star_basic_probability):
self.gacha_rarity_statistics["4星"] += 1
self.distance_4_star = 0
self.last_time_4 = self.get_4_star()
Expand All @@ -278,6 +316,8 @@ def gacha_one(self):

def gacha_10(self):
# 抽10连
if not (self.pool in POOL.keys()):
return '当前卡池已结束,请使用 原神卡池切换 切换其他卡池'

gacha_txt = ""

Expand Down Expand Up @@ -317,6 +357,9 @@ def gacha_10(self):

def gacha_90(self,frequency=90):
# 抽一井
if not (self.pool in POOL.keys()):
return '当前卡池已结束,请使用 原神卡池切换 切换其他卡池'

gacha_txt = ""

for self.current_times in range(frequency):
Expand Down
35 changes: 1 addition & 34 deletions gacha/pool_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import re
import os
import json
import time



Expand All @@ -32,19 +31,6 @@
FONT=ImageFont.truetype(FONT_PATH, size=20)


POOL_PROBABILITY = {
# 所有卡池的4星和5星概率,这里直接填写官方给出的概率,程序会自动对4星概率进行累计
"角色up池": {"5": 0.006, "4": 0.051},
"武器up池": {"5": 0.007, "4": 0.060},
"常驻池": {"5": 0.006, "4": 0.051}
}

UP_PROBABILITY = {
# 这里保存的是当UP池第一次抽取到或上次已经抽取过UP时,本次出现UP的概率有多大,常驻池不受影响
"角色up池": 0.5,
"武器up池": 0.75
}

# 这个字典记录的是3个不同的卡池,每个卡池的抽取列表
POOL = collections.defaultdict(
lambda: {
Expand All @@ -55,12 +41,6 @@
'3_star_not_UP': []
})

DISTANCE_FREQUENCY = {
# 3个池子的5星是多少发才保底
'角色up池': 90,
'武器up池': 80,
'常驻池': 90
}



Expand Down Expand Up @@ -236,27 +216,14 @@ async def init_pool_list():

ROLES_HTML_LIST = None
ARMS_HTML_LIST = None

# fix: #61
POOL.clear()

logger.info(f"正在更新卡池数据")
data = await get_url_data(POOL_API)
data = json.loads(data.decode("utf-8"))
for d in data["data"]["list"]:

begin_time = time.mktime(time.strptime(d['begin_time'],"%Y-%m-%d %H:%M:%S"))
end_time = time.mktime(time.strptime(d['end_time'],"%Y-%m-%d %H:%M:%S"))
if not (begin_time < time.time() < end_time):
continue

if str(d['gacha_type']) == "301":
pool_name = '角色up池'
elif str(d['gacha_type']) == "302":
pool_name = '武器up池'
else:
pool_name = '常驻池'

pool_name = str(d['gacha_name'])
pool_url = f"https://webstatic.mihoyo.com/hk4e/gacha_info/cn_gf01/{d['gacha_id']}/zh-cn.json"
pool_data = await get_url_data(pool_url)
pool_data = json.loads(pool_data.decode("utf-8"))
Expand Down

0 comments on commit 89f162b

Please sign in to comment.