Decoupled simulator instance from solver
multithread soon, but holy crap multithreaded tree stuff is annoying
This commit is contained in:
+10
-11
@@ -19,17 +19,7 @@ public class Simulator
|
|||||||
|
|
||||||
public bool IsFirstStep => State.StepCount == 0;
|
public bool IsFirstStep => State.StepCount == 0;
|
||||||
|
|
||||||
public CompletionState CompletionState
|
public CompletionState CompletionState => CalculateCompletionState(State);
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (Progress >= Input.Recipe.MaxProgress)
|
|
||||||
return CompletionState.ProgressComplete;
|
|
||||||
if (Durability <= 0)
|
|
||||||
return CompletionState.NoMoreDurability;
|
|
||||||
return CompletionState.Incomplete;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public virtual bool IsComplete => CompletionState != CompletionState.Incomplete;
|
public virtual bool IsComplete => CompletionState != CompletionState.Incomplete;
|
||||||
|
|
||||||
public IEnumerable<ActionType> AvailableActions => ActionUtils.AvailableActions(this);
|
public IEnumerable<ActionType> AvailableActions => ActionUtils.AvailableActions(this);
|
||||||
@@ -276,4 +266,13 @@ public class Simulator
|
|||||||
|
|
||||||
public void IncreaseQuality(float efficiency) =>
|
public void IncreaseQuality(float efficiency) =>
|
||||||
IncreaseQualityRaw(CalculateQualityGain(efficiency, false));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,7 @@ public sealed class Simulator : SimulatorNoRandom
|
|||||||
{
|
{
|
||||||
private readonly int maxStepCount;
|
private readonly int maxStepCount;
|
||||||
|
|
||||||
public new CompletionState CompletionState =>
|
public new CompletionState CompletionState => CalculateCompletionState(State, maxStepCount);
|
||||||
(ActionCount + 1) >= maxStepCount ?
|
|
||||||
CompletionState.MaxActionCountReached :
|
|
||||||
(CompletionState)base.CompletionState;
|
|
||||||
public override bool IsComplete => CompletionState != CompletionState.Incomplete;
|
public override bool IsComplete => CompletionState != CompletionState.Incomplete;
|
||||||
|
|
||||||
public Simulator(SimulationState state, int maxStepCount) : base(state)
|
public Simulator(SimulationState state, int maxStepCount) : base(state)
|
||||||
@@ -168,4 +165,9 @@ public sealed class Simulator : SimulatorNoRandom
|
|||||||
ret.AddAction(action);
|
ret.AddAction(action);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CompletionState CalculateCompletionState(SimulationState state, int maxStepCount) =>
|
||||||
|
(state.ActionCount + 1) >= maxStepCount ?
|
||||||
|
CompletionState.MaxActionCountReached :
|
||||||
|
(CompletionState)CalculateCompletionState(state);
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-22
@@ -4,8 +4,6 @@ using System.Diagnostics.Contracts;
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Intrinsics;
|
|
||||||
using System.Runtime.Intrinsics.X86;
|
|
||||||
using Node = Craftimizer.Solver.Crafty.ArenaNode<Craftimizer.Solver.Crafty.SimulationNode>;
|
using Node = Craftimizer.Solver.Crafty.ArenaNode<Craftimizer.Solver.Crafty.SimulationNode>;
|
||||||
|
|
||||||
namespace Craftimizer.Solver.Crafty;
|
namespace Craftimizer.Solver.Crafty;
|
||||||
@@ -14,39 +12,39 @@ namespace Craftimizer.Solver.Crafty;
|
|||||||
public class Solver
|
public class Solver
|
||||||
{
|
{
|
||||||
public SolverConfig Config;
|
public SolverConfig Config;
|
||||||
public Simulator Simulator;
|
|
||||||
public Node RootNode;
|
public Node RootNode;
|
||||||
|
|
||||||
public Random Random => Simulator.Input.Random;
|
public Random Random;
|
||||||
|
|
||||||
public Solver(SolverConfig config, SimulationState state, bool strict)
|
public Solver(SolverConfig config, SimulationState state, bool strict)
|
||||||
{
|
{
|
||||||
Config = config;
|
Config = config;
|
||||||
Simulator = new(state, config.MaxStepCount);
|
Simulator sim = new(state, config.MaxStepCount);
|
||||||
RootNode = new(new(
|
RootNode = new(new(
|
||||||
state,
|
state,
|
||||||
null,
|
null,
|
||||||
Simulator.CompletionState,
|
sim.CompletionState,
|
||||||
Simulator.AvailableActionsHeuristic(strict)
|
sim.AvailableActionsHeuristic(strict)
|
||||||
));
|
));
|
||||||
|
Random = state.Input.Random;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Solver(SolverConfig config, SimulationInput input, bool strict) : this(config, new SimulationState(input), strict)
|
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(
|
return new(
|
||||||
newState,
|
newState,
|
||||||
action,
|
action,
|
||||||
Simulator.CompletionState,
|
simulator.CompletionState,
|
||||||
Simulator.AvailableActionsHeuristic(strict)
|
simulator.AvailableActionsHeuristic(strict)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public (Node EndNode, CompletionState State) ExecuteActions(Node startNode, ReadOnlySpan<ActionType> actions, bool strict = false)
|
public static (Node EndNode, CompletionState State) ExecuteActions(Simulator simulator, Node startNode, ReadOnlySpan<ActionType> actions, bool strict = false)
|
||||||
{
|
{
|
||||||
foreach (var action in actions)
|
foreach (var action in actions)
|
||||||
{
|
{
|
||||||
@@ -58,7 +56,7 @@ public class Solver
|
|||||||
return (startNode, CompletionState.InvalidAction);
|
return (startNode, CompletionState.InvalidAction);
|
||||||
state.AvailableActions.RemoveAction(action);
|
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);
|
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;
|
ref var initialState = ref initialNode.State;
|
||||||
// expand once
|
// expand once
|
||||||
@@ -169,7 +167,7 @@ public class Solver
|
|||||||
|
|
||||||
var randomAction = initialState.AvailableActions.SelectRandom(Random);
|
var randomAction = initialState.AvailableActions.SelectRandom(Random);
|
||||||
initialState.AvailableActions.RemoveAction(randomAction);
|
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
|
// playout to a terminal state
|
||||||
var currentState = expandedNode.State.State;
|
var currentState = expandedNode.State.State;
|
||||||
@@ -184,9 +182,9 @@ public class Solver
|
|||||||
break;
|
break;
|
||||||
randomAction = currentActions.SelectRandom(Random);
|
randomAction = currentActions.SelectRandom(Random);
|
||||||
actions[actionCount++] = randomAction;
|
actions[actionCount++] = randomAction;
|
||||||
(_, currentState) = Simulator.Execute(currentState, randomAction);
|
(_, currentState) = simulator.Execute(currentState, randomAction);
|
||||||
currentCompletionState = Simulator.CompletionState;
|
currentCompletionState = simulator.CompletionState;
|
||||||
currentActions = Simulator.AvailableActionsHeuristic(true);
|
currentActions = simulator.AvailableActionsHeuristic(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the result if a max score was reached
|
// 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)
|
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);
|
return (terminalNode, currentCompletionState, score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,13 +215,14 @@ public class Solver
|
|||||||
|
|
||||||
public void Search(CancellationToken token)
|
public void Search(CancellationToken token)
|
||||||
{
|
{
|
||||||
|
Simulator simulator = new(RootNode.State.State, Config.MaxStepCount);
|
||||||
for (var i = 0; i < Config.Iterations; i++)
|
for (var i = 0; i < Config.Iterations; i++)
|
||||||
{
|
{
|
||||||
if (token.IsCancellationRequested)
|
if (token.IsCancellationRequested)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var selectedNode = Select();
|
var selectedNode = Select();
|
||||||
var (endNode, _, score) = ExpandAndRollout(selectedNode);
|
var (endNode, _, score) = ExpandAndRollout(simulator, selectedNode);
|
||||||
|
|
||||||
Backpropagate(endNode, score);
|
Backpropagate(endNode, score);
|
||||||
}
|
}
|
||||||
@@ -251,8 +250,9 @@ public class Solver
|
|||||||
public static (List<ActionType> Actions, SimulationState State) SearchStepwise(SolverConfig config, SimulationState state, Action<ActionType>? actionCallback, CancellationToken token = default)
|
public static (List<ActionType> Actions, SimulationState State) SearchStepwise(SolverConfig config, SimulationState state, Action<ActionType>? actionCallback, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var actions = new List<ActionType>();
|
var actions = new List<ActionType>();
|
||||||
|
Simulator sim = new(state, config.MaxStepCount);
|
||||||
var solver = new Solver(config, state, true);
|
var solver = new Solver(config, state, true);
|
||||||
while (!solver.Simulator.IsComplete)
|
while (!sim.IsComplete)
|
||||||
{
|
{
|
||||||
if (token.IsCancellationRequested)
|
if (token.IsCancellationRequested)
|
||||||
break;
|
break;
|
||||||
@@ -267,7 +267,7 @@ public class Solver
|
|||||||
}
|
}
|
||||||
|
|
||||||
var chosen_action = solution_actions[0];
|
var chosen_action = solution_actions[0];
|
||||||
(_, state) = solver.Simulator.Execute(state, chosen_action);
|
(_, state) = sim.Execute(state, chosen_action);
|
||||||
actions.Add(chosen_action);
|
actions.Add(chosen_action);
|
||||||
|
|
||||||
actionCallback?.Invoke(chosen_action);
|
actionCallback?.Invoke(chosen_action);
|
||||||
|
|||||||
Reference in New Issue
Block a user