private void CreateBidirectionalSolution(BoardNode forwardNode, BoardNode reverseNode, char tile) { solution.StopTime(); solution.IsSolved = true; //get move path to forwardNode var currentNode = forwardNode; solution.MoveList = new List <BoardNode> { currentNode }; while (currentNode.Previous != null) { solution.MoveList.Insert(0, currentNode.Previous); currentNode = currentNode.Previous; } //get move path from forwardNode to reverseNode while (true) { var connectNode = new BoardNode(forwardNode, reverseNode.Board, tile); tile = reverseNode.TileMoved; solution.MoveList.Add(connectNode); if (reverseNode.Previous == null) { break; } reverseNode = reverseNode.Previous; } solution.EndBoard = solution.MoveList.Last().Board; }
public void Push(BoardNode node) { if (node.Cost <= Depth) { stack.Push(node); } else { queue.Insert(0, node); } }
private void UpgradeChildren(INodeList openList, BoardNode visitedNode) { return; foreach (var node in visitedNodes.Where(node => node.Value.Previous == visitedNode)) { node.Value.Cost = visitedNode.Cost + 1; if (openList.Upgrade(node.Value)) { UpgradeChildren(openList, node.Value); } } }
public bool Upgrade(BoardNode node) { if (CanDeepen || node.Cost > Depth) { return(false); } if (queue.Contains(node)) { queue.Remove(node); } Push(node); return(node.Cost + 1 <= Depth); }
public BoardNode(BoardNode previous, TileBoard board, char TileMoved) { this.Previous = previous; this.Board = board; this.TileMoved = TileMoved; if (previous == null) { Cost = 0; } else { Cost = previous.Cost + 1; } }
private void Start(TileBoard inputBoard) { //initialize new solution solution = new Solution(); solution.StartBoard = inputBoard.Copy(); solution.StartTime(); //initialize new visited nodes table visitedNodes = new Dictionary <string, BoardNode>(); //add input board to open node list var startNode = new BoardNode(null, inputBoard, '!'); visitedNodes.Add(inputBoard.ToString(), startNode); solution.ExpandedNodes++; openNodes.Push(startNode); //for bidirectional search, add end node to reverse open list if (bidirectional) { var endBoard = new TileBoard("_12345678"); var endNode = new BoardNode(null, endBoard, '!'); endNode.Reverse = true; visitedNodes.Add(endBoard.ToString(), endNode); solution.ExpandedNodes++; openNodesReverse.Push(endNode); } //start solving while (true) { if (Solve()) { break; } if (bidirectional) { if (Solve(true)) { break; } } } }
private void CreateSolution(BoardNode currentNode) { solution.StopTime(); solution.IsSolved = true; solution.EndBoard = currentNode.Board; //get complete move path solution.MoveList = new List <BoardNode> { currentNode }; while (currentNode.Previous != null) { solution.MoveList.Insert(0, currentNode.Previous); if (solution.MoveList.Count >= 100) { currentNode.Previous.TileMoved = '#'; break; } currentNode = currentNode.Previous; } }
private bool Solve(bool reverse = false) { var openList = openNodes; if (reverse) { openList = openNodesReverse; } //if there are no more open nodes, the puzzle is not solveable if (openList.Count() == 0) { return(true); } //get the next node to be evaluated var currentNode = openList.Pop(); //check if current node is the solved node if (!reverse) { if (currentNode.Board.IsSolved()) { CreateSolution(currentNode); return(true); } } //get adjacent nodes var adjacents = currentNode.Board.GetAdjacents('_'); //if adjacent node hasn't been visited, add it to open nodes foreach (var tile in adjacents) { var newBoard = currentNode.Board.Copy(); newBoard.Switch('_', tile); var newBoardKey = newBoard.ToString(); if (visitedNodes.ContainsKey(newBoardKey)) { var visitedNode = visitedNodes[newBoardKey]; //if new cost to get to this board is less than existing cost, replace it's previous node if (visitedNode.Reverse == reverse) { var newCost = currentNode.Cost + 1; if (visitedNode.Cost > newCost) { visitedNode.Previous = currentNode; visitedNode.TileMoved = tile; visitedNode.Cost = newCost; if (openList.Upgrade(visitedNode)) { UpgradeChildren(openList, visitedNode); } } } else { //piece this thang together, solved it! if (reverse) { CreateBidirectionalSolution(visitedNode, currentNode, tile); } else { CreateBidirectionalSolution(currentNode, visitedNode, tile); } return(true); } continue; } solution.ExpandedNodes++; var newNode = new BoardNode(currentNode, newBoard, tile); newNode.Reverse = reverse; visitedNodes.Add(newBoardKey, newNode); openList.Push(newNode); } return(false); }
public bool Upgrade(BoardNode node) { return(false); }
public void Push(BoardNode node) { stack.Push(node); }
public void Push(BoardNode node) { queue.Enqueue(node); }