Skip to content

Instantly share code, notes, and snippets.

@Young-Lord
Last active May 16, 2022 13:33
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Young-Lord/d4593dc06649338c5515dd88b6c0df17 to your computer and use it in GitHub Desktop.
Save Young-Lord/d4593dc06649338c5515dd88b6c0df17 to your computer and use it in GitHub Desktop.
风暴血条模拟代码
#模拟代码 LY
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
def draw(arr,arr2,qiudao=0,color='black'):#绘图
while qiudao:
arr=[arr[i+1]-arr[i] for i in range(len(arr)-1)]
arr2.pop()
qiudao-=1
for i in arr:
if i>=30:
print(arr.index(i))
#plt.plot(arr2,arr,'o')
plt.plot(arr2, arr, color=color)
getAllHPs=lambda ntc:80+ntc*0.2 if ntc<400 else (32+ntc*0.2 if ntc<600 else 96+ntc*0.08)
#回忆系数算法
class Element:#简化过的ScoreState类
lasttime=0
hit_hps=0
nonhit_hps=0
时长=0
单回忆系数=0
总回忆系数=0
物量=0
上一次的v16=0
HP=0
def __init__(self,时长_,物量_):
self.时长=时长_
self.物量=物量_
self.总回忆系数=getAllHPs(self.物量)
self.单回忆系数=self.总回忆系数/self.物量
print("回忆系数为:",self.单回忆系数)
self.HP=100.0
self.上一次的v16=100-self.总回忆系数 if self.总回忆系数<100 else 0
def handleAction(self,action):#类似performNoteHit
#print("action_type",end=" = ")
assert(action in [0,1,2])
if action==0:#pure
#print("pure")
self.hit_hps+=self.单回忆系数*2
elif action==1:#far
#print("far")
self.hit_hps+=self.单回忆系数
else:#lost
#print("lost")
self.nonhit_hps-=18
offsets=[0, 6, 7, 7, 17, 17, 18, 18, 34, 34, 35, 35, 50, 51, 51, 52, 67, 68, 68, 68, 84, 85, 85, 85]
#别问,问就是616sb
#模拟一秒调用240次函数(仅在未开启高刷的手机上是240/s,开启120fps高刷的手机是480/s)
base = -3000
lst=0
def remove_same(arrr,arrr2):#在连续的重复元素中只保留1个
ans1,ans2=[arrr[0],],[arrr2[0],]
for i in range(1,len(arrr2)):
if arrr2[i]!=ans2[-1]:
ans1.append(arrr[i])
ans2.append(arrr2[i])
return (ans1,ans2)
def fill_average(arrr,arrr2):#将没有数据的部分使用邻近的数的平均值填充(就像两点做直线一样)
t_start,t_end=arrr2[0],arrr2[-1]
t_fix=list(range(t_start,t_end+1))
k_fix=t_fix.copy()
k_fix=[np.nan for kfidsadx in k_fix]
for i in range(len(arrr2)):
k_fix[arrr2[i]-base]=arrr[i]
k_fix=pd.DataFrame(k_fix)
k_fix=k_fix.fillna(k_fix.interpolate())
k_fix=k_fix.values.tolist()
k=[i[0] for i in k_fix];t=[i for i in t_fix]
return(k,t)
def sim(Note数,最后一个元素结束时间,模拟时间=(-3,10),actions=[]):#模拟
global 实例
实例=Element(最后一个元素结束时间+500,Note数)
result,times=[],[]
for i in range(模拟时间[0]*10,模拟时间[1]*10):
for j in offsets:
sim_time=i*100+j
cur=[k[0] for k in actions if (len(times)==0 and k[1]<=sim_time) or (len(times)!=0 and times[-1]<k[1]<=sim_time)]
if len(cur)!=0:
for k in cur:
实例.handleAction(k)
update(sim_time)
result.append(实例.HP)
times.append(sim_time)
#print(实例.nonhit_hps,end=",")
return fill_average(*remove_same(result,times))
def update(当前时间):#全部来自伪代码,注释掉的是貌似没用的
global 实例,lst
两次更新间的秒数 = 0.0
if 实例.lasttime < 当前时间:
两次更新间的秒数 = (当前时间 - 实例.lasttime) / 1000.0
实例.lasttime = 当前时间
v6 = 2 ** (-两次更新间的秒数)
v7 = 2 ** (两次更新间的秒数 * -0.5)
v16 = ((1.0 - v6) * 实例.hit_hps) + ((1.0 - v7) * 实例.nonhit_hps) + 实例.上一次的v16
实例.hit_hps *= 2 ** (-两次更新间的秒数)
实例.nonhit_hps *= 2 ** (两次更新间的秒数 * -0.5)
新HP = 实例.总回忆系数*(1.0-min(当前时间/实例.时长,1.0)) + v16
#实例.unk76 = (新HP - 实例.HP) / 两次更新间的秒数
if 新HP > 100:
v16 -= 新HP - 100
新HP = 100.0
实例.上一次的v16 = v16
实例.HP=新HP
#注意,以下两处的"毫秒"都是指"a2",即“转场的画面开始展开时为-3000,随后每1ms增加1”的值
#使用示例,此处是801个note,谱面最后一个元素位于58612处,在(第50ms打中1个pure),(第150ms打中1个far),(第550ms出现1个lost)的情况
res,模拟时间=sim(801,58612,actions=[(0,50),(1,150),(2,550)])
draw(res,模拟时间,0)#第三个参数是导数的阶数,不填或者填0设为不求导数
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment