From 1dda7496e9006b9660f098b833e105ba95e7d20f Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Wed, 21 Jun 2023 09:40:37 -0700 Subject: [PATCH] Remove unused NodeData instantiations --- Solver/Crafty/ActionSet.cs | 5 +++++ Solver/Crafty/SimulationNode.cs | 34 +++++++++++++++------------- Solver/Crafty/Solver.cs | 39 +++++++++++++++++++-------------- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/Solver/Crafty/ActionSet.cs b/Solver/Crafty/ActionSet.cs index ced5415..1568992 100644 --- a/Solver/Crafty/ActionSet.cs +++ b/Solver/Crafty/ActionSet.cs @@ -56,4 +56,9 @@ public struct ActionSet public readonly ActionType ElementAt(int index) => ToAction(NthBitSet(bits, index) - 1); public readonly int Count => BitOperations.PopCount(bits); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ActionType SelectRandom(Random random) => ElementAt(random.Next(Count)); + + public readonly ActionType First() => ElementAt(0); } diff --git a/Solver/Crafty/SimulationNode.cs b/Solver/Crafty/SimulationNode.cs index 11f0a70..4abb7bb 100644 --- a/Solver/Crafty/SimulationNode.cs +++ b/Solver/Crafty/SimulationNode.cs @@ -10,10 +10,7 @@ public readonly struct SimulationNode public readonly CompletionState SimulationCompletionState; public readonly NodeData Data; - public CompletionState CompletionState => - Data.AvailableActions.Count == 0 && SimulationCompletionState == CompletionState.Incomplete ? - CompletionState.NoMoreActions : - SimulationCompletionState; + public CompletionState CompletionState => GetCompletionState(SimulationCompletionState, Data.AvailableActions); public bool IsComplete => CompletionState != CompletionState.Incomplete; @@ -25,9 +22,16 @@ public readonly struct SimulationNode Data = data; } - public float? CalculateScore() + public static CompletionState GetCompletionState(CompletionState simCompletionState, ActionSet actions) => + actions.Count == 0 && simCompletionState == CompletionState.Incomplete ? + CompletionState.NoMoreActions : + simCompletionState; + + public float? CalculateScore() => CalculateScoreForState(State, SimulationCompletionState); + + public static float? CalculateScoreForState(SimulationState state, CompletionState completionState) { - if (CompletionState != CompletionState.ProgressComplete) + if (completionState != CompletionState.ProgressComplete) return null; static float Apply(float bonus, float value, float target) => @@ -41,30 +45,30 @@ public readonly struct SimulationNode var progressScore = Apply( progressBonus, - State.Progress, - State.Input.Recipe.MaxProgress + state.Progress, + state.Input.Recipe.MaxProgress ); var qualityScore = Apply( qualityBonus, - State.Quality, - State.Input.Recipe.MaxQuality + state.Quality, + state.Input.Recipe.MaxQuality ); var durabilityScore = Apply( durabilityBonus, - State.Durability, - State.Input.Recipe.MaxDurability + state.Durability, + state.Input.Recipe.MaxDurability ); var cpScore = Apply( cpBonus, - State.CP, - State.Input.Stats.CP + state.CP, + state.Input.Stats.CP ); var fewerStepsScore = - fewerStepsBonus * (1f - ((float)(State.ActionCount + 1) / Solver.MaxStepCount)); + fewerStepsBonus * (1f - ((float)(state.ActionCount + 1) / Solver.MaxStepCount)); return progressScore + qualityScore + durabilityScore + cpScore + fewerStepsScore; } diff --git a/Solver/Crafty/Solver.cs b/Solver/Crafty/Solver.cs index 5292295..bb7e155 100644 --- a/Solver/Crafty/Solver.cs +++ b/Solver/Crafty/Solver.cs @@ -36,14 +36,20 @@ public class Solver { } - private SimulationNode Execute(SimulationState state, ActionType action, bool strict) + private (SimulationState NewState, CompletionState SimulatorCompletionState, ActionSet AvailableActions) ExecuteSimple(SimulationState state, ActionType action, bool strict) { (_, var newState) = Simulator.Execute(state, action); + return (newState, Simulator.CompletionState, Simulator.AvailableActionsHeuristic(strict)); + } + + private SimulationNode Execute(SimulationState state, ActionType action, bool strict) + { + (var newState, var completionState, var newActions) = ExecuteSimple(state, action, strict); return new( newState, action, - Simulator.CompletionState, - new() { AvailableActions = Simulator.AvailableActionsHeuristic(strict) } + completionState, + new() { AvailableActions = newActions } ); } @@ -158,37 +164,38 @@ public class Solver if (initialState.IsComplete) return (initialNode, initialState.CompletionState, initialState.CalculateScore() ?? 0); - var randomIdx = 0;// Random.Next(initialState.Data.AvailableActions.Count); - var randomAction = initialState.Data.AvailableActions.ElementAt(randomIdx); + var randomAction = initialState.Data.AvailableActions.First(); initialState.Data.AvailableActions.RemoveAction(randomAction); - var expandedState = Execute(initialState.State, randomAction, true); - var expandedNode = initialNode.Add(expandedState); + var expandedNode = initialNode.Add(Execute(initialState.State, randomAction, true)); // playout to a terminal state - var currentState = expandedNode.State; + var currentState = expandedNode.State.State; + var currentCompletionState = expandedNode.State.SimulationCompletionState; + var currentActions = expandedNode.State.Data.AvailableActions; + byte actionCount = 0; Span actions = stackalloc ActionType[MaxStepCount]; while (true) { - if (currentState.IsComplete) + if (SimulationNode.GetCompletionState(currentCompletionState, currentActions) != CompletionState.Incomplete) break; - randomIdx = 0;// Random.Next(currentState.Data.AvailableActions.Count); - randomAction = currentState.Data.AvailableActions.ElementAt(randomIdx); + randomAction = currentActions.First(); actions[actionCount++] = randomAction; - currentState = Execute(currentState.State, randomAction, true); + (currentState, currentCompletionState, currentActions) = ExecuteSimple(currentState, randomAction, true); } // store the result if a max score was reached - var score = currentState.CalculateScore() ?? 0; - if (currentState.CompletionState == CompletionState.ProgressComplete) + currentCompletionState = SimulationNode.GetCompletionState(currentCompletionState, currentActions); + var score = SimulationNode.CalculateScoreForState(currentState, currentCompletionState) ?? 0; + if (currentCompletionState == CompletionState.ProgressComplete) { if (score >= ScoreStorageThreshold && score >= RootNode.State.Data.Scores.MaxScore) { (var terminalNode, _) = ExecuteActions(expandedNode, actions[..actionCount], true); - return (terminalNode, currentState.CompletionState, score); + return (terminalNode, currentCompletionState, score); } } - return (expandedNode, currentState.CompletionState, score); + return (expandedNode, currentCompletionState, score); } public static void Backpropagate(Node startNode, Node targetNode, float score)