heat/cool prediction: fixed embarassing off-by-1 bug! removed the "margin of error" config convering up this bug.
This commit is contained in:
@@ -504,15 +504,4 @@ public interface EasyGiantsFoundryConfig extends Config
|
|||||||
)
|
)
|
||||||
String generalSettings = "generalSettings";
|
String generalSettings = "generalSettings";
|
||||||
|
|
||||||
@ConfigItem(
|
|
||||||
keyName = "heatingCoolingMarginOfError",
|
|
||||||
name = "Heating/Cooling Margin of Error",
|
|
||||||
description = "The margin of error for lava/waterfall calculations to compensate for decay and overshooting.",
|
|
||||||
position = 0,
|
|
||||||
section = generalSettings
|
|
||||||
)
|
|
||||||
default int heatingCoolingBuffer()
|
|
||||||
{
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ public class EasyGiantsFoundryPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
Widget title = Objects.requireNonNull(mouldParent.getChild(1));
|
Widget title = Objects.requireNonNull(mouldParent.getChild(1));
|
||||||
|
|
||||||
// not sure why, the ":" character turns into ": ," when rendered; obmitting it.
|
// not sure why, the ":" character turns into ": ," when rendered; omitting it.
|
||||||
title.setText("Giants' Foundry Mould Setup <col=FFFFFF>(Score " + mouldScore + ")");
|
title.setText("Giants' Foundry Mould Setup <col=FFFFFF>(Score " + mouldScore + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,8 +369,8 @@ public class EasyGiantsFoundryPlugin extends Plugin
|
|||||||
|
|
||||||
state.heatingCoolingState.onTick();
|
state.heatingCoolingState.onTick();
|
||||||
}
|
}
|
||||||
previousHeat = event.getValue();
|
|
||||||
}
|
}
|
||||||
|
previousHeat = event.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class FoundryOverlay3D extends Overlay
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawHeatingActionOverlay(graphics, stageObject);
|
drawActionOverlay(graphics, stageObject);
|
||||||
|
|
||||||
Heat heat = state.getCurrentHeat();
|
Heat heat = state.getCurrentHeat();
|
||||||
Color color = getObjectColor(stage, heat);
|
Color color = getObjectColor(stage, heat);
|
||||||
@@ -155,11 +155,11 @@ public class FoundryOverlay3D extends Overlay
|
|||||||
|
|
||||||
if (state.heatingCoolingState.isCooling())
|
if (state.heatingCoolingState.isCooling())
|
||||||
{
|
{
|
||||||
drawHeatingActionOverlay(graphics, waterfall, false);
|
drawHeatingCoolingOverlay(graphics, waterfall);
|
||||||
}
|
}
|
||||||
if (state.heatingCoolingState.isHeating())
|
if (state.heatingCoolingState.isHeating())
|
||||||
{
|
{
|
||||||
drawHeatingActionOverlay(graphics, lavaPool, true);
|
drawHeatingCoolingOverlay(graphics, lavaPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -192,10 +192,10 @@ public class FoundryOverlay3D extends Overlay
|
|||||||
modelOutlineRenderer.drawOutline(stageObject, config.borderThickness(), _color, config.borderFeather());
|
modelOutlineRenderer.drawOutline(stageObject, config.borderThickness(), _color, config.borderFeather());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawHeatingActionOverlay(
|
private void drawHeatingCoolingOverlay(
|
||||||
Graphics2D graphics,
|
Graphics2D graphics,
|
||||||
GameObject stageObject,
|
GameObject stageObject
|
||||||
boolean isLava /* and not cooling */)
|
)
|
||||||
{
|
{
|
||||||
if (!config.drawLavaWaterInfoOverlay())
|
if (!config.drawLavaWaterInfoOverlay())
|
||||||
{
|
{
|
||||||
@@ -208,22 +208,10 @@ public class FoundryOverlay3D extends Overlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
String text;
|
String text;
|
||||||
if (isLava)
|
text = String.format("%d %s",
|
||||||
{
|
state.heatingCoolingState.getRemainingDuration(),
|
||||||
// %d heats or %d dunks
|
state.heatingCoolingState.getActionName()
|
||||||
text = String.format("%d %s",
|
);
|
||||||
state.heatingCoolingState.getRemainingDuration(),
|
|
||||||
state.heatingCoolingState.getActionName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// %d cools
|
|
||||||
text = String.format("%d %s",
|
|
||||||
state.heatingCoolingState.getRemainingDuration(),
|
|
||||||
state.heatingCoolingState.getActionName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoint stageLoc = stageObject.getLocalLocation();
|
LocalPoint stageLoc = stageObject.getLocalLocation();
|
||||||
stageLoc = new LocalPoint(stageLoc.getX(), stageLoc.getY());
|
stageLoc = new LocalPoint(stageLoc.getX(), stageLoc.getY());
|
||||||
@@ -437,7 +425,7 @@ public class FoundryOverlay3D extends Overlay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawHeatingActionOverlay(Graphics2D graphics, GameObject gameObject)
|
private void drawActionOverlay(Graphics2D graphics, GameObject gameObject)
|
||||||
{
|
{
|
||||||
int actionsLeft = state.getActionsLeftInStage();
|
int actionsLeft = state.getActionsLeftInStage();
|
||||||
int heatLeft = state.getActionsForHeatLevel();
|
int heatLeft = state.getActionsForHeatLevel();
|
||||||
|
|||||||
@@ -78,6 +78,13 @@ public class HeatActionSolver
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* <b>Warning:</b> this method prefers overshooting goal. For example, if goal is 957,
|
||||||
|
* it will return index that reaches >957.<br>
|
||||||
|
* This may be desirable if we're aiming to heat over range minimum,
|
||||||
|
* but undesirable when cooling below range maximum; make sure to -1 the index if so.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
* @param goal the desired heat destination
|
* @param goal the desired heat destination
|
||||||
* @param init_dx1 initial speed of heating/cooling. currently 7 for heat/cool, 27 for dunk/quench.
|
* @param init_dx1 initial speed of heating/cooling. currently 7 for heat/cool, 27 for dunk/quench.
|
||||||
* @param dx2_offset bonus acceleration. currently, 0 for heat/cool, 2 for dunk/quench.
|
* @param dx2_offset bonus acceleration. currently, 0 for heat/cool, 2 for dunk/quench.
|
||||||
|
|||||||
@@ -113,26 +113,32 @@ public class HeatActionStateMachine
|
|||||||
*/
|
*/
|
||||||
public void calculateEstimates()
|
public void calculateEstimates()
|
||||||
{
|
{
|
||||||
|
// 0: left/min 1: right/max
|
||||||
int[] range = State.getCurrentHeatRange();
|
int[] range = State.getCurrentHeatRange();
|
||||||
|
int stageMin = range[0];
|
||||||
|
int stageMax = range[1];
|
||||||
|
|
||||||
Stage stage = State.getCurrentStage();
|
Stage stage = State.getCurrentStage();
|
||||||
int actionsLeft = State.getActionsLeftInStage();
|
int actionsLeft = State.getActionsLeftInStage();
|
||||||
int actionsLeft_DeltaHeat = actionsLeft * stage.getHeatChange();
|
int actionsLeft_DeltaHeat = (actionsLeft+1) * stage.getHeatChange();
|
||||||
if (isHeating())
|
if (isHeating())
|
||||||
{
|
{
|
||||||
if (stage.isHeating())
|
if (stage.isHeating())
|
||||||
{
|
{
|
||||||
GoalHeat = Math.max(range[0] + Config.heatingCoolingBuffer(), range[1] - actionsLeft_DeltaHeat);
|
GoalHeat = Math.max(stageMin, stageMax - actionsLeft_DeltaHeat);
|
||||||
if (StartingHeat < GoalHeat)
|
if (StartingHeat < GoalHeat)
|
||||||
{
|
{
|
||||||
EstimatedDuration = HeatActionSolver.findDx0Index(
|
int duration = HeatActionSolver.findDx0Index(
|
||||||
GoalHeat - StartingHeat,
|
GoalHeat - StartingHeat,
|
||||||
Velocity, AccelerationBonus);
|
Velocity, AccelerationBonus
|
||||||
|
);
|
||||||
|
|
||||||
GoalHeat += EstimatedDuration / 2; // compensate for decay during heating
|
GoalHeat += duration / 2;
|
||||||
|
|
||||||
EstimatedDuration = HeatActionSolver.findDx0Index(
|
EstimatedDuration = HeatActionSolver.findDx0Index(
|
||||||
GoalHeat - StartingHeat,
|
GoalHeat - StartingHeat,
|
||||||
Velocity, AccelerationBonus);
|
Velocity, AccelerationBonus
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else // overheating
|
else // overheating
|
||||||
{
|
{
|
||||||
@@ -141,13 +147,21 @@ public class HeatActionStateMachine
|
|||||||
}
|
}
|
||||||
else // is cooling
|
else // is cooling
|
||||||
{
|
{
|
||||||
GoalHeat = Math.min(range[1] - Config.heatingCoolingBuffer(), range[0] - actionsLeft_DeltaHeat);
|
// actionsLeft_DeltaHeat is negative here
|
||||||
|
GoalHeat = Math.min(stageMax, stageMin - actionsLeft_DeltaHeat);
|
||||||
if (StartingHeat < GoalHeat)
|
if (StartingHeat < GoalHeat)
|
||||||
{
|
{
|
||||||
|
int duration = HeatActionSolver.findDx0Index(
|
||||||
|
GoalHeat - StartingHeat,
|
||||||
|
Velocity, AccelerationBonus
|
||||||
|
) - 1;
|
||||||
|
|
||||||
|
GoalHeat -= duration / 2;
|
||||||
|
|
||||||
EstimatedDuration = HeatActionSolver.findDx0Index(
|
EstimatedDuration = HeatActionSolver.findDx0Index(
|
||||||
GoalHeat - StartingHeat,
|
GoalHeat - StartingHeat,
|
||||||
Velocity, AccelerationBonus
|
Velocity, AccelerationBonus
|
||||||
);
|
) - 1;
|
||||||
}
|
}
|
||||||
else // cold enough
|
else // cold enough
|
||||||
{
|
{
|
||||||
@@ -157,11 +171,39 @@ public class HeatActionStateMachine
|
|||||||
}
|
}
|
||||||
else if (isCooling())
|
else if (isCooling())
|
||||||
{
|
{
|
||||||
if (stage.isCooling())
|
if (stage.isHeating()) {
|
||||||
{
|
GoalHeat = Math.max(stageMin, stageMax - actionsLeft_DeltaHeat);
|
||||||
GoalHeat = Math.max(range[1] - Config.heatingCoolingBuffer(), range[0] + actionsLeft_DeltaHeat);
|
if (StartingHeat > GoalHeat)
|
||||||
|
{
|
||||||
|
int duration = HeatActionSolver.findDx0Index(
|
||||||
|
StartingHeat - GoalHeat,
|
||||||
|
Math.abs(Velocity), Math.abs(AccelerationBonus)
|
||||||
|
) - 1;
|
||||||
|
|
||||||
|
GoalHeat += duration / 2;
|
||||||
|
|
||||||
|
EstimatedDuration = HeatActionSolver.findDx0Index(
|
||||||
|
(StartingHeat - GoalHeat),
|
||||||
|
Math.abs(Velocity), Math.abs(AccelerationBonus)
|
||||||
|
) - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EstimatedDuration = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Heating Stage
|
||||||
|
else {
|
||||||
|
GoalHeat = Math.max(stageMax, stageMin + actionsLeft_DeltaHeat);
|
||||||
if (StartingHeat > GoalHeat) // too hot
|
if (StartingHeat > GoalHeat) // too hot
|
||||||
{
|
{
|
||||||
|
int duration = HeatActionSolver.findDx0Index(
|
||||||
|
StartingHeat - GoalHeat,
|
||||||
|
Math.abs(Velocity), Math.abs(AccelerationBonus)
|
||||||
|
);
|
||||||
|
|
||||||
|
GoalHeat -= duration / 2;
|
||||||
|
|
||||||
EstimatedDuration = HeatActionSolver.findDx0Index(
|
EstimatedDuration = HeatActionSolver.findDx0Index(
|
||||||
StartingHeat - GoalHeat,
|
StartingHeat - GoalHeat,
|
||||||
Math.abs(Velocity), Math.abs(AccelerationBonus)
|
Math.abs(Velocity), Math.abs(AccelerationBonus)
|
||||||
@@ -172,21 +214,7 @@ public class HeatActionStateMachine
|
|||||||
EstimatedDuration = 0;
|
EstimatedDuration = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Heating Stage
|
|
||||||
{
|
|
||||||
GoalHeat = Math.max(range[0] + Config.heatingCoolingBuffer(), range[1] - actionsLeft_DeltaHeat);
|
|
||||||
if (StartingHeat > GoalHeat)
|
|
||||||
{
|
|
||||||
EstimatedDuration = HeatActionSolver.findDx0Index(
|
|
||||||
(StartingHeat - GoalHeat),
|
|
||||||
Math.abs(Velocity), Math.abs(AccelerationBonus)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EstimatedDuration = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class HeatSolverTest
|
|||||||
|
|
||||||
for (int i = 0; i < answer_dx1.length; i++)
|
for (int i = 0; i < answer_dx1.length; i++)
|
||||||
{
|
{
|
||||||
TestHeatSolver_Dx0_Helper(answer_dx0.get(i), answer_dx0.get(0), i + 1);
|
TestHeatSolver_Dx0_Helper(answer_dx0.get(i), answer_dx0.get(0), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,9 @@ public class HeatSolverTest
|
|||||||
// System.err.println(
|
// System.err.println(
|
||||||
// HeatSolver.findDx0IndexContinue(1000, 7, 0));
|
// HeatSolver.findDx0IndexContinue(1000, 7, 0));
|
||||||
System.err.println(
|
System.err.println(
|
||||||
HeatActionSolver.findDx0Index(1000, 7, 1));
|
HeatActionSolver.findDx0Index(957, 27, 2));
|
||||||
|
// System.err.println(
|
||||||
|
// HeatActionSolver.findDx0Index(1000, 7, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TestHeatSolver_Dx0_Helper(int dx0, int constant, int answer_index)
|
public void TestHeatSolver_Dx0_Helper(int dx0, int constant, int answer_index)
|
||||||
@@ -139,7 +141,7 @@ public class HeatSolverTest
|
|||||||
System.err.print(dx0 + "->" + HeatActionSolver.findDx0Index(dx0, constant, 0) + ",");
|
System.err.print(dx0 + "->" + HeatActionSolver.findDx0Index(dx0, constant, 0) + ",");
|
||||||
|
|
||||||
// test calcDx0Index
|
// test calcDx0Index
|
||||||
assertEquals("Asserting dx0 index for " + answer_index,
|
assertEquals("Asserting dx0 for index " + answer_index,
|
||||||
answer_index, HeatActionSolver.findDx0Index(dx0, constant, 0));
|
answer_index, HeatActionSolver.findDx0Index(dx0, constant, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user