package framework;
import graph.DequeAdder;
import java.util.Deque;
import bridge.BridgeProblem;
import bridge.BridgeState;
import bridge.Position;
import graph.Vertex;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* This class tests your implementation of the expand and search
* algorithms used in depth-first and breadth-first state space search.
* It depends on your bridge crossing application being correctly implemented.
* @author tcolburn
*/
public class ProblemTest {
public ProblemTest() {
problem = new BridgeProblem();
start =
new BridgeState(Position.WEST,
Position.WEST,
Position.WEST,
Position.WEST,
Position.WEST,
0);
goal =
new BridgeState(Position.EAST,
Position.EAST,
Position.EAST,
Position.EAST,
Position.EAST,
17);
/**
* The following states are used in testExpand1 and testSearch2
*/
p1East =
new BridgeState(Position.EAST,
Position.WEST,
Position.EAST,
Position.WEST,
Position.WEST,
0);
p2East =
new BridgeState(Position.WEST,
Position.EAST,
Position.EAST,
Position.WEST,
Position.WEST,
0);
p5East =
new BridgeState(Position.WEST,
Position.WEST,
Position.EAST,
Position.EAST,
Position.WEST,
0);
p10East =
new BridgeState(Position.WEST,
Position.WEST,
Position.EAST,
Position.WEST,
Position.EAST,
0);
p1p2East =
new BridgeState(Position.EAST,
Position.EAST,
Position.EAST,
Position.WEST,
Position.WEST,
0);
p1p5East =
new BridgeState(Position.EAST,
Position.WEST,
Position.EAST,
Position.EAST,
Position.WEST,
0);
p1p10East =
new BridgeState(Position.EAST,
Position.WEST,
Position.EAST,
Position.WEST,
Position.EAST,
0);
p2p5East =
new BridgeState(Position.WEST,
Position.EAST,
Position.EAST,
Position.EAST,
Position.WEST,
0);
p2p10East =
new BridgeState(Position.WEST,
Position.EAST,
Position.EAST,
Position.WEST,
Position.EAST,
0);
p5p10East =
new BridgeState(Position.WEST,
Position.WEST,
Position.EAST,
Position.EAST,
Position.EAST,
0);
/**
* The following states are used in testExpand2
*/
p1p5p10West =
new BridgeState(Position.WEST,
Position.EAST,
Position.WEST,
Position.WEST,
Position.WEST,
0);
p2p5p10West =
new BridgeState(Position.EAST,
Position.WEST,
Position.WEST,
Position.WEST,
Position.WEST,
0);
p1p2p5p10West =
new BridgeState(Position.WEST,
Position.WEST,
Position.WEST,
Position.WEST,
Position.WEST,
0);
/**
* The following state is used in testSearch1
*/
p1p2West =
new BridgeState(Position.WEST,
Position.WEST,
Position.WEST,
Position.EAST,
Position.EAST,
15);
/**
* The following states are used in testSearch2
*/
p2p5p10East =
new BridgeState(Position.WEST,
Position.EAST,
Position.EAST,
Position.EAST,
Position.EAST,
13);
p1p5p10East =
new BridgeState(Position.EAST,
Position.WEST,
Position.EAST,
Position.EAST,
Position.EAST,
14);
/**
* This DequeAdder is used to perform breadth-first search in
* testSearch1 and testSearch2
*/
tailAdder = new DequeAdder() {
public void add(Vertex vertex, Deque deque) {
deque.addLast(vertex);
}
};
}
/**
* This test expands the start state, checks to make sure there are
* ten children, and they are the correct children
*/
@Test
public void testExpand1() {
List children = problem.expand(start);
assertTrue( children.size() == 10 );
nextStates = new Vertex[] {p1East, p2East, p5East, p10East, p1p2East,
p1p5East, p1p10East, p2p5East, p2p10East, p5p10East};
for (Vertex next: nextStates) {
assertTrue( children.contains(next));
}
}
/**
* This test expands the state where P1, P2, and the flashlight are on the
* east side, checks to make sure there are three children, and they are the
* correct children.
*/
@Test
public void testExpand2() {
List children = problem.expand(p1p2East);
assertTrue( children.size() == 3 );
nextStates = new Vertex[] {p1p5p10West, p2p5p10West, p1p2p5p10West};
for (Vertex next: nextStates) {
assertTrue( children.contains(next));
}
}
/**
* This test performs a breadth-first search on a state that is one
* step from the goal state. It checks to make sure that the goal
* state is found, and that the goal's predecessor was correctly set.
* It also displays the solution in the console.
*/
@Test
public void testSearch1() {
Vertex found = problem.search(p1p2West, tailAdder);
assertTrue( ((BridgeState) found).equals(goal) );
assertTrue( found.getPredecessor().equals(p1p2West) );
displaySolution(found);
}
/**
* This test performs a breadth-first search on the normal start state.
* It checks to make sure that the goal state is found, and that the
* predecessors of all the goal's ancestors were correctly set.
* It also displays the solution in the console.
*/
@Test
public void testSearch2() {
Vertex found = problem.search(start, tailAdder);
assertTrue( ((BridgeState) found).equals(goal) );
Vertex ancestor = found.getPredecessor();
assertTrue( ancestor.equals(p1p2West) );
ancestor = ancestor.getPredecessor();
assertTrue( ancestor.equals(p2p5p10East) || ancestor.equals(p1p5p10East) );
ancestor = ancestor.getPredecessor();
assertTrue( ancestor.equals(p1p5p10West) || ancestor.equals(p2p5p10West));
ancestor = ancestor.getPredecessor();
assertTrue( ancestor.equals(p1p2East) );
ancestor = ancestor.getPredecessor();
assertTrue( ancestor.equals(start) );
displaySolution(found);
}
/**
* Displays the solution to the console by recursing to the start state
* and then individually displaying states as the recursion is unwound.
* @param state the terminating state in the solution path
*/
private void displaySolution(Vertex state) {
if ( state != null ) {
displaySolution(state.getPredecessor());
System.out.println(state.toString());
}
}
private Problem problem;
private Vertex start;
private Vertex goal;
private Vertex p1East;
private Vertex p2East;
private Vertex p5East;
private Vertex p10East;
private Vertex p1p2East;
private Vertex p1p5East;
private Vertex p1p10East;
private Vertex p2p5East;
private Vertex p2p10East;
private Vertex p5p10East;
private Vertex p1p5p10West;
private Vertex p2p5p10West;
private Vertex p1p2p5p10West;
private Vertex p1p2West;
private Vertex p1p5p10East;
private Vertex p2p5p10East;
/**
* The following array is used in testExpand1 and testExpand2
*/
private Vertex[] nextStates;
private DequeAdder tailAdder;
}