Finished tests

This commit is contained in:
Niklas Birk 2019-03-24 16:41:14 +01:00
parent d014b9f686
commit d2c1cb698c
3 changed files with 171 additions and 22 deletions

View File

@ -3,13 +3,15 @@ package search.breadthfirstsearch;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream; import java.util.stream.IntStream;
public class EightPuzzleNode implements Node public class EightPuzzleNode implements Node
{ {
private int[][] state; private int[][] state;
public EightPuzzleNode(int[][] state) { public EightPuzzleNode(int[][] state)
{
if (!isValidState(state)) if (!isValidState(state))
{ {
throw new IllegalArgumentException("Allowed numbers are only 0-8 and they must exist uniquely."); throw new IllegalArgumentException("Allowed numbers are only 0-8 and they must exist uniquely.");
@ -19,44 +21,137 @@ public class EightPuzzleNode implements Node
} }
@Override @Override
public boolean isTargetReached(Node target) { public boolean isTargetReached(Node target)
{
return Arrays.equals(this.state, ((EightPuzzleNode) target).state); return Arrays.equals(this.state, ((EightPuzzleNode) target).state);
} }
@Override @Override
public List<Node> generateSuccessors() { public List<Node> generateSuccessors()
ArrayList<Node> successors = new ArrayList<>(); {
var successors = new ArrayList<Node>();
var emptyPosition = Objects.requireNonNull(detectEmptyPosition());
int x = emptyPosition.getRight();
int y = emptyPosition.getLeft();
successors.add(new EightPuzzleNode(null)); for (Direction dir : Direction.values())
{
var newState = copyOfState();
try
{
int tmp;
switch (dir)
{
case TOP:
tmp = newState[y-1][x];
newState[y-1][x] = newState[y][x];
newState[y][x] = tmp;
successors.add(new EightPuzzleNode(newState));
break;
case RIGHT:
tmp = newState[y][x+1];
newState[y][x+1] = newState[y][x];
newState[y][x] = tmp;
successors.add(new EightPuzzleNode(newState));
break;
case DOWN:
tmp = newState[y+1][x];
newState[y+1][x] = newState[y][x];
newState[y][x] = tmp;
successors.add(new EightPuzzleNode(newState));
break;
case LEFT:
tmp = newState[y][x-1];
newState[y][x-1] = newState[y][x];
newState[y][x] = tmp;
successors.add(new EightPuzzleNode(newState));
break;
}
}
catch (ArrayIndexOutOfBoundsException ignored)
{
}
}
return successors; return successors;
} }
public int[][] getState()
{
return state;
}
private boolean isValidState(int[][] state) private boolean isValidState(int[][] state)
{ {
int[] numbers = Arrays.stream(state).flatMapToInt(IntStream::of).toArray(); var numbers = Arrays.stream(state).flatMapToInt(IntStream::of).toArray();
int[] countOfNumbers = new int[9];
for (int i : numbers) return numbersAreInAllowedRange(numbers) && numbersAreUnique(numbers);
}
private boolean numbersAreInAllowedRange(int[] numbers)
{
return Arrays.stream(numbers).min().getAsInt() == 0 && Arrays.stream(numbers).max().getAsInt() == 8;
}
private boolean numbersAreUnique(int[] numbers)
{
return Arrays.stream(numbers).count() == Arrays.stream(numbers).distinct().count();
}
private IntPair detectEmptyPosition()
{
for (int row = 0; row < this.state.length; row++)
{ {
try for (int col = 0; col < this.state[row].length; col++)
{ {
countOfNumbers[i]++; if (state[row][col] == 0)
} {
catch (ArrayIndexOutOfBoundsException e) return new IntPair(row, col);
{ }
return false;
} }
} }
for (int i : countOfNumbers) return null;
}
private int[][] copyOfState()
{
var copy = new int[3][3];
for (int y = 0; y < copy.length; y++)
{ {
if (i == 0 || i > 1) System.arraycopy(this.state[y], 0, copy[y], 0, copy.length);
{
return false;
}
} }
return true; return copy;
}
private class IntPair
{
private final int left;
private final int right;
public IntPair(int left, int right)
{
this.left = left;
this.right = right;
}
public int getLeft()
{
return left;
}
public int getRight()
{
return right;
}
}
private enum Direction
{
TOP, RIGHT, DOWN, LEFT
} }
} }

View File

@ -0,0 +1,14 @@
package search.breadthfirstsearch;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class BreadthFirstSearchTest
{
@Test
void shouldReturnCorrectTarget()
{
}
}

View File

@ -3,10 +3,9 @@ package search.breadthfirstsearch;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class EightPuzzleNodeTest class EightPuzzleNodeTest
{ {
@Test @Test
@ -84,4 +83,45 @@ class EightPuzzleNodeTest
Assertions.assertFalse(successors.isEmpty()); Assertions.assertFalse(successors.isEmpty());
} }
@Test
public void shouldReturnEmptyListOfSuccessors()
{
}
@Test
public void shouldReturnCorrectSuccessors()
{
int[][] state = {
{7, 1, 6},
{0, 4, 2},
{3, 5, 8}
};
var node = new EightPuzzleNode(state);
var successors = node.generateSuccessors();
Assertions.assertEquals(3, successors.size());
int[][] newState1 = {
{0, 1, 6},
{7, 4, 2},
{3, 5, 8}
};
int[][] newState2 = {
{7, 1, 6},
{4, 0, 2},
{3, 5, 8}
};
int[][] newState3 = {
{7, 1, 6},
{3, 4, 2},
{0, 5, 8}
};
Assertions.assertArrayEquals(newState1, ((EightPuzzleNode) successors.get(0)).getState());
Assertions.assertArrayEquals(newState2, ((EightPuzzleNode) successors.get(1)).getState());
Assertions.assertArrayEquals(newState3, ((EightPuzzleNode) successors.get(2)).getState());
}
} }