Implement judge report.

This commit is contained in:
2023-01-01 19:00:19 +08:00
parent ca72f7adb5
commit e8f74399f2
2 changed files with 51 additions and 7 deletions

View File

@@ -16,11 +16,12 @@ namespace Cryville.Crtr {
= new Dictionary<Identifier, List<JudgeEvent>>(); = new Dictionary<Identifier, List<JudgeEvent>>();
readonly Dictionary<Identifier, List<JudgeEvent>> activeEvs readonly Dictionary<Identifier, List<JudgeEvent>> activeEvs
= new Dictionary<Identifier, List<JudgeEvent>>(); = new Dictionary<Identifier, List<JudgeEvent>>();
struct JudgeEvent { public struct JudgeEvent {
public double StartTime { get; set; } public double StartTime { get; set; }
public double EndTime { get; set; } public double EndTime { get; set; }
public double StartClip { get; set; } public double StartClip { get; set; }
public double EndClip { get; set; } public double EndClip { get; set; }
public Identifier JudgeId { get; set; }
public JudgeDefinition Definition { get; set; } public JudgeDefinition Definition { get; set; }
public NoteHandler Handler { get; set; } public NoteHandler Handler { get; set; }
} }
@@ -33,20 +34,23 @@ namespace Cryville.Crtr {
public Judge(PdtRuleset rs) { public Judge(PdtRuleset rs) {
_etor = ChartPlayer.etor; _etor = ChartPlayer.etor;
_rs = rs; _rs = rs;
InitJudges();
InitScores(); InitScores();
} }
public void Prepare(double st, double et, Identifier input, JudgeDefinition def, NoteHandler handler) { public void Prepare(double st, double et, Identifier input, Identifier judge, NoteHandler handler) {
List<JudgeEvent> list; List<JudgeEvent> list;
if (!evs.TryGetValue(input, out list)) { if (!evs.TryGetValue(input, out list)) {
ct.Add(input, 0); ct.Add(input, 0);
evs.Add(input, list = new List<JudgeEvent>()); evs.Add(input, list = new List<JudgeEvent>());
activeEvs.Add(input, new List<JudgeEvent>()); activeEvs.Add(input, new List<JudgeEvent>());
} }
var def = _rs.judges[judge];
var ev = new JudgeEvent { var ev = new JudgeEvent {
StartTime = st, StartTime = st,
EndTime = et, EndTime = et,
StartClip = st + def.clip[0], StartClip = st + def.clip[0],
EndClip = et + def.clip[1], EndClip = et + def.clip[1],
JudgeId = judge,
Definition = def, Definition = def,
Handler = handler, Handler = handler,
}; };
@@ -56,6 +60,14 @@ namespace Cryville.Crtr {
} }
#endregion #endregion
#region Judge #region Judge
internal readonly Dictionary<int, int> jtabsMap = new Dictionary<int, int>();
internal readonly Dictionary<int, int> jtrelMap = new Dictionary<int, int>();
void InitJudges() {
foreach (var i in _rs.judges.Keys) {
jtabsMap.Add(i.Key, IdentifierManager.SharedInstance.Request("jtabs_" + i.Name));
jtrelMap.Add(i.Key, IdentifierManager.SharedInstance.Request("jtrel_" + i.Name));
}
}
static bool _flag; static bool _flag;
static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v); static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v);
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn"); static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
@@ -114,7 +126,7 @@ namespace Cryville.Crtr {
else _flag = true; else _flag = true;
if (_flag) { if (_flag) {
if (def.scores != null) UpdateScore(def.scores); if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(def.pass); if (def.pass != null) Pass(ev, (ft + tt) / 2, def.pass);
actlist.RemoveAt(index); actlist.RemoveAt(index);
if (def.prop != 0 && actlist.Count > 0) { if (def.prop != 0 && actlist.Count > 0) {
index = BinarySearchFirst(actlist, (float)ev.StartClip, def.stack - def.prop); index = BinarySearchFirst(actlist, (float)ev.StartClip, def.stack - def.prop);
@@ -126,14 +138,15 @@ namespace Cryville.Crtr {
} }
} }
} }
bool Pass(Identifier[] ids) { bool Pass(JudgeEvent ev, float time, Identifier[] ids) {
foreach (var i in ids) { foreach (var i in ids) {
var def = _rs.judges[i]; var def = _rs.judges[i];
if (def.hit != null) _etor.Evaluate(_flagop, def.hit); if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
else _flag = true; else _flag = true;
if (_flag) { if (_flag) {
if (def.scores != null) UpdateScore(def.scores); if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(def.pass); if (def.pass != null) Pass(ev, time, def.pass);
ev.Handler.ReportJudge(ev, time, i);
return true; return true;
} }
} }
@@ -146,7 +159,7 @@ namespace Cryville.Crtr {
JudgeEvent ev = actlist[i]; JudgeEvent ev = actlist[i];
if (tt > ev.EndClip) { if (tt > ev.EndClip) {
actlist.RemoveAt(i); actlist.RemoveAt(i);
if (ev.Definition.miss != null) Pass(ev.Definition.miss); if (ev.Definition.miss != null) Pass(ev, tt, ev.Definition.miss);
} }
} }
} }

