demo2
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Demo2.Domain
|
||||
{
|
||||
public struct Demo2RuleContext
|
||||
{
|
||||
public long Payload;
|
||||
public long MultiplierMilli;
|
||||
public long Energy;
|
||||
public long Money;
|
||||
public long ExcessFirepower;
|
||||
public int Faults;
|
||||
public bool ThreeSameRecipes;
|
||||
public bool IronFuelAdjacent;
|
||||
public bool BeltBelowEightyPercent;
|
||||
public bool FirstBatch;
|
||||
public bool CoreAtRisk;
|
||||
public int DuplicatedOutputs;
|
||||
|
||||
public long FinalFirepower => SaturatingMath.MultiplyScaled(Payload, MultiplierMilli);
|
||||
}
|
||||
|
||||
public static class Demo2RuleEngine
|
||||
{
|
||||
public static Demo2RuleContext Evaluate(Demo2RuleContext context, IReadOnlyList<Demo2RuleDefinition> orderedRules)
|
||||
{
|
||||
context.MultiplierMilli = context.MultiplierMilli <= 0 ? SaturatingMath.Scale : context.MultiplierMilli;
|
||||
for (var ruleIndex = 0; ruleIndex < orderedRules.Count; ruleIndex++)
|
||||
{
|
||||
var instructions = orderedRules[ruleIndex].Instructions;
|
||||
for (var instructionIndex = 0; instructionIndex < instructions.Count; instructionIndex++)
|
||||
{
|
||||
var instruction = instructions[instructionIndex];
|
||||
if (!Matches(instruction.Condition, context)) continue;
|
||||
Apply(ref context, instruction);
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
public static bool Matches(Demo2RuleCondition condition, in Demo2RuleContext context)
|
||||
{
|
||||
if ((condition & Demo2RuleCondition.ThreeSameRecipes) != 0 && !context.ThreeSameRecipes) return false;
|
||||
if ((condition & Demo2RuleCondition.IronFuelAdjacent) != 0 && !context.IronFuelAdjacent) return false;
|
||||
if ((condition & Demo2RuleCondition.BeltBelowEightyPercent) != 0 && !context.BeltBelowEightyPercent) return false;
|
||||
if ((condition & Demo2RuleCondition.NoFaults) != 0 && context.Faults != 0) return false;
|
||||
if ((condition & Demo2RuleCondition.HasExcessEnergy) != 0 && context.Energy <= 0) return false;
|
||||
if ((condition & Demo2RuleCondition.FirstBatch) != 0 && !context.FirstBatch) return false;
|
||||
if ((condition & Demo2RuleCondition.CoreAtRisk) != 0 && !context.CoreAtRisk) return false;
|
||||
if ((condition & Demo2RuleCondition.HasFaults) != 0 && context.Faults <= 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Apply(ref Demo2RuleContext context, Demo2RuleInstructionData instruction)
|
||||
{
|
||||
switch (instruction.Opcode)
|
||||
{
|
||||
case Demo2RuleOpcode.AddPayload:
|
||||
context.Payload = SaturatingMath.Add(context.Payload, instruction.Operand);
|
||||
break;
|
||||
case Demo2RuleOpcode.MultiplyPayload:
|
||||
context.Payload = SaturatingMath.MultiplyScaled(context.Payload, instruction.Operand);
|
||||
break;
|
||||
case Demo2RuleOpcode.AddMultiplier:
|
||||
context.MultiplierMilli = SaturatingMath.Add(context.MultiplierMilli, instruction.Operand);
|
||||
break;
|
||||
case Demo2RuleOpcode.MultiplyMultiplier:
|
||||
context.MultiplierMilli = SaturatingMath.MultiplyScaled(context.MultiplierMilli, instruction.Operand);
|
||||
break;
|
||||
case Demo2RuleOpcode.ConvertEnergyToPayload:
|
||||
context.Payload = SaturatingMath.Add(context.Payload, SaturatingMath.Multiply(context.Energy, instruction.Operand));
|
||||
context.Energy = 0;
|
||||
break;
|
||||
case Demo2RuleOpcode.AddMoneyFromExcess:
|
||||
context.Money = SaturatingMath.Add(context.Money, context.ExcessFirepower / Math.Max(1, instruction.Operand));
|
||||
break;
|
||||
case Demo2RuleOpcode.DuplicateNextOutput:
|
||||
context.DuplicatedOutputs = SaturatingMath.Add(context.DuplicatedOutputs, (int)instruction.Operand) > int.MaxValue
|
||||
? int.MaxValue
|
||||
: context.DuplicatedOutputs + (int)instruction.Operand;
|
||||
break;
|
||||
case Demo2RuleOpcode.AddFaults:
|
||||
context.Faults = Math.Max(0, context.Faults + (int)instruction.Operand);
|
||||
break;
|
||||
case Demo2RuleOpcode.RepairFaults:
|
||||
context.Faults = Math.Max(0, context.Faults - (int)instruction.Operand);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user