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;
        }
        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 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;
 }
Example #4
0
 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);
                }
            }
        }
Example #6
0
 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;
     }
 }
Example #7
0
        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);
        }
        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;
            }
        }
 public bool Upgrade(BoardNode node)
 {
     return false;
 }
 public void Push(BoardNode node)
 {
     stack.Push(node);
 }
 public void Push(BoardNode node)
 {
     queue.Enqueue(node);
 }
        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;
        }
Example #14
0
 public bool Upgrade(BoardNode node)
 {
     return(false);
 }
Example #15
0
 public void Push(BoardNode node)
 {
     stack.Push(node);
 }
Example #16
0
 public void Push(BoardNode node)
 {
     queue.Enqueue(node);
 }
        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 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);
            }
        }
        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 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 void Push(BoardNode node)
 {
     if (node.Cost <= Depth)
         stack.Push(node);
     else
         queue.Insert(0,node);
 }
        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);
        }