using Cryville.Common; using Cryville.Common.Pdt; using System; using System.Collections.Generic; using System.Linq; namespace Cryville.Crtr.Ruleset { internal struct JudgeActionResult { public bool BreakExecution; public bool PreventRecycle; } public abstract class JudgeAction { public static JudgeAction Construct(HashSet a, string k) { if (a.Remove("pass")) { return new Pass(a, from i in k.Split(',') select new Identifier(i.Trim())); } else if (a.Remove("call")) { return new Call(a, new Identifier(k)); } else if (a.Remove("score")) { return new Score(a, k); } else if (a.Remove("var")) { return new Variable(a, new Identifier(k)); } throw new FormatException("Invalid judge action format."); } public readonly HashSet annotations; public JudgeAction(IEnumerable a) { annotations = a.ToHashSet(); } public virtual void Optimize(PdtEvaluatorBase etor, PdtExpression value) { etor.Optimize(value); } internal abstract JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index); public class Call : JudgeAction { readonly Identifier _target; public Call(IEnumerable a, Identifier k) : base(a) { _target = k; } internal override JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index) { judge.Call(ev, time, _target, onMiss, index); return new JudgeActionResult { BreakExecution = true, PreventRecycle = true }; } } public class Pass : JudgeAction { readonly Identifier[] _targets; public Pass(IEnumerable a, IEnumerable k) : base(a) { _targets = k.ToArray(); } internal override JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index) { return new JudgeActionResult { BreakExecution = judge.Pass(ev, time, _targets, onMiss, depth) }; } } public class Score : JudgeAction { readonly ScoreOperation _op; public Score(IEnumerable a, string k) : base(a) { _op = new ScoreOperation(k); } public Score(ScoreOperation op) : base(Enumerable.Empty()) { _op = op; } public override void Optimize(PdtEvaluatorBase etor, PdtExpression value) { base.Optimize(etor, value); if (_op.op != default) PdtExpression.PatchCompound(_op.name.Key, _op.op.Key, value); } internal override JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index) { judge.UpdateScore(_op, exp); return new JudgeActionResult(); } } public class Variable : JudgeAction { readonly Identifier _target; public Variable(IEnumerable a, Identifier k) : base(a) { _target = k; } internal override JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index) { // throw new NotImplementedException(); return new JudgeActionResult(); } } } }