我目前正在尝试使用BFS创建和解决滑块难题。我创建了自己的名为gamestate的对象来存储父gamestate和新的gamestate。我遇到的问题是我没有正确存储父状态,因为当我调用以获取树的所有相邻顶点时,它们没有使用自己的父级。让我展示我的测试以解释更多信息。这是我的GameState对象代码-
public class GameState {
public int[][] state; //state of the puzzle
public GameState parent; //parent in the game tree
public GameState() {
//initialize state to zeros, parent to null
state = new int[0][0];
parent = null;
}
public GameState(int[][] state) {
//initialize this.state to state, parent to null
this.state = new int[3][3];
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
this.state[i][j] = state[i][j];
}
}
parent = null;
}
public GameState(int[][] state, GameState parent) {
//initialize this.state to state, this.parent to parent
this.state = new int[3][3];
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
this.state[i][j] = state[i][j];
}
}
this.parent = parent;
}
public GameState swapRight(GameState s, int row, int col) {
//helper function to swap blank space with right block
// row and col are where the zero index is
s.parent = s;
int temp = state[row][col+1];
s.state[row][col+1] = state[row][col];
s.state[row][col] = temp;
return s;
}
public GameState swapLeft(GameState s, int row, int col) {
//helper function to swap blank space with left block
s.parent = s;
int temp = state[row][col]; // Mark zero as temp
s.state[row][col] = state[row][col-1];
s.state[row][col-1] = temp;
return s;
}
public GameState swapUp(GameState s, int row, int col) {
s.parent = s;
int temp = state[row][col]; // Mark zero as temp
s.state[row][col] = state[row-1][col];
s.state[row-1][col] = temp;
return s;
}
public GameState swapDown(GameState s, int row, int col) {
//helper function to swap blank space with down block
s.parent = s;
int temp = state[row][col];
s.state[row][col] = state[row+1][col];
s.state[row+1][col] = temp;
return s;
}
public boolean isEnd() {
//helper function to check if the GameState is the end state e.g.
//0 1 2
//3 4 5
//6 7 8
//Stores indexes of zero element
GameState testEnd = new GameState();
int[][] t1 = {{0,1,2},{3,4,5},{6,7,8}};
int[][] t2 = {{8,0,1},{2,3,4},{5,6,7}};
int[][] t3 = {{7,8,0},{1,2,3},{4,5,6}};
int[][] t4 = {{6,7,8},{0,1,2},{3,4,5}};
int[][] t5 = {{5,6,7},{8,0,1},{2,3,4}};
int[][] t6 = {{4,5,6},{7,8,0},{1,2,3}};
int[][] t7 = {{3,4,5},{6,7,8},{0,1,2}};
int[][] t8 = {{2,3,4},{5,6,7},{8,0,1}};
int[][] t9 = {{1,2,3},{4,5,6},{7,8,0}};
testEnd.state = t1;
if(this.equals(testEnd)) return true;
testEnd.state = t2;
if(this.equals(testEnd)) return true;
testEnd.state = t3;
if(this.equals(testEnd)) return true;
testEnd.state = t4;
if(this.equals(testEnd)) return true;
testEnd.state = t5;
if(this.equals(testEnd)) return true;
testEnd.state = t6;
if(this.equals(testEnd)) return true;
testEnd.state = t7;
if(this.equals(testEnd)) return true;
testEnd.state = t8;
if(this.equals(testEnd)) return true;
testEnd.state = t9;
if(this.equals(testEnd)) return true;
return false;
}
public ArrayList<GameState> getAdjacent() {
//Use the swap functions to generate the new vertices of the tree
//Beware of the boundary conditions, i.e. don’t swap left when you are
//already on the left edge
ArrayList<GameState> vertices = new ArrayList<>();
int row = 0;
int col = 0;
//Gets index of our zero element
for (int i = 0 ; i < this.state.length; i++) {
for (int j = 0; j < this.state.length; j++) {
if (this.state[i][j] == 0) {
row = i;
col = j;
}
}
}
//Checking if we can swap up
if(row != 0) {
vertices.add(swapUp(this, row, col));
}
//Checking if we can swap down
if(row != 2) {
vertices.add(swapDown(this, row, col));
}
//Checking if we can swap left
if(col != 0) {
vertices.add(swapLeft(this, row, col));
}
//Checking if we can swap right
if(col != 2) {
vertices.add(swapRight(this, row, col));
}
return vertices;
}
@Override
public boolean equals(Object o) {
//test that 2 GameStates are equal
if (!(o instanceof GameState)) return false;
GameState that = (GameState) o;
return Arrays.deepEquals(this.state, that.state);
}
@Override
public String toString() {
// print out the int[][] array in a 3x3 block e.g.
//0 1 2
//3 4 5
//6 7 8
String result = Arrays
.stream(state)
.map(Arrays::toString)
.collect(Collectors.joining(System.lineSeparator()));
return result;
}
}
我正在测试的主要方法是我正在测试的问题是否在1-4种不同情况下调用getAdjacent结果,但是它们都在打印相同的情况。我的主要方法调用-
int[][] tArr = {{1,5,2},{3,4,0},{6,8,7}}; //start state, i.e. tree root
GameState start = new GameState(tArr,null); // state with tArr state, null parent
explored = new ArrayList<GameState>();
frontier = new ArrayDeque<GameState>();
frontier.add(start);
while(!frontier.isEmpty())
{
explored.add(frontier.remove());
System.out.println(start);
if(start.isEnd())
{
break;
}
ArrayList<GameState> vertices = start.getAdjacent();
System.out.println(vertices.size());
for(int i=0; i<vertices.size(); i++)
{
System.out.println(i);
if(!explored.contains(vertices.get(i)))
{
frontier.add(vertices.get(i));
}
System.out.println(vertices.get(i));
}
System.out.println(frontier.size());
}
这是我收到的输出-
[1, 5, 2]
[3, 4, 0]
[6, 8, 7]
3
0
[1, 5, 0]
[3, 7, 4]
[6, 8, 2]
1
[1, 5, 0]
[3, 7, 4]
[6, 8, 2]
2
[1, 5, 0]
[3, 7, 4]
[6, 8, 2]
0
如您所见,它只是交换。