package rabbitescape.engine.solution;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
import org.junit.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import rabbitescape.engine.Token;
import rabbitescape.engine.World.CompletionState;
public class TestSolutionInterpreter
{
private static final CompletionState R = CompletionState.RUNNING;
private static final CompletionState W = CompletionState.WON;
private static final CompletionState L = CompletionState.LOST;
@Test
public void Empty_solution_does_nothing()
{
Solution solution = new Solution();
SolutionInterpreter interpreter =
new SolutionInterpreter( solution, false );
assertThat( interpreter.next( R ), nullValue() );
}
@Test
public void One_wait_waits_for_that_long()
{
Solution solution = new Solution(
new SolutionCommand( new WaitAction( 3 ) ) );
SolutionInterpreter interpreter =
new SolutionInterpreter(solution, false );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep( 1 )
, new SolutionTimeStep( 1 )
, new SolutionTimeStep( 1 )
)
)
);
}
@Test
public void Single_nonwait_action_makes_single_time_step()
{
Solution solution = new Solution(
new SolutionCommand( new SelectAction( Token.Type.explode ) )
);
SolutionInterpreter interpreter =
new SolutionInterpreter( solution, false );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1, new SelectAction( Token.Type.explode ) )
)
)
);
}
@Test
public void Multiple_nonwait_actions_in_single_cmd_make_1_time_step()
{
Solution solution = new Solution(
new SolutionCommand(
new SelectAction( Token.Type.explode ),
new PlaceTokenAction( 2, 2 )
)
);
SolutionInterpreter interpreter =
new SolutionInterpreter( solution, false );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1
, new SelectAction( Token.Type.explode )
, new PlaceTokenAction( 2, 2 )
)
)
)
);
}
@Test
public void Do_then_wait_then_do_translates_into_time_steps()
{
Solution solution = new Solution(
new SolutionCommand(
new SelectAction( Token.Type.explode ),
new PlaceTokenAction( 2, 2 )
),
new SolutionCommand( new WaitAction( 4 ) ),
new SolutionCommand( new PlaceTokenAction( 3, 2 ) )
);
SolutionInterpreter interpreter =
new SolutionInterpreter( solution, false );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1
, new SelectAction( Token.Type.explode )
, new PlaceTokenAction( 2, 2 )
),
new SolutionTimeStep( 2 ),
new SolutionTimeStep( 2 ),
new SolutionTimeStep( 2 ),
new SolutionTimeStep( 2 ),
new SolutionTimeStep( 3, new PlaceTokenAction( 3, 2 ) )
)
)
);
}
@Test
public void Wait_then_do_then_wait_translates_into_time_steps()
{
Solution solution = new Solution(
new SolutionCommand(),
new SolutionCommand( new WaitAction( 1 ) ),
new SolutionCommand(
new SelectAction( Token.Type.explode ),
new PlaceTokenAction( 2, 2 )
),
new SolutionCommand( new WaitAction( 2 ) ),
new SolutionCommand()
);
SolutionInterpreter interpreter = new SolutionInterpreter(
solution, false );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep( 1 ),
new SolutionTimeStep( 2 ),
new SolutionTimeStep(
3
, new SelectAction( Token.Type.explode )
, new PlaceTokenAction( 2, 2 )
),
new SolutionTimeStep( 4 ),
new SolutionTimeStep( 4 ),
new SolutionTimeStep( 5 )
)
)
);
}
@Test
public void Empty_command_is_like_wait_1()
{
Solution solution = new Solution(
new SolutionCommand()
);
SolutionInterpreter interpreter =
new SolutionInterpreter( solution, false );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep( 1 )
)
)
);
}
@Test
public void Many_empty_commands()
{
Solution solution = new Solution(
new SolutionCommand(),
new SolutionCommand( new SelectAction( Token.Type.dig ) ),
new SolutionCommand( new PlaceTokenAction( 1, 1 ) ),
new SolutionCommand(
new AssertStateAction( CompletionState.RUNNING ) ),
new SolutionCommand(),
new SolutionCommand(),
new SolutionCommand()
);
SolutionInterpreter interpreter =
new SolutionInterpreter( solution, false );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep( 1 ),
new SolutionTimeStep(
2, new SelectAction( Token.Type.dig ) ),
new SolutionTimeStep( 3, new PlaceTokenAction( 1, 1 ) ),
new SolutionTimeStep(
4, new AssertStateAction( CompletionState.RUNNING ) ),
new SolutionTimeStep( 5 ),
new SolutionTimeStep( 6 ),
new SolutionTimeStep( 7 )
)
)
);
}
@Test
public void If_no_commands_we_do_a_final_assert()
{
Solution solution = new Solution();
SolutionInterpreter interpreter = new SolutionInterpreter( solution );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1, new AssertStateAction( CompletionState.WON ) )
)
)
);
}
@Test
public void If_normal_commands_we_do_a_final_assert()
{
Solution solution = new Solution(
new SolutionCommand(
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 ) ),
new SolutionCommand( new PlaceTokenAction( 1, 1 ) )
);
SolutionInterpreter interpreter = new SolutionInterpreter( solution );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1,
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 )
),
new SolutionTimeStep( 2, new PlaceTokenAction( 1, 1 ) ),
new SolutionTimeStep(
3, new AssertStateAction( CompletionState.WON ) )
)
)
);
}
@Test
public void If_last_command_is_empty_we_do_a_final_assert()
{
Solution solution = new Solution(
new SolutionCommand(
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 )
),
new SolutionCommand( new PlaceTokenAction( 1, 1 ) ),
new SolutionCommand()
);
SolutionInterpreter interpreter = new SolutionInterpreter( solution );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1,
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 )
),
new SolutionTimeStep( 2, new PlaceTokenAction( 1, 1 ) ),
new SolutionTimeStep( 3 ),
new SolutionTimeStep(
4, new AssertStateAction( CompletionState.WON ) )
)
)
);
}
@Test
public void If_last_command_is_assert_we_do_not_add_an_assert()
{
Solution solution = new Solution(
new SolutionCommand(
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 ) ),
new SolutionCommand( new PlaceTokenAction( 1, 1 ) ),
new SolutionCommand(
new AssertStateAction( CompletionState.LOST ) )
);
SolutionInterpreter interpreter = new SolutionInterpreter( solution );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1,
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 )
),
new SolutionTimeStep( 2, new PlaceTokenAction( 1, 1 ) ),
new SolutionTimeStep(
3, new AssertStateAction( CompletionState.LOST ) )
)
)
);
}
@Test
public void If_assert_then_wait_we_do_add_a_final_assert()
{
Solution solution = new Solution(
new SolutionCommand(
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 )
),
new SolutionCommand( new PlaceTokenAction( 1, 1 ) ),
new SolutionCommand(
new AssertStateAction( CompletionState.WON ) ),
new SolutionCommand()
);
SolutionInterpreter interpreter = new SolutionInterpreter( solution );
assertThat(
interpreterList( interpreter ),
equalTo(
Arrays.asList(
new SolutionTimeStep(
1,
new SelectAction( Token.Type.dig ),
new PlaceTokenAction( 1, 1 )
),
new SolutionTimeStep( 2, new PlaceTokenAction( 1, 1 ) ),
new SolutionTimeStep(
3, new AssertStateAction( CompletionState.WON ) ),
new SolutionTimeStep( 4 ),
new SolutionTimeStep(
5, new AssertStateAction( CompletionState.WON ) )
)
)
);
}
@Test
public void Until_stops_with_assert_when_won()
{
// Just one until action ...
Solution solution = new Solution(
new SolutionCommand( new UntilAction( CompletionState.WON ) )
);
SolutionInterpreter i = new SolutionInterpreter( solution );
// ... leads to lots of time steps...
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 1 ) ) );
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 1 ) ) );
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 1 ) ) );
// ... and when we've finished, an assert.
assertThat(
i.next( W ),
equalTo(
new SolutionTimeStep(
1
, new AssertStateAction( CompletionState.WON )
)
)
);
// Then we're done
assertThat( i.next( R ), nullValue() );
}
@Test
public void Until_stops_with_assert_when_lost_after_other_steps()
{
// Actions followed by an Until
Solution solution = new Solution(
new SolutionCommand( new WaitAction( 2 ) ),
new SolutionCommand( new SelectAction( Token.Type.bridge ) ),
new SolutionCommand( new PlaceTokenAction( 2, 3 ) ),
new SolutionCommand( new UntilAction( CompletionState.WON ) )
);
SolutionInterpreter i = new SolutionInterpreter( solution );
// Leads to actions, followed by waiting
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 1 ) ) );
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 1 ) ) );
assertThat(
i.next( R ),
equalTo(
new SolutionTimeStep(
2,
new SelectAction( Token.Type.bridge )
)
)
);
assertThat(
i.next( R ),
equalTo(
new SolutionTimeStep( 3, new PlaceTokenAction( 2, 3 ) )
)
);
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 4 ) ) );
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 4 ) ) );
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 4 ) ) );
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 4 ) ) );
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 4 ) ) );
// ... until we lose (i.e. not running) at which time we assert.
assertThat(
i.next( L ),
equalTo(
new SolutionTimeStep(
4
, new AssertStateAction( CompletionState.WON )
)
)
);
// Then we're done
assertThat( i.next( R ), nullValue() );
}
@Test
public void Until_can_assert_lost()
{
// Just one until action ...
Solution solution = new Solution(
new SolutionCommand( new UntilAction( CompletionState.LOST ) )
);
SolutionInterpreter i = new SolutionInterpreter( solution );
// ... leads to lots of time steps...
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 1 ) ) );
// ... and when we've finished, an assert.
assertThat(
i.next( W ),
equalTo(
new SolutionTimeStep(
1
, new AssertStateAction( CompletionState.LOST )
)
)
);
// Then we're done
assertThat( i.next( R ), nullValue() );
}
@Test( expected = SolutionExceptions.UntilActionNeverEnded.class )
public void Until_stops_and_fails_after_many_time_steps()
{
Solution solution = new Solution(
new SolutionCommand( new UntilAction( CompletionState.LOST ) ) );
SolutionInterpreter i = new SolutionInterpreter( solution );
for ( int n = 0; n < 2000; ++n )
{
assertThat( i.next( R ), equalTo( new SolutionTimeStep( 1 ) ) );
}
}
// ---
private List<SolutionTimeStep> interpreterList(
SolutionInterpreter interpreter )
{
List<SolutionTimeStep> ret = new ArrayList<SolutionTimeStep>();
for (
SolutionTimeStep step = interpreter.next( R );
step != null;
step = interpreter.next( R )
)
{
ret.add( step );
}
return ret;
}
}