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; } }