(记一个谱子总Note数为N)
1.评分(90w基础分+10w连击分)
基础分每权重为90w/N
连击分每权重为10w/(1+2+...+N-1)
2.TP(Technique Point:技巧点)(也就是准度)
TP每权重为(100%)/N
Note判定分级 :
名称:基础分权重, TP权重, 判定区间
彩P: 1 1 0~0.07s
黑P: 1 0.7 0.07~0.2s
Good: 0.3 0.3 0.2~0.4s
Bad: 0.3 0 0.4~0.8s
Miss: 0 0 /
关于连击分 :
萌娘百科和百度贴吧上某大佬的说法有误(至少在现版本是这样), 实际上是:
一段Combo的首个Note被赋予的连击分权重为0.
相应的, 连击分被分为(1+2+...+N-1)份, 而不是(1+2+...+N)份, 一份即一个权重.
在一段Combo中, 各Note按0,1,2,3...依次赋予权重.
断连后, 下一组Combo重新依次被赋予权重.
关于我发现Combo首项被赋予0权重这回事 :
在我试图用我只掌握皮毛的C语言知识, 写一个计算只断一次Combo时漏掉的Note是第几个的程序时, 经过几次调试, 却一直得不出正确的结果. 我开始怀疑萌娘百科的算法, 写了一个模拟MM时击打
各Note后, 分数变化的程序进行验证, 发现与实际情况误差很大, 我尝试更改算法, 发现更改后误差不超过1.
模拟MM计分的程序如下:
#include<stdio.h>
main()
{
int i, N; float a,b,s;
printf("物量:");
scanf_s("%d", &N);
a = 900000.0/ N;
b= 100000.0 / ( N-1.0) / N * 2;
printf("基础分每权重:%f\n连击分每权重:%f\n",a,b);
for (s = 0, i= 1; i <= N; i++)
{
s+= a + b * (i-1);
printf("%d %f\n",i,s);
}
}
验证如下:
比如, 在46Combo时, 的确是270370.
关于我写的一个简单的C语言程序 :
这个程序在输入TP的值,Perfect,Good,Bad,Miss的个数后, 可以计算彩P黑P的个数, 计算FC时的得分, 判断评分等级(非FC情况下要另外输入得分), 计算基础分连击分, 在性歌(只断连一次)的情况下计算是第几个Note断了.程序如下:
#include<stdio.h>
int s(int p, int g, int b, float N)
{
return (90e4 / N) * (p + (g + b) *0.3);
}
int gr(int s)
{
if (s == 100e4)
printf("评级 :MM");
if (95e4 <= s && s < 100e4)
printf("评级:S");
if (90e4 <= s && s < 95e4)
printf("评级:A");
if (80e4 <= s && s < 90e4)
printf("评级:B");
if (70e4 <= s && s < 80e4)
printf("评级:C");
if (s < 70e4)
printf("评级:Failed");
printf("\n");
return 0;
}
int combo(int c,int N)
{
int i, s;
for (i = 0, s = 0; i <= N - 1; i++)
{
(int)s = 100000.0 / (N - 1.0) / N * ((i - 1.0) * i + (N - i - 2.0) * (N - 1.0 - i));
if (s == c || s == c + 1 || s == c - 1)//存在不超过1的误差,只能这样处理了QAQ
break;
}
printf("可能在第%d或%d个note处断连\n", i+1,N-i);
return 0;
}
int main()
{
float tp, a, N;
int p, g, b, m, cp, hp;
printf("TP:");
scanf_s("%f", &tp);
printf("Perfect:");
scanf_s("%d", &p);
printf("Good:");
scanf_s("%d", &g);
printf("Bad:");
scanf_s("%d", &b);
printf("Miss:");
scanf_s("%d", &m);
N = p + g + b + m;
a = 100 / N;
hp = -((tp - 1.0*a * g * 0.3) / a - p) / 0.3;
cp = p - hp;
printf("彩Perfect数目:%d\n黑Perfect数目:%d\n", cp, hp);
switch ((g == 0) + (b == 0) * 2 + (m == 0) * 4)
{
case 7 ://MM
printf("得分:1000000\n基础分:900000\n连击分:100000\n");
gr(100e4);
if (tp != 100)printf("恭喜达成MM");
else printf("恭喜椰叶杀歌辣!");
break;
case 6://FC
{int s1;
s1 = s(p, g, b, N) + 10e4;
printf("得分:%d\n基础分:%d\n连击分:100000\n", s1,s(p, g, b, N));
gr(s1);
printf("恭喜达成FC");
break; }
case 5:
case 4://good?,bad= 0,miss!=0
{int s2,c2;
printf("得分:");
scanf_s("%d", &s2);
c2 = s2 - s(p, g, b, N);
printf("基础分:%d\n连击分:%d\n",s(p, g, b, N),c2);
gr(s2);
if (b == 1)
{
printf("恭喜获得成就:每日一性\n");
combo(c2, N);
}
break;
}
case 3:
case 2://good?,bad!=0,miss==0
{int s3,c3;
printf("得分:");
scanf_s("%d", &s3);
c3 = s3 - s(p, g, b, N);
printf("基础分:%d\n连击分:%d\n", s(p, g, b, N),c3);
gr(s3);
if (m == 1)
{
printf("恭喜获得成就:每日一性\n");
combo(c3, N);
}
break; }
case 1:
case 0://good?,bad!=0,miss!=0
{int s4,c4;
printf("得分:");
scanf_s("%d", &s4);
c4 = s4 - s(p, g, b, N);
printf("基础分:%d\n连击分:%d\n", s(p, g, b, N),c4);
gr(s4);
printf("恭喜获得成就:又菜又爱玩"); }
}
return 0;
}
总结 :
写这些程序对于C语言新手和Cy2玩家来说, 难度不大也很有意思, 同时能练习一下所学知识, 于是我就这么做了.
PS: 明天C语言考试, 恐慌...