Skip to content

Commit 6e4b454

Browse files
committed
[F] 对着测试修MA2转Simai的bug
1 parent a4b84d0 commit 6e4b454

4 files changed

Lines changed: 27 additions & 22 deletions

File tree

generator/SimaiGenerator.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,11 @@ private string DurationStr(Rational start, Duration duration)
125125

126126
// 遍历音符,生成SimaiNote中间表示(时间还是Rational、但音符内容已转为字符串),存入buf中
127127
int noteIdx = 0;
128-
while (noteIdx < chart.Notes.Count)
129-
{
130-
var note = chart.Notes[noteIdx];
128+
while (noteIdx < chart.Notes.Count || bpmIdx < chart.BpmList.Count)
129+
{ // 只要有音符没写入或bpm标记没写入,就继续
130+
// 如果noteIdx 不< chart.Notes.Count,还能走到这里的话一定是因为bpm还没写入完(bpmIdx < chart.BpmList.Count)。
131+
// 此时只要让time是一个特别大的数,确保下面的time >= chart.BpmList[bpmIdx].Time的逻辑能触发,就可以了。
132+
var note = noteIdx < chart.Notes.Count ? chart.Notes[noteIdx] : new Tap(null!, 999999999);
131133
var time = note.Time;
132134

133135
// 先看是否引发bpm change,如果是的话,则本次循环只结算这个bpm change

parser/MA2Parser.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ private void WarnParamsCount(int lineNo, ReadOnlySpan<char> line, Rational? time
8080
}
8181
else if (cmd == "MET" && values.Length == 5 && int.TryParse(values[1], out var _) && int.TryParse(values[2], out var _)
8282
&& int.TryParse(values[3], out var _) && int.TryParse(values[4], out var _)) {} // MET不需要解析,忽略之
83+
else if (cmd == "SEF") {} // SEF不需要解析,忽略之
8384
// 读到了统计段,后面就不用读了,谱面解析结束
8485
else if (cmd.StartsWith("T_REC") || cmd.StartsWith("T_NUM") || cmd.StartsWith("T_JUDGE") || cmd.StartsWith("TTM_"))
8586
{

tests/testset/官谱/系ぎて [DX]/maidata.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
{4}5/6,5/6,7/8,7/8,
9595
{4}5/6,3/4,1/2,7/8,
9696
(78.8){4}7xh[384:953]/8x,,(58.8),C1h[48:59],
97-
{1},
97+
(68.8),,(58.8),(48.8),
9898
{1},
9999
{1},
100100
{1},
@@ -181,7 +181,7 @@ E
181181
{8}3,2,1,8,7,6,4/5,,
182182
{8}5,6,7,8,1,2,3,4,
183183
(78.8){2}4xh[384:953]/5xh[384:953],(58.8),
184-
{1},
184+
(68.8),(58.8){4},(48.8),
185185
{1},
186186
{1},
187187
{1},

tests/官谱转Simai测试.cs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public static IEnumerable<object[]> AllLevels()
3333
var maidataTxt = File.ReadAllText(maidataPath, Encoding.UTF8);
3434
var maidata = new Maidata(maidataTxt);
3535
foreach (var id in maidata.Levels.Keys.OrderBy(k => k))
36+
// if (maidataPath.Contains("系ぎて") && id == 3)
3637
yield return [new TestInput(maidataPath, id)];
3738
}
3839
}
@@ -108,15 +109,15 @@ static IEnumerable<Entry> Canon(IReadOnlyList<Entry> e) =>
108109
Assert.Equal(expected[i].Time, actual[i].Time);
109110
AssertNoteEqual(expected[i].Text, actual[i].Text, i, actual[i].Time, chart);
110111
}
111-
catch (Xunit.Sdk.XunitException e)
112+
catch (Xunit.Sdk.XunitException)
112113
{
113114
output?.WriteLine(FormatNeighborhood(expected, actual, i).TrimEnd());
114115
throw;
115116
}
116117
}
117118
}
118119

