140 lines
4.3 KiB
C#
140 lines
4.3 KiB
C#
using Cryville.Common;
|
|
using Cryville.Common.Pdt;
|
|
using Cryville.Crtr.Event;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Cryville.Crtr {
|
|
public class Judge {
|
|
readonly PdtEvaluator _etor;
|
|
readonly PdtRuleset _rs;
|
|
readonly Dictionary<Identifier, float> ct
|
|
= new Dictionary<Identifier, float>();
|
|
readonly Dictionary<Identifier, List<JudgeEvent>> evs
|
|
= new Dictionary<Identifier, List<JudgeEvent>>();
|
|
readonly Dictionary<Identifier, List<JudgeEvent>> activeEvs
|
|
= new Dictionary<Identifier, List<JudgeEvent>>();
|
|
struct JudgeEvent {
|
|
public float StartTime { get; set; }
|
|
public float EndTime { get; set; }
|
|
public JudgeDefinition Definition { get; set; }
|
|
public ContainerState State { get; set; }
|
|
}
|
|
static readonly IComparer<JudgeEvent> _stcmp = new JudgeEventStartTimeComparer();
|
|
class JudgeEventStartTimeComparer : IComparer<JudgeEvent> {
|
|
public int Compare(JudgeEvent x, JudgeEvent y) {
|
|
return x.StartTime.CompareTo(y.StartTime);
|
|
}
|
|
}
|
|
static readonly IComparer<JudgeEvent> _etcmp = new JudgeEventEndTimeComparer();
|
|
class JudgeEventEndTimeComparer : IComparer<JudgeEvent> {
|
|
public int Compare(JudgeEvent x, JudgeEvent y) {
|
|
return x.EndTime.CompareTo(y.EndTime);
|
|
}
|
|
}
|
|
public Judge(PdtRuleset rs) {
|
|
_etor = ChartPlayer.etor;
|
|
_rs = rs;
|
|
foreach (var s in rs.scores) {
|
|
var name = s.Key.Key;
|
|
scoreDefs.Add(name, s.Value);
|
|
scores.Add(name, s.Value.init);
|
|
}
|
|
}
|
|
public void Prepare(float st, float et, Identifier input, JudgeDefinition def, ContainerState container) {
|
|
List<JudgeEvent> list;
|
|
if (!evs.TryGetValue(input, out list)) {
|
|
ct.Add(input, 0);
|
|
evs.Add(input, list = new List<JudgeEvent>());
|
|
activeEvs.Add(input, new List<JudgeEvent>());
|
|
}
|
|
var ev = new JudgeEvent {
|
|
StartTime = st + def.clip[0],
|
|
EndTime = et + def.clip[1],
|
|
Definition = def,
|
|
State = container,
|
|
};
|
|
var index = list.BinarySearch(ev, _stcmp);
|
|
if (index < 0) index = ~index;
|
|
list.Insert(index, ev);
|
|
}
|
|
public void Feed(Identifier target, float ft, float tt) {
|
|
Forward(target, tt);
|
|
var actlist = activeEvs[target];
|
|
foreach (var ev in actlist) {
|
|
// TODO judge ev
|
|
}
|
|
}
|
|
public void Cleanup(Identifier target, float ft, float tt) {
|
|
Forward(target, tt);
|
|
var actlist = activeEvs[target];
|
|
for (int i = actlist.Count - 1; i >= 0; i--) {
|
|
JudgeEvent ev = actlist[i];
|
|
if (tt > ev.EndTime) {
|
|
actlist.RemoveAt(i);
|
|
// TODO miss ev
|
|
}
|
|
}
|
|
}
|
|
void Forward(Identifier target, float tt) {
|
|
var list = evs[target];
|
|
var actlist = activeEvs[target];
|
|
JudgeEvent ev;
|
|
while (list.Count > 0 && (ev = list[0]).StartTime <= tt) {
|
|
list.RemoveAt(0);
|
|
var index = actlist.BinarySearch(ev, _etcmp);
|
|
if (index < 0) index = ~index;
|
|
actlist.Insert(index, ev);
|
|
// TODO priority?
|
|
}
|
|
}
|
|
public readonly Dictionary<int, ScoreDefinition> scoreDefs = new Dictionary<int, ScoreDefinition>();
|
|
public readonly Dictionary<int, float> scores = new Dictionary<int, float>();
|
|
readonly Dictionary<int, string> ScoreCache = new Dictionary<int, string>();
|
|
readonly object _lock = new object();
|
|
public Dictionary<int, string> GetFormattedScoreStrings() {
|
|
lock (_lock) {
|
|
if (ScoreCache.Count == 0) {
|
|
foreach (var s in scores)
|
|
ScoreCache.Add(s.Key, s.Value.ToString(scoreDefs[s.Key].format));
|
|
}
|
|
return ScoreCache;
|
|
}
|
|
}
|
|
public string GetFullFormattedScoreString() {
|
|
bool flag = false;
|
|
string result = "";
|
|
foreach (var s in GetFormattedScoreStrings()) {
|
|
result += string.Format(flag ? "\n{0}: {1}" : "{0}: {1}", IdentifierManager.SharedInstance.Retrieve(s.Key), s.Value);
|
|
flag = true;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
public class InputDefinition {
|
|
public int dim;
|
|
public bool notnull;
|
|
public Dictionary<Identifier, PdtExpression> pass;
|
|
}
|
|
public class JudgeDefinition {
|
|
public float[] clip;
|
|
public PdtExpression input;
|
|
public PdtExpression hit;
|
|
public Identifier[] pass;
|
|
public Identifier miss;
|
|
public Dictionary<ScoreOperation, PdtExpression> scores;
|
|
}
|
|
public class ScoreOperation {
|
|
public Identifier name;
|
|
public Identifier op;
|
|
public override string ToString() {
|
|
if (op == default(Identifier)) return name.ToString();
|
|
else return string.Format("{0} {1}", name, op);
|
|
}
|
|
}
|
|
public class ScoreDefinition {
|
|
public PdtExpression value;
|
|
public float init = 0;
|
|
public string format = "";
|
|
}
|
|
}
|