public List <int> findPath(int source, int dest)
        {
            List <int>            points            = new List <int>();
            PointDirection        p                 = new PointDirection();
            var                   firsttokenSource  = new System.Threading.CancellationTokenSource();
            var                   token1            = firsttokenSource.Token;
            var                   secondtokenSource = new System.Threading.CancellationTokenSource();
            var                   token2            = secondtokenSource.Token;
            PointDirection        nextfirst         = new PointDirection();
            PointDirection        nextsecond        = new PointDirection();
            Task <PointDirection> firsttask         = null;
            Task <PointDirection> secondtask        = null;

            p.point = source; p.direction = Directions.north;
            if (p.point == dest)
            {
                points.Add(dest);
                return(points);
            }

            int[] moves      = directions.move(p.direction, n);
            int   firstMove  = moves[0];
            int   secondMove = moves[1];

            if (firstMove > 0)
            {
                nextfirst.direction = Directions.east;
            }
            else
            {
                nextfirst.direction = Directions.west;
            }
            if (inMatrix(p.point + firstMove) && isOpen(p.point + firstMove) && notLast(p.point + firstMove, p.point))
            {
                nextfirst.point = p.point + firstMove;
                first.Add(nextfirst, p);
                firsttask = new Task <PointDirection>(() => path(nextfirst, dest, first), token1);
                firsttask.Start();
            }
            if (secondMove > 0)
            {
                nextsecond.direction = Directions.south;
            }
            else
            {
                nextsecond.direction = Directions.north;
            }
            if (inMatrix(p.point + secondMove) && isOpen(p.point + secondMove))
            {
                nextsecond.point = p.point + secondMove;
                second.Add(nextsecond, p);
                secondtask = new Task <PointDirection>(() => path(nextsecond, dest, second), token2);
                secondtask.Start();
            }
            int index = 2;

            if (firsttask != null && secondtask != null)
            {
                index = Task.WaitAny(secondtask, firsttask);
                if (index < 2)
                {
                    if (index == 1)
                    {
                        secondtokenSource.Cancel();
                        if (secondtask.Result != null)
                        {
                            PointDirection d = secondtask.Result;
                            points.Add(d.point);
                            while (second[d] != p)
                            {
                                points.Add(second[d].point);
                                d = second[d];
                            }
                            points.Add(second[d].point);
                        }
                    }
                    else if (index == 0)
                    {
                        firsttokenSource.Cancel();
                        if (firsttask.Result != null)
                        {
                            PointDirection d = firsttask.Result;
                            points.Add(d.point);
                            while (first[d] != p)
                            {
                                points.Add(first[d].point);
                                d = first[d];
                            }
                            points.Add(first[d].point);
                        }
                    }
                }
            }
            else if (firsttask != null && secondtask == null)
            {
                firsttask.Wait();
                Task result = firsttask.ContinueWith(s =>
                {
                    if (firsttask.Result != null)
                    {
                        PointDirection d = firsttask.Result;
                        points.Add(d.point);
                        while (first[d] != p)
                        {
                            points.Add(first[d].point);
                            d = first[d];
                        }
                        points.Add(first[d].point);
                    }
                });
                result.Wait();
            }
            else
            {
                secondtask.Wait();
                if (secondtask.Result != null)
                {
                    PointDirection d = secondtask.Result;
                    points.Add(d.point);
                    while (second[d] != p)
                    {
                        points.Add(second[d].point);
                        d = second[d];
                    }
                    points.Add(second[d].point);
                }
            }

            return(points);
        }
        public List <int> findPath(int source, int dest)
        {
            PointDirection p = new PointDirection();

            p.point = source; p.direction = Directions.north;
            Queue <PointDirection> Visited      = new Queue <PointDirection>();
            List <PointDirection>  VisitedNodes = new List <PointDirection>();
            PointDirection         destination  = new PointDirection();

            VisitedNodes.Add(p);
            Visited.Enqueue(p);
            for (; Visited.Count > 0;)
            {
                PointDirection current    = Visited.Dequeue();
                PointDirection nextfirst  = new PointDirection();
                PointDirection nextsecond = new PointDirection();

                if (current.point == dest)
                {
                    destination.point     = dest;
                    destination.direction = current.direction;
                    break;
                }

                int[] moves      = directions.move(current.direction, n);;
                int   firstMove  = moves[0];
                int   secondMove = moves[1];
                if (firstMove > 0)
                {
                    nextfirst.direction = Directions.east;
                }
                else
                {
                    nextfirst.direction = Directions.west;
                }
                nextfirst.point = current.point + firstMove;
                if (inMatrix(current.point + firstMove) && isOpen(current.point + firstMove) && !VisitedNodes.Contains(nextfirst) && notLast(current.point + firstMove, current.point))
                {
                    nextfirst.point = current.point + firstMove;
                    Visited.Enqueue(nextfirst);
                    VisitedNodes.Add(nextfirst);
                    map.Add(nextfirst, current);
                }
                if (secondMove > 0)
                {
                    nextsecond.direction = Directions.south;
                }
                else
                {
                    nextsecond.direction = Directions.north;
                }
                nextsecond.point = current.point + secondMove;
                if (inMatrix(current.point + secondMove) && isOpen(current.point + secondMove) && !VisitedNodes.Contains(nextsecond))
                {
                    nextsecond.point = current.point + secondMove;
                    Visited.Enqueue(nextsecond);
                    VisitedNodes.Add(nextsecond);
                    map.Add(nextsecond, current);
                }
            }
            List <int> points = new List <int>();

            if (destination != null)
            {
                PointDirection key = destination;
                if (map.ContainsKey(key))
                {
                    points.Add(destination.point);
                    while (map[key] != p)
                    {
                        points.Add(map[key].point);
                        key = map[key];
                    }
                    points.Add(map[key].point);
                }
            }

            return(points);
        }
        public PointDirection path(PointDirection source, int dest, Dictionary <PointDirection, PointDirection> map)
        {
            PointDirection p = new PointDirection();

            Queue <PointDirection> Visited      = new Queue <PointDirection>();
            List <PointDirection>  VisitedNodes = new List <PointDirection>();
            PointDirection         destination  = new PointDirection();

            VisitedNodes.Add(source);
            Visited.Enqueue(source);
            PointDirection prev    = new PointDirection();
            PointDirection current = new PointDirection();

            for (; Visited.Count > 0;)
            {
                prev    = current;
                current = Visited.Dequeue();
                PointDirection nextfirst  = new PointDirection();
                PointDirection nextsecond = new PointDirection();

                if (current.point == dest)
                {
                    //map.Add(current,prev);
                    return(current);
                }

                int[] moves      = directions.move(current.direction, n);;
                int   firstMove  = moves[0];
                int   secondMove = moves[1];
                if (firstMove > 0)
                {
                    nextfirst.direction = Directions.east;
                }
                else
                {
                    nextfirst.direction = Directions.west;
                }
                nextfirst.point = current.point + firstMove;
                if (inMatrix(current.point + firstMove) && isOpen(current.point + firstMove) && !VisitedNodes.Contains(nextfirst) && notLast(current.point + firstMove, current.point))
                {
                    nextfirst.point = current.point + firstMove;
                    Visited.Enqueue(nextfirst);
                    VisitedNodes.Add(nextfirst);
                    map.Add(nextfirst, current);
                }
                if (secondMove > 0)
                {
                    nextsecond.direction = Directions.south;
                }
                else
                {
                    nextsecond.direction = Directions.north;
                }
                nextsecond.point = current.point + secondMove;
                if (inMatrix(current.point + secondMove) && isOpen(current.point + secondMove) && !VisitedNodes.Contains(nextsecond))
                {
                    nextsecond.point = current.point + secondMove;
                    Visited.Enqueue(nextsecond);
                    VisitedNodes.Add(nextsecond);
                    map.Add(nextsecond, current);
                }
            }
            return(null);
        }