Update solver scoring; remove byregot adjustment
This commit is contained in:
+85
-128
@@ -1,18 +1,30 @@
|
|||||||
using Craftimizer.Simulator;
|
using Craftimizer.Simulator;
|
||||||
using Craftimizer.Simulator.Actions;
|
using Craftimizer.Simulator.Actions;
|
||||||
using Craftimizer.Solver;
|
using Craftimizer.Solver;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Craftimizer.Benchmark;
|
namespace Craftimizer.Benchmark;
|
||||||
|
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
private static async Task Main(string[] args)
|
private static Task Main(string[] args)
|
||||||
{
|
{
|
||||||
#if !IS_TRACE
|
#if !IS_TRACE
|
||||||
|
RunBench(args);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
#else
|
||||||
|
return RunTrace();
|
||||||
|
#endif
|
||||||
|
// return RunOther();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RunBench(string[] args)
|
||||||
|
{
|
||||||
Environment.SetEnvironmentVariable("IS_BENCH", "1");
|
Environment.SetEnvironmentVariable("IS_BENCH", "1");
|
||||||
BenchmarkDotNet.Running.BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
|
BenchmarkDotNet.Running.BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
|
||||||
#else
|
}
|
||||||
|
|
||||||
|
private static async Task RunTrace()
|
||||||
|
{
|
||||||
var input = new SimulationInput(
|
var input = new SimulationInput(
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
@@ -43,143 +55,88 @@ internal static class Program
|
|||||||
var config = new SolverConfig()
|
var config = new SolverConfig()
|
||||||
{
|
{
|
||||||
Algorithm = SolverAlgorithm.Stepwise,
|
Algorithm = SolverAlgorithm.Stepwise,
|
||||||
Iterations = 30000
|
Iterations = 30000,
|
||||||
|
MaxStepCount = 25
|
||||||
};
|
};
|
||||||
var solver = new Solver.Solver(config, new(input));
|
var solver = new Solver.Solver(config, new(input));
|
||||||
solver.OnNewAction += s => Console.WriteLine($">{s}");
|
solver.OnNewAction += s => Console.WriteLine($">{s}");
|
||||||
solver.Start();
|
solver.Start();
|
||||||
var (_, s) = await solver.GetTask().ConfigureAwait(false);
|
var (_, s) = await solver.GetTask().ConfigureAwait(false);
|
||||||
Console.WriteLine($"Qual: {s.Quality}/{s.Input.Recipe.MaxQuality}");
|
Console.WriteLine($"Qual: {s.Quality}/{s.Input.Recipe.MaxQuality}");
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
|
|
||||||
////TypeLayout.PrintLayout<ArenaNode<SimulationNode>>(true);
|
|
||||||
////return;
|
|
||||||
|
|
||||||
//var input = new SimulationInput(
|
|
||||||
// new CharacterStats
|
|
||||||
// {
|
|
||||||
// Craftsmanship = 4078,
|
|
||||||
// Control = 3897,
|
|
||||||
// CP = 704,
|
|
||||||
// Level = 90,
|
|
||||||
// CanUseManipulation = true,
|
|
||||||
// HasSplendorousBuff = false,
|
|
||||||
// IsSpecialist = false,
|
|
||||||
// CLvl = 560,
|
|
||||||
// },
|
|
||||||
// new RecipeInfo()
|
|
||||||
// {
|
|
||||||
// IsExpert = false,
|
|
||||||
// ClassJobLevel = 90,
|
|
||||||
// RLvl = 640,
|
|
||||||
// ConditionsFlag = 15,
|
|
||||||
// MaxDurability = 70,
|
|
||||||
// MaxQuality = 14040,
|
|
||||||
// MaxProgress = 6600,
|
|
||||||
// QualityModifier = 70,
|
|
||||||
// QualityDivider = 115,
|
|
||||||
// ProgressModifier = 80,
|
|
||||||
// ProgressDivider = 130,
|
|
||||||
// }
|
|
||||||
//);
|
|
||||||
|
|
||||||
//var config = new SolverConfig()
|
|
||||||
//{
|
|
||||||
// Iterations = 100_000,
|
|
||||||
// ForkCount = 32,
|
|
||||||
// FurcatedActionCount = 16,
|
|
||||||
// MaxStepCount = 30,
|
|
||||||
//};
|
|
||||||
|
|
||||||
//var sim = new SimulatorNoRandom(new(input));
|
|
||||||
//(_, var state) = sim.Execute(new(input), ActionType.MuscleMemory);
|
|
||||||
//(_, state) = sim.Execute(state, ActionType.PrudentTouch);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Manipulation);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Veneration);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.WasteNot);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Groundwork);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Groundwork);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Groundwork);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Innovation);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.PrudentTouch);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.AdvancedTouchCombo);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Manipulation);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Innovation);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.PrudentTouch);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.AdvancedTouchCombo);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.GreatStrides);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.Innovation);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.FocusedTouchCombo);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.GreatStrides);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.ByregotsBlessing);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.CarefulSynthesis);
|
|
||||||
////(_, state) = sim.Execute(state, ActionType.CarefulSynthesis);
|
|
||||||
|
|
||||||
//Console.WriteLine($"{state.Quality} {state.CP} {state.Progress} {state.Durability}");
|
|
||||||
////return;
|
|
||||||
//var solver = new Solver.Solver(config, state);
|
|
||||||
//solver.OnLog += Console.WriteLine;
|
|
||||||
//solver.OnNewAction += s => Console.WriteLine(s);
|
|
||||||
//solver.Start();
|
|
||||||
//var (_, s) = await solver.GetTask().ConfigureAwait(false);
|
|
||||||
//Console.WriteLine($"Qual: {s.Quality}/{s.Input.Recipe.MaxQuality}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Benchmark(Func<SolverSolution> search)
|
private static async Task RunOther()
|
||||||
{
|
{
|
||||||
var s = Stopwatch.StartNew();
|
//TypeLayout.PrintLayout<ArenaNode<SimulationNode>>(true);
|
||||||
List<int> q = new();
|
//return;
|
||||||
for (var i = 0; i < 15; ++i)
|
|
||||||
|
var input = new SimulationInput(
|
||||||
|
new CharacterStats
|
||||||
|
{
|
||||||
|
Craftsmanship = 4078,
|
||||||
|
Control = 3897,
|
||||||
|
CP = 704,
|
||||||
|
Level = 90,
|
||||||
|
CanUseManipulation = true,
|
||||||
|
HasSplendorousBuff = false,
|
||||||
|
IsSpecialist = false,
|
||||||
|
CLvl = 560,
|
||||||
|
},
|
||||||
|
new RecipeInfo()
|
||||||
|
{
|
||||||
|
IsExpert = false,
|
||||||
|
ClassJobLevel = 90,
|
||||||
|
RLvl = 640,
|
||||||
|
ConditionsFlag = 15,
|
||||||
|
MaxDurability = 70,
|
||||||
|
MaxQuality = 14040,
|
||||||
|
MaxProgress = 6600,
|
||||||
|
QualityModifier = 70,
|
||||||
|
QualityDivider = 115,
|
||||||
|
ProgressModifier = 80,
|
||||||
|
ProgressDivider = 130,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var config = new SolverConfig()
|
||||||
{
|
{
|
||||||
var state = search().State;
|
Iterations = 100_000,
|
||||||
//Console.WriteLine($"Qual: {state.Quality}/{state.Input.Recipe.MaxQuality}");
|
ForkCount = 32,
|
||||||
|
FurcatedActionCount = 16,
|
||||||
q.Add(state.Quality);
|
MaxStepCount = 30,
|
||||||
}
|
|
||||||
|
|
||||||
s.Stop();
|
|
||||||
Console.WriteLine($"{s.Elapsed.TotalMilliseconds / 60:0.00}ms/cycle");
|
|
||||||
Console.WriteLine(string.Join(',', q));
|
|
||||||
q.Sort();
|
|
||||||
Console.WriteLine($"Min: {Quartile(q, 0)}, Max: {Quartile(q, 4)}, Avg: {Quartile(q, 2)}, Q1: {Quartile(q, 1)}, Q3: {Quartile(q, 3)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/31536435
|
|
||||||
private static float Quartile(List<int> input, int quartile)
|
|
||||||
{
|
|
||||||
float dblPercentage = quartile switch
|
|
||||||
{
|
|
||||||
0 => 0, // Smallest value in the data set
|
|
||||||
1 => 25, // First quartile (25th percentile)
|
|
||||||
2 => 50, // Second quartile (50th percentile)
|
|
||||||
3 => 75, // Third quartile (75th percentile)
|
|
||||||
4 => 100, // Largest value in the data set
|
|
||||||
_ => 0,
|
|
||||||
};
|
};
|
||||||
if (dblPercentage >= 100) return input[^1];
|
|
||||||
|
|
||||||
var position = (input.Count + 1) * dblPercentage / 100f;
|
var sim = new SimulatorNoRandom(new(input));
|
||||||
var n = (dblPercentage / 100f * (input.Count - 1)) + 1;
|
(_, var state) = sim.Execute(new(input), ActionType.MuscleMemory);
|
||||||
|
(_, state) = sim.Execute(state, ActionType.PrudentTouch);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Manipulation);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Veneration);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.WasteNot);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Groundwork);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Groundwork);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Groundwork);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Innovation);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.PrudentTouch);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.AdvancedTouchCombo);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Manipulation);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Innovation);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.PrudentTouch);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.AdvancedTouchCombo);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.GreatStrides);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.Innovation);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.FocusedTouchCombo);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.GreatStrides);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.ByregotsBlessing);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.CarefulSynthesis);
|
||||||
|
//(_, state) = sim.Execute(state, ActionType.CarefulSynthesis);
|
||||||
|
|
||||||
float leftNumber, rightNumber;
|
Console.WriteLine($"{state.Quality} {state.CP} {state.Progress} {state.Durability}");
|
||||||
if (position >= 1)
|
//return;
|
||||||
{
|
var solver = new Solver.Solver(config, state);
|
||||||
leftNumber = input[(int)MathF.Floor(n) - 1];
|
solver.OnLog += Console.WriteLine;
|
||||||
rightNumber = input[(int)MathF.Floor(n)];
|
solver.OnNewAction += s => Console.WriteLine(s);
|
||||||
}
|
solver.Start();
|
||||||
else
|
var (_, s) = await solver.GetTask().ConfigureAwait(false);
|
||||||
{
|
Console.WriteLine($"Qual: {s.Quality}/{s.Input.Recipe.MaxQuality}");
|
||||||
leftNumber = input[0]; // first data
|
|
||||||
rightNumber = input[1]; // first data
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leftNumber == rightNumber)
|
|
||||||
return leftNumber;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var part = n - MathF.Floor(n);
|
|
||||||
return leftNumber + (part * (rightNumber - leftNumber));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<IsTestProject>true</IsTestProject>
|
<IsTestProject>true</IsTestProject>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release;Trace</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -27,4 +27,9 @@
|
|||||||
<DefineConstants>$(DefineConstants);IS_DETERMINISTIC</DefineConstants>
|
<DefineConstants>$(DefineConstants);IS_DETERMINISTIC</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)'=='Trace'">
|
||||||
|
<Optimize>True</Optimize>
|
||||||
|
<DefineConstants>$(DefineConstants);IS_DETERMINISTIC;IS_TRACE</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -89,33 +89,47 @@ public class ActionSetTests
|
|||||||
|
|
||||||
Assert.AreEqual(4, set.Count);
|
Assert.AreEqual(4, set.Count);
|
||||||
|
|
||||||
|
#if !IS_TRACE
|
||||||
Assert.AreEqual(ActionType.DelicateSynthesis, set.ElementAt(0));
|
Assert.AreEqual(ActionType.DelicateSynthesis, set.ElementAt(0));
|
||||||
Assert.AreEqual(ActionType.FocusedTouch, set.ElementAt(1));
|
Assert.AreEqual(ActionType.FocusedTouch, set.ElementAt(1));
|
||||||
Assert.AreEqual(ActionType.ByregotsBlessing, set.ElementAt(2));
|
Assert.AreEqual(ActionType.ByregotsBlessing, set.ElementAt(2));
|
||||||
Assert.AreEqual(ActionType.BasicSynthesis, set.ElementAt(3));
|
Assert.AreEqual(ActionType.BasicSynthesis, set.ElementAt(3));
|
||||||
|
#else
|
||||||
|
Assert.AreEqual(ActionType.BasicSynthesis, set.ElementAt(0));
|
||||||
|
Assert.AreEqual(ActionType.ByregotsBlessing, set.ElementAt(1));
|
||||||
|
Assert.AreEqual(ActionType.FocusedTouch, set.ElementAt(2));
|
||||||
|
Assert.AreEqual(ActionType.DelicateSynthesis, set.ElementAt(3));
|
||||||
|
#endif
|
||||||
|
|
||||||
set.RemoveAction(ActionType.FocusedTouch);
|
set.RemoveAction(ActionType.FocusedTouch);
|
||||||
|
|
||||||
Assert.AreEqual(3, set.Count);
|
Assert.AreEqual(3, set.Count);
|
||||||
|
|
||||||
|
#if !IS_TRACE
|
||||||
Assert.AreEqual(ActionType.DelicateSynthesis, set.ElementAt(0));
|
Assert.AreEqual(ActionType.DelicateSynthesis, set.ElementAt(0));
|
||||||
Assert.AreEqual(ActionType.ByregotsBlessing, set.ElementAt(1));
|
Assert.AreEqual(ActionType.ByregotsBlessing, set.ElementAt(1));
|
||||||
Assert.AreEqual(ActionType.BasicSynthesis, set.ElementAt(2));
|
Assert.AreEqual(ActionType.BasicSynthesis, set.ElementAt(2));
|
||||||
|
#else
|
||||||
|
Assert.AreEqual(ActionType.BasicSynthesis, set.ElementAt(0));
|
||||||
|
Assert.AreEqual(ActionType.ByregotsBlessing, set.ElementAt(1));
|
||||||
|
Assert.AreEqual(ActionType.DelicateSynthesis, set.ElementAt(2));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestRandomIndex()
|
public void TestRandomIndex()
|
||||||
{
|
{
|
||||||
#if IS_DETERMINISTIC
|
#if IS_DETERMINISTIC
|
||||||
Assert.Inconclusive("Craftimizer is built for benchmarking; all random actions are deterministic and not actually random.");
|
Assert.Inconclusive("Craftimizer is currently built for determinism; all random actions are not actually random.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var actions = new[]
|
var actions = new[]
|
||||||
{
|
{
|
||||||
ActionType.BasicTouch,
|
ActionType.BasicTouch,
|
||||||
ActionType.BasicSynthesis,
|
ActionType.BasicSynthesis,
|
||||||
ActionType.GreatStrides,
|
ActionType.GreatStrides,
|
||||||
ActionType.TrainedFinesse,
|
ActionType.TrainedFinesse,
|
||||||
};
|
};
|
||||||
|
|
||||||
var set = new ActionSet();
|
var set = new ActionSet();
|
||||||
foreach(var action in actions)
|
foreach(var action in actions)
|
||||||
|
|||||||
+2
-1
@@ -53,7 +53,8 @@ Global
|
|||||||
{C3AEA981-9DA8-405C-995B-86528493891B}.Debug|x64.Build.0 = Debug|x64
|
{C3AEA981-9DA8-405C-995B-86528493891B}.Debug|x64.Build.0 = Debug|x64
|
||||||
{C3AEA981-9DA8-405C-995B-86528493891B}.Release|x64.ActiveCfg = Release|x64
|
{C3AEA981-9DA8-405C-995B-86528493891B}.Release|x64.ActiveCfg = Release|x64
|
||||||
{C3AEA981-9DA8-405C-995B-86528493891B}.Release|x64.Build.0 = Release|x64
|
{C3AEA981-9DA8-405C-995B-86528493891B}.Release|x64.Build.0 = Release|x64
|
||||||
{C3AEA981-9DA8-405C-995B-86528493891B}.Trace|x64.ActiveCfg = Release|x64
|
{C3AEA981-9DA8-405C-995B-86528493891B}.Trace|x64.ActiveCfg = Trace|x64
|
||||||
|
{C3AEA981-9DA8-405C-995B-86528493891B}.Trace|x64.Build.0 = Trace|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
+37
-1
@@ -11,6 +11,7 @@ public struct ActionSet
|
|||||||
|
|
||||||
public static readonly ActionType[] AcceptedActions = new[]
|
public static readonly ActionType[] AcceptedActions = new[]
|
||||||
{
|
{
|
||||||
|
#if !IS_TRACE
|
||||||
ActionType.StandardTouchCombo,
|
ActionType.StandardTouchCombo,
|
||||||
ActionType.AdvancedTouchCombo,
|
ActionType.AdvancedTouchCombo,
|
||||||
ActionType.FocusedTouchCombo,
|
ActionType.FocusedTouchCombo,
|
||||||
@@ -40,6 +41,36 @@ public struct ActionSet
|
|||||||
ActionType.Observe,
|
ActionType.Observe,
|
||||||
ActionType.MastersMend,
|
ActionType.MastersMend,
|
||||||
ActionType.BasicTouch,
|
ActionType.BasicTouch,
|
||||||
|
#else
|
||||||
|
//ActionType.BasicSynthesis,
|
||||||
|
ActionType.BasicTouch,
|
||||||
|
ActionType.MastersMend,
|
||||||
|
ActionType.Observe,
|
||||||
|
ActionType.WasteNot,
|
||||||
|
ActionType.Veneration,
|
||||||
|
ActionType.StandardTouch,
|
||||||
|
ActionType.GreatStrides,
|
||||||
|
ActionType.Innovation,
|
||||||
|
ActionType.BasicSynthesis,
|
||||||
|
ActionType.WasteNot2,
|
||||||
|
ActionType.ByregotsBlessing,
|
||||||
|
ActionType.MuscleMemory,
|
||||||
|
//ActionType.CarefulSynthesis,
|
||||||
|
ActionType.Manipulation,
|
||||||
|
ActionType.PrudentTouch,
|
||||||
|
ActionType.FocusedSynthesis,
|
||||||
|
ActionType.FocusedTouch,
|
||||||
|
ActionType.Reflect,
|
||||||
|
ActionType.PreparatoryTouch,
|
||||||
|
//ActionType.Groundwork,
|
||||||
|
ActionType.DelicateSynthesis,
|
||||||
|
ActionType.TrainedEye,
|
||||||
|
ActionType.CarefulSynthesis,
|
||||||
|
ActionType.AdvancedTouch,
|
||||||
|
ActionType.Groundwork,
|
||||||
|
ActionType.PrudentSynthesis,
|
||||||
|
ActionType.TrainedFinesse,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly int[] AcceptedActionsLUT;
|
public static readonly int[] AcceptedActionsLUT;
|
||||||
@@ -64,7 +95,12 @@ public struct ActionSet
|
|||||||
}
|
}
|
||||||
[Pure]
|
[Pure]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static ActionType ToAction(int index) => AcceptedActions[index];
|
private static ActionType ToAction(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= AcceptedActions.Length)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(index), index, $"Index {index} is out of range for {nameof(ActionSet)}.");
|
||||||
|
return AcceptedActions[index];
|
||||||
|
}
|
||||||
[Pure]
|
[Pure]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static uint ToMask(ActionType action) => 1u << (FromAction(action) + 1);
|
private static uint ToMask(ActionType action) => 1u << (FromAction(action) + 1);
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ public struct SimulationNode
|
|||||||
if (completionState != CompletionState.ProgressComplete)
|
if (completionState != CompletionState.ProgressComplete)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (state.Input.Recipe.MaxQuality == 0)
|
||||||
|
return 1f - ((float)(state.ActionCount + 1) / config.MaxStepCount);
|
||||||
|
|
||||||
static float Apply(float bonus, float value, float target) =>
|
static float Apply(float bonus, float value, float target) =>
|
||||||
bonus * (target > 0 ? Math.Min(1f, value / target) : 1);
|
bonus * (target > 0 ? Math.Min(1f, value / target) : 1);
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ public struct SimulationNode
|
|||||||
state.Input.Recipe.MaxProgress
|
state.Input.Recipe.MaxProgress
|
||||||
);
|
);
|
||||||
|
|
||||||
var byregotBonus = CanByregot(state) ? (state.ActiveEffects.InnerQuiet * .2f + 1) * state.Input.BaseQualityGain : 0;
|
var byregotBonus = 0;// CanByregot(state) ? (state.ActiveEffects.InnerQuiet * .2f + 1) * state.Input.BaseQualityGain : 0;
|
||||||
var qualityScore = Apply(
|
var qualityScore = Apply(
|
||||||
config.ScoreQuality,
|
config.ScoreQuality,
|
||||||
state.Quality + byregotBonus,
|
state.Quality + byregotBonus,
|
||||||
@@ -75,7 +78,7 @@ public struct SimulationNode
|
|||||||
);
|
);
|
||||||
|
|
||||||
var fewerStepsScore =
|
var fewerStepsScore =
|
||||||
config.ScoreSteps * (1f - (float)(state.ActionCount + 1) / config.MaxStepCount);
|
config.ScoreSteps * (1f - ((float)(state.ActionCount + 1) / config.MaxStepCount));
|
||||||
|
|
||||||
return progressScore + qualityScore + durabilityScore + cpScore + fewerStepsScore;
|
return progressScore + qualityScore + durabilityScore + cpScore + fewerStepsScore;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user