Last active
May 16, 2022 13:33
-
-
Save Young-Lord/d4593dc06649338c5515dd88b6c0df17 to your computer and use it in GitHub Desktop.
风暴血条模拟代码
This file contains 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
#模拟代码 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