package rabbitescape.engine.solution;
import rabbitescape.engine.Token;
import rabbitescape.engine.World;
import rabbitescape.engine.World.CompletionState;
import rabbitescape.engine.err.RabbitEscapeException;
public class SolutionExceptions
{
/**
* Base class for everything that can go wrong when running a solution.
* The member variables get filled in as we roll up the stack through
* the command we are on, and the solution we are running.
*/
public static abstract class ProblemRunningSolution
extends RabbitEscapeException
{
private static final long serialVersionUID = 1L;
public int solutionId = -1;
public int commandIndex = -1;
public String level = "<>";
public String world = "";
public ProblemRunningSolution()
{
}
public ProblemRunningSolution( Throwable cause )
{
super( cause );
}
}
/**
* Indicates that a world was not in the state we asserted it should
* be in, in our solution.
*/
public static class UnexpectedState extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public final CompletionState expected;
public final CompletionState actual;
public UnexpectedState(
CompletionState expected, CompletionState actual )
{
this.expected = expected;
this.actual = actual;
}
}
/**
* Special subclass of UnexpectedState for when the expected state
* was "WON" - a separate exception so we can give a clearer error message
* in this common case.
*/
public static class DidNotWin extends UnexpectedState
{
private static final long serialVersionUID = 1L;
public DidNotWin( CompletionState actualState )
{
super( CompletionState.WON, actualState );
}
}
/**
* The solution went on longer, but the world was at WON or LOST.
*/
public static class RanPastEnd extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public final CompletionState worldState;
public RanPastEnd( CompletionState worldState )
{
this.worldState = worldState;
}
}
/**
* We used a token that we've already used up.
*/
public static class UsedRunOutAbility extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public final Token.Type ability;
public UsedRunOutAbility( Token.Type ability )
{
this.ability = ability;
}
}
/**
* We used a token that was not available in this world.
*/
public static class UsedMissingAbility extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public final Token.Type ability;
public UsedMissingAbility( Token.Type ability )
{
this.ability = ability;
}
}
/**
* We placed a token outside the size of this world.
*/
public static class PlacedTokenOutsideWorld extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public final int x;
public final int y;
public final int worldWidth;
public final int worldHeight;
public PlacedTokenOutsideWorld(
int x,
int y,
int worldWidth,
int worldHeight
)
{
this.x = x;
this.y = y;
this.worldWidth = worldWidth;
this.worldHeight = worldHeight;
}
}
/**
* We placed a token but the world wouldn't accept it (presumably because
* there was a block at that position).
*/
public static class FailedToPlaceToken extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public final int x;
public final int y;
public final Token.Type type;
public FailedToPlaceToken(
int x,
int y,
Token.Type type
)
{
this.x = x;
this.y = y;
this.type = type;
}
}
/**
* We had an until action, but the level never ended.
*/
public static class UntilActionNeverEnded extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public final World.CompletionState expectedState;
public UntilActionNeverEnded( World.CompletionState expectedState )
{
this.expectedState = expectedState;
}
}
/**
* Some other exception was thrown.
*/
public static class UnknownProblem extends ProblemRunningSolution
{
private static final long serialVersionUID = 1L;
public UnknownProblem( Throwable cause )
{
super( cause );
}
}
}