From 2e9d1e899e1b70f024a5d67b83226723fc58d56e Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Mon, 3 Jul 2023 21:01:18 +0200 Subject: [PATCH] Decoupled simulator instance from solver multithread soon, but holy crap multithreaded tree stuff is annoying --- Simulator/Simulator.cs | 21 +++++++++--------- Solver/Crafty/Simulator.cs | 10 +++++---- Solver/Crafty/Solver.cs | 44 +++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/Simulator/Simulator.cs b/Simulator/Simulator.cs index 7ee8fc9..ffc2f8d 100644 --- a/Simulator/Simulator.cs +++ b/Simulator/Simulator.cs @@ -19,17 +19,7 @@ public class Simulator public bool IsFirstStep => State.StepCount == 0; - public CompletionState CompletionState - { - get - { - if (Progress >= Input.Recipe.MaxProgress) - return CompletionState.ProgressComplete; - if (Durability <= 0) - return CompletionState.NoMoreDurability; - return CompletionState.Incomplete; - } - } + public CompletionState CompletionState => CalculateCompletionState(State); public virtual bool IsComplete => CompletionState != CompletionState.Incomplete; public IEnumerable AvailableActions => ActionUtils.AvailableActions(this); @@ -276,4 +266,13 @@ public class Simulator public void IncreaseQuality(float efficiency) => IncreaseQualityRaw(CalculateQualityGain(efficiency, false)); + + public static CompletionState CalculateCompletionState(SimulationState state) + { + if (state.Progress >= state.Input.Recipe.MaxProgress) + return CompletionState.ProgressComplete; + if (state.Durability <= 0) + return CompletionState.NoMoreDurability; + return CompletionState.Incomplete; + } } diff --git a/Solver/Crafty/Simulator.cs b/Solver/Crafty/Simulator.cs index d420cc0..2e3a82a 100644 --- a/Solver/Crafty/Simulator.cs +++ b/Solver/Crafty/Simulator.cs @@ -9,10 +9,7 @@ public sealed class Simulator : SimulatorNoRandom { private readonly int maxStepCount; - public new CompletionState CompletionState => - (ActionCount + 1) >= maxStepCount ? - CompletionState.MaxActionCountReached : - (CompletionState)base.CompletionState; + public new CompletionState CompletionState => CalculateCompletionState(State, maxStepCount); public override bool IsComplete => CompletionState != CompletionState.Incomplete; public Simulator(SimulationState state, int maxStepCount) : base(state) @@ -168,4 +165,9 @@ public sealed class Simulator : SimulatorNoRandom ret.AddAction(action); return ret; } + + public static CompletionState CalculateCompletionState(SimulationState state, int maxStepCount) => + (state.ActionCount + 1) >= maxStepCount ? + CompletionState.MaxActionCountReached : + (CompletionState)CalculateCompletionState(state); } diff --git a/Solver/Crafty/Solver.cs b/Solver/Crafty/Solver.cs index e079f23..8b7796b 100644 --- a/Solver/Crafty/Solver.cs +++ b/Solver/Crafty/Solver.cs @@ -4,8 +4,6 @@ using System.Diagnostics.Contracts; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; using Node = Craftimizer.Solver.Crafty.ArenaNode; namespace Craftimizer.Solver.Crafty; @@ -14,39 +12,39 @@ namespace Craftimizer.Solver.Crafty; public class Solver { public SolverConfig Config; - public Simulator Simulator; public Node RootNode; - public Random Random => Simulator.Input.Random; + public Random Random; public Solver(SolverConfig config, SimulationState state, bool strict) { Config = config; - Simulator = new(state, config.MaxStepCount); + Simulator sim = new(state, config.MaxStepCount); RootNode = new(new( state, null, - Simulator.CompletionState, - Simulator.AvailableActionsHeuristic(strict) + sim.CompletionState, + sim.AvailableActionsHeuristic(strict) )); + Random = state.Input.Random; } public Solver(SolverConfig config, SimulationInput input, bool strict) : this(config, new SimulationState(input), strict) { } - private SimulationNode Execute(SimulationState state, ActionType action, bool strict) + private static SimulationNode Execute(Simulator simulator, SimulationState state, ActionType action, bool strict) { - (_, var newState) = Simulator.Execute(state, action); + (_, var newState) = simulator.Execute(state, action); return new( newState, action, - Simulator.CompletionState, - Simulator.AvailableActionsHeuristic(strict) + simulator.CompletionState, + simulator.AvailableActionsHeuristic(strict) ); } - public (Node EndNode, CompletionState State) ExecuteActions(Node startNode, ReadOnlySpan actions, bool strict = false) + public static (Node EndNode, CompletionState State) ExecuteActions(Simulator simulator, Node startNode, ReadOnlySpan actions, bool strict = false) { foreach (var action in actions) { @@ -58,7 +56,7 @@ public class Solver return (startNode, CompletionState.InvalidAction); state.AvailableActions.RemoveAction(action); - startNode = startNode.Add(Execute(state.State, action, strict)); + startNode = startNode.Add(Execute(simulator, state.State, action, strict)); } return (startNode, startNode.State.CompletionState); @@ -160,7 +158,7 @@ public class Solver } } - public (Node ExpandedNode, CompletionState State, float Score) ExpandAndRollout(Node initialNode) + public (Node ExpandedNode, CompletionState State, float Score) ExpandAndRollout(Simulator simulator, Node initialNode) { ref var initialState = ref initialNode.State; // expand once @@ -169,7 +167,7 @@ public class Solver var randomAction = initialState.AvailableActions.SelectRandom(Random); initialState.AvailableActions.RemoveAction(randomAction); - var expandedNode = initialNode.Add(Execute(initialState.State, randomAction, true)); + var expandedNode = initialNode.Add(Execute(simulator, initialState.State, randomAction, true)); // playout to a terminal state var currentState = expandedNode.State.State; @@ -184,9 +182,9 @@ public class Solver break; randomAction = currentActions.SelectRandom(Random); actions[actionCount++] = randomAction; - (_, currentState) = Simulator.Execute(currentState, randomAction); - currentCompletionState = Simulator.CompletionState; - currentActions = Simulator.AvailableActionsHeuristic(true); + (_, currentState) = simulator.Execute(currentState, randomAction); + currentCompletionState = simulator.CompletionState; + currentActions = simulator.AvailableActionsHeuristic(true); } // store the result if a max score was reached @@ -195,7 +193,7 @@ public class Solver { if (score >= Config.ScoreStorageThreshold && score >= RootNode.State.Scores.MaxScore) { - (var terminalNode, _) = ExecuteActions(expandedNode, actions[..actionCount], true); + (var terminalNode, _) = ExecuteActions(simulator, expandedNode, actions[..actionCount], true); return (terminalNode, currentCompletionState, score); } } @@ -217,13 +215,14 @@ public class Solver public void Search(CancellationToken token) { + Simulator simulator = new(RootNode.State.State, Config.MaxStepCount); for (var i = 0; i < Config.Iterations; i++) { if (token.IsCancellationRequested) break; var selectedNode = Select(); - var (endNode, _, score) = ExpandAndRollout(selectedNode); + var (endNode, _, score) = ExpandAndRollout(simulator, selectedNode); Backpropagate(endNode, score); } @@ -251,8 +250,9 @@ public class Solver public static (List Actions, SimulationState State) SearchStepwise(SolverConfig config, SimulationState state, Action? actionCallback, CancellationToken token = default) { var actions = new List(); + Simulator sim = new(state, config.MaxStepCount); var solver = new Solver(config, state, true); - while (!solver.Simulator.IsComplete) + while (!sim.IsComplete) { if (token.IsCancellationRequested) break; @@ -267,7 +267,7 @@ public class Solver } var chosen_action = solution_actions[0]; - (_, state) = solver.Simulator.Execute(state, chosen_action); + (_, state) = sim.Execute(state, chosen_action); actions.Add(chosen_action); actionCallback?.Invoke(chosen_action);