From 9a75542e4bce7d9e29fdb05aa57c8b7ac59c139c Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Thu, 13 Jul 2023 12:27:45 +0200 Subject: [PATCH] Tweak byregot scoring system, add bonuses to config --- Simulator/Actions/AdvancedTouchCombo.cs | 4 +- Simulator/Actions/BaseAction.cs | 50 ++++++++++++++++++++++ Simulator/Actions/FocusedSynthesisCombo.cs | 4 +- Simulator/Actions/FocusedTouchCombo.cs | 4 +- Simulator/Actions/StandardTouchCombo.cs | 41 ------------------ Solver/Crafty/SimulationNode.cs | 36 +++++----------- Solver/Crafty/Solver.cs | 4 +- Solver/Crafty/SolverConfig.cs | 12 ++++++ 8 files changed, 80 insertions(+), 75 deletions(-) diff --git a/Simulator/Actions/AdvancedTouchCombo.cs b/Simulator/Actions/AdvancedTouchCombo.cs index 5bfb274..cb51547 100644 --- a/Simulator/Actions/AdvancedTouchCombo.cs +++ b/Simulator/Actions/AdvancedTouchCombo.cs @@ -12,8 +12,8 @@ internal sealed class AdvancedTouchCombo : BaseAction public override int CPCost(Simulator s) => 18 + 18 + 18; public override bool CanUse(Simulator s) => - // BasicTouch.DurabilityCost vv vv StandardTouch.DurabilityCost - base.CanUse(s) && StandardTouchCombo.VerifyDurability3(s, 10, 10); + // BasicTouch.DurabilityCost vv vv StandardTouch.DurabilityCost + base.CanUse(s) && VerifyDurability3(s, 10, 10); private static readonly BasicTouch ActionA = new(); private static readonly StandardTouch ActionB = new(); diff --git a/Simulator/Actions/BaseAction.cs b/Simulator/Actions/BaseAction.cs index 4fc63a3..1470989 100644 --- a/Simulator/Actions/BaseAction.cs +++ b/Simulator/Actions/BaseAction.cs @@ -80,4 +80,54 @@ public abstract class BaseAction builder.AppendLine($"{s.CalculateSuccessRate(SuccessRate(s)) * 100:##}%% Success Rate"); return builder.ToString(); } + + private static bool VerifyDurability2(int durabilityA, int durability, Effects effects) + { + var wasteNots = effects.HasEffect(EffectType.WasteNot) || effects.HasEffect(EffectType.WasteNot2); + // -A + durability -= (int)MathF.Ceiling(durabilityA * (wasteNots ? .5f : 1f)); + if (durability <= 0) + return false; + + // If we can do the first action and still have durability left to survive to the next + // step (even before the Manipulation modifier), we can certainly do the next action. + return true; + } + + public static bool VerifyDurability2(SimulationState s, int durabilityA) => + VerifyDurability2(durabilityA, s.Durability, s.ActiveEffects); + + public static bool VerifyDurability2(Simulator s, int durabilityA) => + VerifyDurability2(durabilityA, s.Durability, s.ActiveEffects); + + public static bool VerifyDurability3(int durabilityA, int durabilityB, int durability, Effects effects) + { + var wasteNots = Math.Max(effects.GetDuration(EffectType.WasteNot), effects.GetDuration(EffectType.WasteNot2)); + var manips = effects.HasEffect(EffectType.Manipulation); + + durability -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f); + if (durability <= 0) + return false; + + if (manips) + durability += 5; + + if (wasteNots > 0) + wasteNots--; + + durability -= (int)MathF.Ceiling(durabilityB * wasteNots > 0 ? .5f : 1f); + + if (durability <= 0) + return false; + + // If we can do the second action and still have durability left to survive to the next + // step (even before the Manipulation modifier), we can certainly do the next action. + return true; + } + + public static bool VerifyDurability3(Simulator s, int durabilityA, int durabilityB) => + VerifyDurability3(durabilityA, durabilityB, s.Durability, s.ActiveEffects); + + public static bool VerifyDurability3(SimulationState s, int durabilityA, int durabilityB) => + VerifyDurability3(durabilityA, durabilityB, s.Durability, s.ActiveEffects); } diff --git a/Simulator/Actions/FocusedSynthesisCombo.cs b/Simulator/Actions/FocusedSynthesisCombo.cs index 7570d91..4c5bc4f 100644 --- a/Simulator/Actions/FocusedSynthesisCombo.cs +++ b/Simulator/Actions/FocusedSynthesisCombo.cs @@ -12,8 +12,8 @@ internal sealed class FocusedSynthesisCombo : BaseAction public override int CPCost(Simulator s) => 7 + 5; public override bool CanUse(Simulator s) => - // Observe.DurabilityCost v - base.CanUse(s) && StandardTouchCombo.VerifyDurability2(s, 0); + // Observe.DurabilityCost v + base.CanUse(s) && VerifyDurability2(s, 0); private static readonly Observe ActionA = new(); private static readonly FocusedSynthesis ActionB = new(); diff --git a/Simulator/Actions/FocusedTouchCombo.cs b/Simulator/Actions/FocusedTouchCombo.cs index e545493..98e9767 100644 --- a/Simulator/Actions/FocusedTouchCombo.cs +++ b/Simulator/Actions/FocusedTouchCombo.cs @@ -12,8 +12,8 @@ internal sealed class FocusedTouchCombo : BaseAction public override int CPCost(Simulator s) => 7 + 18; public override bool CanUse(Simulator s) => - // Observe.DurabilityCost v - base.CanUse(s) && StandardTouchCombo.VerifyDurability2(s, 0); + // Observe.DurabilityCost v + base.CanUse(s) && VerifyDurability2(s, 0); private static readonly Observe ActionA = new(); private static readonly FocusedTouch ActionB = new(); diff --git a/Simulator/Actions/StandardTouchCombo.cs b/Simulator/Actions/StandardTouchCombo.cs index 2cf4725..ded0665 100644 --- a/Simulator/Actions/StandardTouchCombo.cs +++ b/Simulator/Actions/StandardTouchCombo.cs @@ -25,45 +25,4 @@ internal sealed class StandardTouchCombo : BaseAction public override string GetTooltip(Simulator s, bool addUsability) => $"{ActionA.GetTooltip(s, addUsability)}\n{ActionB.GetTooltip(s, addUsability)}"; - - public static bool VerifyDurability2(Simulator s, int durabilityA) - { - var d = s.Durability; - var wasteNots = s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2); - - // -A - d -= (int)MathF.Ceiling(durabilityA * (wasteNots ? .5f : 1f)); - if (d <= 0) - return false; - - // If we can do the first action and still have durability left to survive to the next - // step (even before the Manipulation modifier), we can certainly do the next action. - return true; - } - - public static bool VerifyDurability3(Simulator s, int durabilityA, int durabilityB) - { - var d = s.Durability; - var wasteNots = Math.Max(s.GetEffectDuration(EffectType.WasteNot), s.GetEffectDuration(EffectType.WasteNot2)); - var manips = s.GetEffectDuration(EffectType.Manipulation); - - d -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f); - if (d <= 0) - return false; - - if (manips > 0) - d += 5; - - if (wasteNots > 0) - wasteNots--; - - d -= (int)MathF.Ceiling(durabilityB * wasteNots > 0 ? .5f : 1f); - - if (d <= 0) - return false; - - // If we can do the second action and still have durability left to survive to the next - // step (even before the Manipulation modifier), we can certainly do the next action. - return true; - } } diff --git a/Solver/Crafty/SimulationNode.cs b/Solver/Crafty/SimulationNode.cs index 700e82f..35b9543 100644 --- a/Solver/Crafty/SimulationNode.cs +++ b/Solver/Crafty/SimulationNode.cs @@ -30,27 +30,18 @@ public struct SimulationNode CompletionState.NoMoreActions : simCompletionState; - public readonly float? CalculateScore(int maxStepCount) => CalculateScoreForState(State, SimulationCompletionState, maxStepCount); + public readonly float? CalculateScore(SolverConfig config) => + CalculateScoreForState(State, SimulationCompletionState, config); private static bool CanByregot(SimulationState state) { if (state.ActiveEffects.InnerQuiet == 0) return false; - var wasteNot = Math.Max(state.ActiveEffects.WasteNot, state.ActiveEffects.WasteNot2); - var manipulation = state.ActiveEffects.Manipulation; - var durability = state.Durability; - durability -= wasteNot-- > 0 ? 5 : 10; - if (durability <= 0) - return false; - if (manipulation-- > 0) - durability += 5; - durability -= wasteNot-- > 0 ? 5 : 10; - - return durability >= 0; + return BaseAction.VerifyDurability2(state, 10); } - public static float? CalculateScoreForState(SimulationState state, CompletionState completionState, int maxStepCount) + public static float? CalculateScoreForState(SimulationState state, CompletionState completionState, SolverConfig config) { if (completionState != CompletionState.ProgressComplete) return null; @@ -58,40 +49,33 @@ public struct SimulationNode static float Apply(float bonus, float value, float target) => bonus * Math.Min(1f, value / target); - var progressBonus = 0.20f; - var qualityBonus = 0.65f; - var durabilityBonus = 0.05f; - var cpBonus = 0.05f; - var fewerStepsBonus = 0.05f; - var progressScore = Apply( - progressBonus, + config.ScoreProgressBonus, state.Progress, state.Input.Recipe.MaxProgress ); var byregotBonus = CanByregot(state) ? (state.ActiveEffects.InnerQuiet * .2f + 1) * state.Input.BaseQualityGain : 0; - var quality = Math.Clamp(state.Quality + byregotBonus, 0, state.Input.Recipe.MaxQuality); var qualityScore = Apply( - qualityBonus, - quality, + config.ScoreQualityBonus, + state.Quality + byregotBonus, state.Input.Recipe.MaxQuality ); var durabilityScore = Apply( - durabilityBonus, + config.ScoreDurabilityBonus, state.Durability, state.Input.Recipe.MaxDurability ); var cpScore = Apply( - cpBonus, + config.ScoreCPBonus, state.CP, state.Input.Stats.CP ); var fewerStepsScore = - fewerStepsBonus * (1f - ((float)(state.ActionCount + 1) / maxStepCount)); + config.ScoreFewerStepsBonus * (1f - ((float)(state.ActionCount + 1) / config.MaxStepCount)); return progressScore + qualityScore + durabilityScore + cpScore + fewerStepsScore; } diff --git a/Solver/Crafty/Solver.cs b/Solver/Crafty/Solver.cs index d0354d6..6ff7771 100644 --- a/Solver/Crafty/Solver.cs +++ b/Solver/Crafty/Solver.cs @@ -199,7 +199,7 @@ public sealed class Solver ref var initialState = ref initialNode.State; // expand once if (initialState.IsComplete) - return (initialNode, initialState.CalculateScore(config.MaxStepCount) ?? 0); + return (initialNode, initialState.CalculateScore(config) ?? 0); var poppedAction = initialState.AvailableActions.PopRandom(random); var expandedNode = initialNode.Add(Execute(simulator, initialState.State, poppedAction, true)); @@ -225,7 +225,7 @@ public sealed class Solver } // store the result if a max score was reached - var score = SimulationNode.CalculateScoreForState(currentState, currentCompletionState, config.MaxStepCount) ?? 0; + var score = SimulationNode.CalculateScoreForState(currentState, currentCompletionState, config) ?? 0; if (currentCompletionState == CompletionState.ProgressComplete) { if (score >= config.ScoreStorageThreshold && score >= MaxScore) diff --git a/Solver/Crafty/SolverConfig.cs b/Solver/Crafty/SolverConfig.cs index 5e68b66..17a2d9b 100644 --- a/Solver/Crafty/SolverConfig.cs +++ b/Solver/Crafty/SolverConfig.cs @@ -15,6 +15,12 @@ public readonly record struct SolverConfig public int FurcatedActionCount { get; init; } public bool StrictActions { get; init; } + public float ScoreProgressBonus { get; init; } + public float ScoreQualityBonus { get; init; } + public float ScoreDurabilityBonus { get; init; } + public float ScoreCPBonus { get; init; } + public float ScoreFewerStepsBonus { get; init; } + public SolverConfig() { Iterations = 300000; @@ -26,5 +32,11 @@ public readonly record struct SolverConfig ForkCount = Environment.ProcessorCount; FurcatedActionCount = ForkCount / 2; StrictActions = true; + + ScoreProgressBonus = .20f; + ScoreQualityBonus = .65f; + ScoreDurabilityBonus = .05f; + ScoreCPBonus = .05f; + ScoreFewerStepsBonus = .05f; } }