View File

@@ -24,7 +24,32 @@ namespace Cryville.Crtr {
} }
SectionalGameObject[] sgos; SectionalGameObject[] sgos;
readonly Dictionary<Identifier, JudgeState> judges = new Dictionary<Identifier, JudgeState>();
class JudgeState {
public int AbsoluteAnchorName { get; set; }
public int RelativeAnchorName { get; set; }
public bool Judged { get; private set; }
public float AbsoluteTime { get; private set; }
public float RelativeTime { get; private set; }
public JudgeState(NoteHandler handler, int name) {
handler.RegisterAnchor(AbsoluteAnchorName = handler.judge.jtabsMap[name]);
handler.RegisterAnchor(RelativeAnchorName = handler.judge.jtrelMap[name]);
}
public void MarkJudged(float abs, float rel) {
Judged = true;
AbsoluteTime = abs;
RelativeTime = rel;
}
}
public override void PreInit() {
base.PreInit();
foreach (var j in Event.judges) {
if (!judges.ContainsKey(j.Id)) {
judges.Add(j.Id, new JudgeState(this, j.Id.Key));
}
}
}
public override void Init() { public override void Init() {
base.Init(); base.Init();
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>(); sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
@@ -90,7 +115,7 @@ namespace Cryville.Crtr {
ChartPlayer.etor.ContextEvent = tev; ChartPlayer.etor.ContextEvent = tev;
ChartPlayer.etor.ContextState = s; ChartPlayer.etor.ContextState = s;
ChartPlayer.etor.Evaluate(new PropOp.Identifier(v => name = new Identifier(v)), ruleset.judges[tev.Id].input); ChartPlayer.etor.Evaluate(new PropOp.Identifier(v => name = new Identifier(v)), ruleset.judges[tev.Id].input);
judge.Prepare(ev.Time, ev.Time + ev.Duration, name, ruleset.judges[tev.Id], this); judge.Prepare(ev.Time, ev.Time + ev.Duration, name, tev.Id, this);
ChartPlayer.etor.ContextState = null; ChartPlayer.etor.ContextState = null;
ChartPlayer.etor.ContextEvent = null; ChartPlayer.etor.ContextEvent = null;
} }
@@ -166,5 +191,11 @@ namespace Cryville.Crtr {
} }
} }
} }
public void ReportJudge(Judge.JudgeEvent ev, float time, Identifier result) {
JudgeState state;
if (!judges.TryGetValue(ev.JudgeId, out state)) return;
state.MarkJudged(time, (float)(time - cs.Time));
}
} }
} }