-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c422527
commit 220b4e2
Showing
7 changed files
with
361 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
using Craftimizer.Simulator; | ||
using Craftimizer.Simulator.Actions; | ||
using System.Diagnostics.Contracts; | ||
using System.Runtime.CompilerServices; | ||
|
||
namespace Craftimizer.Solver.Heuristics; | ||
|
||
internal sealed class ExpertFinisher : IHeuristic | ||
{ | ||
[Pure] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static bool ShouldUseAction(Simulator s, ActionType action, BaseAction baseAction) | ||
{ | ||
if (!Normal.ShouldUseAction(s, action, baseAction)) | ||
return false; | ||
|
||
// always use Trained Eye if it's available | ||
if (action == ActionType.TrainedEye) | ||
return baseAction.CanUse(s); | ||
|
||
// only allow Focused moves after Observe | ||
if (s.ActionStates.Observed && | ||
action != ActionType.FocusedSynthesis && | ||
action != ActionType.FocusedTouch) | ||
return false; | ||
|
||
// don't allow quality moves under Muscle Memory for difficult crafts | ||
if (s.Input.Recipe.ClassJobLevel == 90 && | ||
s.HasEffect(EffectType.MuscleMemory) && | ||
baseAction.IncreasesQuality) | ||
return false; | ||
|
||
// use First Turn actions if it's available and the craft is difficult | ||
if (s.IsFirstStep && | ||
s.Input.Recipe.ClassJobLevel == 90 && | ||
baseAction.Category != ActionCategory.FirstTurn && | ||
s.CP > 10) | ||
return false; | ||
|
||
// don't allow combo actions if the combo is already in progress | ||
if (s.ActionStates.TouchComboIdx != 0 && | ||
(action == ActionType.StandardTouchCombo || action == ActionType.AdvancedTouchCombo)) | ||
return false; | ||
|
||
// don't allow pure quality moves under Veneration | ||
if (s.HasEffect(EffectType.Veneration) && | ||
!baseAction.IncreasesProgress && | ||
baseAction.IncreasesQuality) | ||
return false; | ||
|
||
// don't allow pure quality moves when it won't be able to finish the craft | ||
if (baseAction.IncreasesQuality && | ||
s.CalculateDurabilityCost(baseAction.DurabilityCost) > s.Durability) | ||
return false; | ||
|
||
if (baseAction.IncreasesProgress) | ||
{ | ||
var progressIncrease = s.CalculateProgressGain(baseAction.Efficiency(s)); | ||
var wouldFinish = s.Progress + progressIncrease >= s.Input.Recipe.MaxProgress; | ||
|
||
if (wouldFinish) | ||
{ | ||
// don't allow finishing the craft if there is significant quality remaining | ||
if (s.Quality < s.Input.Recipe.MaxQuality / 5) | ||
return false; | ||
} | ||
else | ||
{ | ||
// don't allow pure progress moves under Innovation, if it wouldn't finish the craft | ||
if (s.HasEffect(EffectType.Innovation) && | ||
!baseAction.IncreasesQuality && | ||
baseAction.IncreasesProgress) | ||
return false; | ||
} | ||
} | ||
|
||
// Only allow byregot at 2+ stacks | ||
if (action == ActionType.ByregotsBlessing && | ||
s.GetEffectStrength(EffectType.InnerQuiet) <= 1) | ||
return false; | ||
|
||
// Don't execute waste not if a type is already active | ||
if ((action == ActionType.WasteNot || action == ActionType.WasteNot2) && | ||
(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))) | ||
return false; | ||
|
||
// Don't observe if you can't combo it into anything | ||
if (action == ActionType.Observe && | ||
s.CP < 12) | ||
return false; | ||
|
||
// Do not Masters Mend if it would restore less than 25 dur | ||
if (action == ActionType.MastersMend && | ||
s.Input.Recipe.MaxDurability - s.Durability < 25) | ||
return false; | ||
|
||
// Don't re-execute manipulation/great strides | ||
if (action == ActionType.Manipulation && | ||
s.HasEffect(EffectType.Manipulation)) | ||
return false; | ||
|
||
if (action == ActionType.GreatStrides && | ||
s.HasEffect(EffectType.GreatStrides)) | ||
return false; | ||
|
||
// Don't overlap/reapply veneration/innovation if there is 2+ steps left | ||
if ((action == ActionType.Veneration || action == ActionType.Innovation) && | ||
(s.GetEffectDuration(EffectType.Veneration) > 1 || s.GetEffectDuration(EffectType.Innovation) > 1)) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
[Pure] | ||
public static ActionSet AvailableActions(Simulator s) => | ||
IHeuristic.AvailableActions<Strict>(s, Normal.AcceptedActions); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Craftimizer.Simulator; | ||
using System.Diagnostics.Contracts; | ||
|
||
namespace Craftimizer.Solver.Heuristics; | ||
|
||
internal sealed class ExpertHydra // : IHeuristic | ||
{ | ||
[Pure] | ||
public static ActionSet AvailableActions(Simulator s) | ||
{ | ||
var qualityTarget = s.Input.Recipe.MaxQuality * 0.8f; // 80% quality at least | ||
if (s.GetEffectStrength(EffectType.InnerQuiet) == 10 || s.Quality > qualityTarget) | ||
return ExpertFinisher.AvailableActions(s); | ||
|
||
qualityTarget = s.Input.Recipe.MaxQuality * 0.2f; // 20% quality at least | ||
var progressTarget = s.Input.Recipe.MaxProgress - s.Input.BaseProgressGain * 2.5f; // 250% efficiency away from completion | ||
if (s.Progress > progressTarget || s.Quality > qualityTarget) | ||
return ExpertQuality.AvailableActions(s); | ||
|
||
return ExpertOpener.AvailableActions(s); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using Craftimizer.Simulator; | ||
using Craftimizer.Simulator.Actions; | ||
using System.Diagnostics.Contracts; | ||
using System.Runtime.CompilerServices; | ||
|
||
namespace Craftimizer.Solver.Heuristics; | ||
|
||
internal sealed class ExpertOpener : IHeuristic | ||
{ | ||
public static readonly ActionType[] AcceptedActions = new[] | ||
{ | ||
ActionType.CarefulObservation, | ||
ActionType.FinalAppraisal, | ||
ActionType.Manipulation, | ||
ActionType.MuscleMemory, | ||
ActionType.PreciseTouch, | ||
ActionType.RapidSynthesis, | ||
ActionType.TricksOfTheTrade, | ||
ActionType.Veneration, | ||
ActionType.HeartAndSoul, | ||
}; | ||
|
||
private static readonly BaseAction RapidSynthesis = ActionType.RapidSynthesis.Base(); | ||
|
||
[Pure] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static bool ShouldUseAction(Simulator s, ActionType action, BaseAction baseAction) | ||
{ | ||
// Make sure the first step is muscle memory | ||
if (baseAction.IncreasesStepCount && s.IsFirstStep && action != ActionType.MuscleMemory) | ||
return false; | ||
|
||
// Roll for a malleable or sturdy before taking the first muscle memory step | ||
if (s.Condition is not (Condition.Malleable or Condition.Sturdy) && s.IsFirstStep && action == ActionType.MuscleMemory && s.ActionStates.CarefulObservationCount != 3) | ||
return false; | ||
|
||
if (baseAction.IncreasesProgress) | ||
{ | ||
var progressIncrease = s.CalculateProgressGain(baseAction.Efficiency(s)); | ||
var wouldFinish = s.Progress + progressIncrease >= s.Input.Recipe.MaxProgress; | ||
|
||
if (wouldFinish) | ||
return false; | ||
} | ||
|
||
if (action == ActionType.FinalAppraisal) | ||
{ | ||
if (s.HasEffect(EffectType.FinalAppraisal)) | ||
return false; | ||
|
||
var rapidProgressIncrease = s.CalculateProgressGain(RapidSynthesis.Efficiency(s)); | ||
var wouldRapidFinish = s.Progress + rapidProgressIncrease >= s.Input.Recipe.MaxProgress; | ||
return wouldRapidFinish; | ||
} | ||
|
||
// Don't reapply manipulation if there is 2+ steps left | ||
if (action == ActionType.Manipulation && | ||
s.GetEffectDuration(EffectType.Manipulation) > 1) | ||
return false; | ||
|
||
// Don't reapply veneration if there is 2+ steps left | ||
if (action == ActionType.Veneration && | ||
s.GetEffectDuration(EffectType.Veneration) > 1) | ||
return false; | ||
|
||
return s.Condition switch | ||
{ | ||
Condition.Centered or Condition.Sturdy or Condition.Normal or Condition.GoodOmen => | ||
action is ActionType.RapidSynthesis or ActionType.Veneration || | ||
action is ActionType.Manipulation && !s.HasEffect(EffectType.MuscleMemory), | ||
Condition.Malleable => | ||
action is ActionType.RapidSynthesis, | ||
Condition.Primed or Condition.Pliant => | ||
action is ActionType.RapidSynthesis or ActionType.Manipulation or ActionType.Veneration, | ||
Condition.Good => | ||
action is ActionType.RapidSynthesis or ActionType.TricksOfTheTrade or ActionType.PreciseTouch, | ||
_ => true | ||
}; | ||
} | ||
|
||
[Pure] | ||
public static ActionSet AvailableActions(Simulator s) => | ||
IHeuristic.AvailableActions<Strict>(s, AcceptedActions); | ||
} |
Oops, something went wrong.