Remove threadlocal dependence

This commit is contained in:
Asriel Camora
2023-06-21 13:20:05 -07:00
parent 0f2267dabf
commit 5faaa02f1a
43 changed files with 279 additions and 244 deletions
+10 -3
View File
@@ -1,4 +1,5 @@
using Craftimizer.Simulator.Actions;
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics.X86;
@@ -42,23 +43,29 @@ public struct ActionSet
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int FromAction(ActionType action) => Array.IndexOf(Simulator.AcceptedActions, action);
private static int FromAction(ActionType action) => Simulator.AcceptedActionsLUT[(byte)action];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ActionType ToAction(int index) => Simulator.AcceptedActions[index];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly bool HasAction(ActionType action) => (bits & (1u << (FromAction(action) + 1))) != 0;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddAction(ActionType action) => bits |= 1u << (FromAction(action) + 1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveAction(ActionType action) => bits &= ~(1u << (FromAction(action) + 1));
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly bool HasAction(ActionType action) => (bits & (1u << (FromAction(action) + 1))) != 0;
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly ActionType ElementAt(int index) => ToAction(NthBitSet(bits, index) - 1);
[Pure]
public readonly int Count => BitOperations.PopCount(bits);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly ActionType SelectRandom(Random random) => ElementAt(random.Next(Count));
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly ActionType First() => ElementAt(0);
}
+25 -10
View File
@@ -1,10 +1,12 @@
using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using Sim = Craftimizer.Simulator.Simulator;
namespace Craftimizer.Solver.Crafty;
public class Simulator : Sim
public sealed class Simulator : Sim
{
private readonly int maxStepCount;
@@ -52,12 +54,26 @@ public class Simulator : Sim
ActionType.BasicTouch,
};
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L146
private bool CanUseAction(ActionType action, bool strict)
{
var baseAction = action.WithUnsafe();
public static readonly int[] AcceptedActionsLUT;
if (CalculateSuccessRate(baseAction.SuccessRate) != 1)
static Simulator()
{
AcceptedActionsLUT = new int[Enum.GetValues<ActionType>().Length];
for (var i = 0; i < AcceptedActions.Length; i++)
AcceptedActionsLUT[(byte)AcceptedActions[i]] = i;
}
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L146
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
// It's just a bunch of if statements, I would assume this is actually quite simple to follow
#pragma warning disable MA0051 // Method is too long
private bool CanUseAction(ActionType action, bool strict)
#pragma warning restore MA0051 // Method is too long
{
var baseAction = action.Base();
if (CalculateSuccessRate(baseAction.SuccessRate(this)) != 1)
return false;
// don't allow quality moves at max quality
@@ -72,7 +88,7 @@ public class Simulator : Sim
{
// always used Trained Eye if it's available
if (action == ActionType.TrainedEye)
return baseAction.CanUse;
return baseAction.CanUse(this);
// only allow Focused moves after Observe
if (ActionStates.Observed &&
@@ -94,7 +110,7 @@ public class Simulator : Sim
if (baseAction.IncreasesProgress)
{
var progressIncrease = CalculateProgressGain(baseAction.Efficiency);
var progressIncrease = CalculateProgressGain(baseAction.Efficiency(this));
var wouldFinish = Progress + progressIncrease >= Input.Recipe.MaxProgress;
if (wouldFinish)
@@ -142,7 +158,7 @@ public class Simulator : Sim
return false;
}
return baseAction.CanUse;
return baseAction.CanUse(this);
}
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L137
@@ -151,7 +167,6 @@ public class Simulator : Sim
if (IsComplete)
return new();
ActionUtils.SetSimulation(this);
var ret = new ActionSet();
foreach (var action in AcceptedActions)
if (CanUseAction(action, strict))
+7 -11
View File
@@ -1,5 +1,6 @@
using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -32,20 +33,14 @@ public class Solver
{
}
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);
(_, var newState) = Simulator.Execute(state, action);
return new(
newState,
action,
completionState,
newActions
Simulator.CompletionState,
Simulator.AvailableActionsHeuristic(strict)
);
}
@@ -177,11 +172,12 @@ public class Solver
break;
randomAction = currentActions.SelectRandom(Random);
actions[actionCount++] = randomAction;
(currentState, currentCompletionState, currentActions) = ExecuteSimple(currentState, randomAction, true);
(_, currentState) = Simulator.Execute(currentState, randomAction);
currentCompletionState = Simulator.CompletionState;
currentActions = Simulator.AvailableActionsHeuristic(true);
}
// store the result if a max score was reached
currentCompletionState = SimulationNode.GetCompletionState(currentCompletionState, currentActions);
var score = SimulationNode.CalculateScoreForState(currentState, currentCompletionState, Config.MaxStepCount) ?? 0;
if (currentCompletionState == CompletionState.ProgressComplete)
{