119-
[GeneratedRegex(@"\[(?:(\d+):(\d+)|(?:([\d\.]+)#)?#([\d\.]+))\]")]
120+
[GeneratedRegex(@"\[(?:([\d\.]+)##)?(?:(\d+):(\d+)|#?([\d\.]+))\]")]
120121
private static partial Regex DurationStrRegex();
121122

122123
private static bool Near(double a, double b) => Math.Abs(a - b) < 1e-3;
@@ -139,28 +140,29 @@ private static void AssertNoteEqual(string expected, string actual, int noteIdx,
139140
var expTime = DurationStrRegex().Match(exp);
140141
var actTime = DurationStrRegex().Match(act);
141142
var bpm = chart.BpmList.Find(time).Bpm;
142-
if (expTime.Groups[1].Success && actTime.Groups[4].Success)
143+
if (expTime.Groups[2].Success && actTime.Groups[4].Success)
143144
{ // exp中是分数时间、act中是小数时间的情况
144145
// 小数时间化为分数时间,看看是否对的上
145-
var numer = decimal.Parse(actTime.Groups[4].Value) / (240 / bpm) * int.Parse(expTime.Groups[1].Value);
146-
if (Math.Round(numer) == int.Parse(expTime.Groups[2].Value)) result = true; // 如果对的上,则不判定为比较失败
147-
if (actTime.Groups[3].Success)
148-
{ // 如果写了等待时间的话,等待时间必须为1拍
149-
var oneBeatSec = 60 / (Rational)bpm;
150-
if (!Near(double.Parse(actTime.Groups[3].Value), (double)oneBeatSec)) result = false; // 如果等待时间对不上,则仍判定为比较失败
151-
}
146+
var numer = decimal.Parse(actTime.Groups[4].Value) / (240 / bpm) * int.Parse(expTime.Groups[2].Value);
147+
if (Math.Round(numer) == int.Parse(expTime.Groups[3].Value)) result = true; // 如果对的上,则不判定为比较失败
152148
}
153-
else if (actTime.Groups[1].Success && expTime.Groups[4].Success)
149+
else if (actTime.Groups[2].Success && expTime.Groups[4].Success)
154150
{ // exp中是小数时间、act中是分数时间的情况
155151
// 分数时间化为小数时间,看是否对的上(差距<1ms)
156-
var sec = new Rational(int.Parse(actTime.Groups[2].Value), int.Parse(actTime.Groups[1].Value)) * (240 / (Rational)bpm);
152+
var sec = new Rational(int.Parse(actTime.Groups[3].Value), int.Parse(actTime.Groups[2].Value)) * (240 / (Rational)bpm);
157153
if (Near((double)sec, double.Parse(expTime.Groups[4].Value))) result = true; // 如果对的上,则不判定为比较失败
158-
if (expTime.Groups[3].Success)
159-
{ // 如果写了等待时间的话,等待时间必须为1拍
160-
var oneBeatSec = 60 / (Rational)bpm;
161-
if (!Near(double.Parse(expTime.Groups[3].Value), (double)oneBeatSec)) result = false; // 如果等待时间对不上,则仍判定为比较失败
162-
}
163154
}
155+
else if (actTime.Groups[4].Success && expTime.Groups[4].Success)
156+
{ // exp中是小数时间、act中是小数时间的情况
157+
var expSec = double.Parse(expTime.Groups[4].Value);
158+
var actSec = double.Parse(actTime.Groups[4].Value);
159+
if (Near(expSec, actSec)) result = true; // 如果对的上,则不判定为比较失败
160+
}
161+
162+
// 比较等待时间是否相等(没显式写出的就是1拍)
163+
var expWait = expTime.Groups[1].Success ? double.Parse(expTime.Groups[1].Value) : 60 / (double)bpm;
164+
var actWait = actTime.Groups[1].Success ? double.Parse(actTime.Groups[1].Value) : 60 / (double)bpm;
165+
if (!Near(expWait, actWait)) result = false; // 如果等待时间对不上,则仍判定为比较失败
164166
}
165167

166168
if (!result) Assert.Fail(

0 commit comments

Comments
 (0)