//The procedure movePuzzle gets a valid random direction that the blank square of the //puzzle can move in. Once a direction is found the blank square is updated and the //square that is in the place where the blank square was moved to moves to the original //location of the blank square simulataneously. So x goes to where y was and y goes to //where x was. This is counted as a single move. static private void movePuzzle() { Random ran = new Random(); //while loop calls the isValidMove static function of this class till a true a value //is return from the function to ensure a valid direction is chosen. int direction = ran.Next(4); while (!isValidMove(direction)) { direction = ran.Next(4); } if (direction == 0) //Move Left { PuzzleData.moveLeft(PuzzleData.xPuzzle, PuzzleData.yPuzzle); } else if (direction == 1) //Move Up { PuzzleData.moveUp(PuzzleData.xPuzzle, PuzzleData.yPuzzle); } else if (direction == 2) //Move Right { PuzzleData.moveRight(PuzzleData.xPuzzle, PuzzleData.yPuzzle); } else if (direction == 3) //Move Down { PuzzleData.moveDown(PuzzleData.xPuzzle, PuzzleData.yPuzzle); } }
//Method that updates the puzzle with the direction popped of the DFS stack. Then adds the new puzzle state //to the visited list. static private void movePuzzle() { int direction = (int)stackDFS.Pop(); if (direction == 0) //Move Left { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); } else if (direction == 1) //Move Up { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); } else if (direction == 2) //Move Right { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); } else if (direction == 3) //Move Down { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); } //if the trackBack flag is set as there were no moves, it doesn't add the move to the movesList stack. if (!trackBack) { addMove(direction); } addVisitedList(); trackBack = false; }
//Method that updates the puzzle with the direction popped of the DFS stack. Then adds the new puzzle state //to the visited list. static private void movePuzzle() { if (stackProgDFS.Count == 0) { xVisitedList.Clear(); yVisitedList.Clear(); depth++; return; } int direction = (int)stackProgDFS.Pop(); //while (!isValidMove(direction)) //{ // if (stackProgDFS.Count > 0) { direction = (int)stackProgDFS.Pop(); } else { return; } //} if (direction == 0) //Move Left { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); } else if (direction == 1) //Move Up { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); } else if (direction == 2) //Move Right { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); } else if (direction == 3) //Move Down { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); } //only add move to move stack if track back hasn't been set if (!trackBack) { addMove(direction); } addVisitedList(); trackBack = false; }
//The method below checks for a valid move and then checks if the state has been visited //if not the it adds that direction to the stackProgDFS variable. static private void addNextMove() { bool moveAdded = false; if (depthCounter >= depth) { previousState(moveAdded); return; } if ((isValidMove(0)) && (!moveAdded)) { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); stackProgDFS.Push(0); moveAdded = true; } } if ((isValidMove(1)) && (!moveAdded)) { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); stackProgDFS.Push(1); moveAdded = true; } } if ((isValidMove(2)) && (!moveAdded)) { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); stackProgDFS.Push(2); moveAdded = true; } } if ((isValidMove(3)) && (!moveAdded)) { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); stackProgDFS.Push(3); moveAdded = true; } } if (!moveAdded) { previousState(moveAdded); } else { depthCounter++; } }
//Addes a move into the openStates list. Different from the other two algorithms, instead of adding a //direction it creates a new state instance which reflects the possible moves and add that to the openStates //list. static private void addNextMove() { ArrayList possibleMoves = new ArrayList(4); for (int i = 0; i < 4; i++) { possibleMoves.Add(-1); } bool moveAdded = false; if (isValidMove(0)) { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); } else { State st = new State(getManhattanDistance(0), xTempPuzzle, yTempPuzzle, 0); openStates.Add(st); PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); moveAdded = true; } } if (isValidMove(1)) { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); } else { State st = new State(getManhattanDistance(1), xTempPuzzle, yTempPuzzle, 1); openStates.Add(st); PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); moveAdded = true; } } if (isValidMove(2)) { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); } else { State st = new State(getManhattanDistance(2), xTempPuzzle, yTempPuzzle, 2); openStates.Add(st); PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); moveAdded = true; } } if (isValidMove(3)) { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); } else { State st = new State(getManhattanDistance(3), xTempPuzzle, yTempPuzzle, 3); openStates.Add(st); PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); moveAdded = true; } } //if there is no move possible then the algorithm backtracks. if (!moveAdded) { int lastMove = (int)State.directions.Pop(); if (lastMove == 0) { lastMove = 2; } else if (lastMove == 1) { lastMove = 3; } else if (lastMove == 2) { lastMove = 0; } else if (lastMove == 3) { lastMove = 1; } State.directions.Push(lastMove); trackBack = true; } }
//The method below checks for a valid move and then checks if the state has been visited //if not the it adds that direction to the stackDFS variable. static private void addNextMove() { bool moveAdded = false; if (isValidMove(0)) { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); stackDFS.Push(0); moveAdded = true; } } if (isValidMove(1)) { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); stackDFS.Push(1); moveAdded = true; } } if (isValidMove(2)) { PuzzleData.moveRight(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveLeft(xTempPuzzle, yTempPuzzle); stackDFS.Push(2); moveAdded = true; } } if (isValidMove(3)) { PuzzleData.moveDown(xTempPuzzle, yTempPuzzle); if (isVisitedState()) { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); } else { PuzzleData.moveUp(xTempPuzzle, yTempPuzzle); stackDFS.Push(3); moveAdded = true; } } //if no move could be found happens when the current state cannot get out because all the //neighbouring states have already been expanded. It adds the opposite of the last move made //which makes the puzzle go back one step. if (!moveAdded) { int lastMove = (int)stackMoves.Pop(); if (lastMove == 0) { lastMove = 2; } else if (lastMove == 1) { lastMove = 3; } else if (lastMove == 2) { lastMove = 0; } else if (lastMove == 3) { lastMove = 1; } stackDFS.Push(lastMove); trackBack = true; //trackBack flag is set for the movePuzzle method. see there for more explanation. } }