Esempio n. 1
0
        public override string Solve(string input, bool part2)
        {
            if (part2)
            {
                return("Part 2 is unavailable");
            }
            GetNodes(input);
            BaseNodeConnection.PrintConnections(connections, 0, false);
            pathfind = new AStar(connections);

            double totalMoves = 0;
            string order      = "";


            Console.SetCursorPosition(0, maxHeight * (printouts + 1));
            pois         = Prioritize();
            singleHeight = Console.CursorTop - maxHeight;
            printouts++;
            var path = TraceRecursive((Node)startNode, 0, out double moves);

            foreach (Node door in doors)
            {
                door.IsUnlocked = true;
            }
            singleHeight = Console.CursorTop - maxHeight;
            BaseNode currStart = startNode;

            foreach (Node next in path)
            {
                pathfind.GetPath(currStart, next, out List <BaseNodeConnection> cons, out double dist);
                totalMoves += dist;
                BaseNodeConnection.PrintConnections(connections, maxHeight * ++printouts + singleHeight, false);
                BaseNodeConnection.PrintConnections(cons, maxHeight * printouts + singleHeight, true);
                currStart = next;
                order    += next.Key;
            }

            Console.SetCursorPosition(0, maxHeight * ++printouts + singleHeight);
            return("Moves: " + totalMoves + "/" + moves + " Order: " + order);
        }
Esempio n. 2
0
        private void LoadMaze(string input)
        {
            GetNodes(input);
            BaseNodeConnection.PrintConnections(connections, 0);
            Console.SetCursorPosition(0, maxHeight);
            shortcuts = new List <NodeConnection>();
            List <Node> unused = new List <Node>();

            foreach (NodeConnection con in connections.Where(x => x.NodeA.CharRepresentation != '\0' && x.NodeB.CharRepresentation != '\0'))
            {
                Console.Write("" + con.NodeA.CharRepresentation + con.NodeB.CharRepresentation + " -> ");
                if (connections.Where(x => x.HasConnectionTo(con.NodeA)).Count() == 1)
                {
                    unused.Add(con.NodeA);
                    if (con.NodeA.X < con.NodeB.X || con.NodeA.Y < con.NodeB.Y)
                    {
                        con.NodeB.PortalCode = con.NodeA.PortalCode + con.NodeB.PortalCode;
                        if (con.NodeA.X < con.NodeB.X)
                        {
                            con.NodeB.X++;
                        }
                        else
                        {
                            con.NodeB.Y++;
                        }
                    }
                    else
                    {
                        con.NodeB.PortalCode += con.NodeA.PortalCode;
                        if (con.NodeA.X > con.NodeB.X)
                        {
                            con.NodeB.X--;
                        }
                        else
                        {
                            con.NodeB.Y--;
                        }
                    }
                    portals.Add(con.NodeB);
                    connections.Single(x => x.HasConnectionTo(con.NodeB) && !ReferenceEquals(con, x)).RefreshDistance();
                    Console.WriteLine(con.NodeB.PortalCode);
                }
                else
                {
                    unused.Add(con.NodeB);
                    if (con.NodeA.X < con.NodeB.X || con.NodeA.Y < con.NodeB.Y)
                    {
                        con.NodeA.PortalCode += con.NodeB.PortalCode;
                        if (con.NodeA.X < con.NodeB.X)
                        {
                            con.NodeA.X--;
                        }
                        else
                        {
                            con.NodeA.Y--;
                        }
                    }
                    else
                    {
                        con.NodeA.PortalCode = con.NodeB.PortalCode + con.NodeA.PortalCode;
                        if (con.NodeA.X > con.NodeB.X)
                        {
                            con.NodeA.X++;
                        }
                        else
                        {
                            con.NodeA.Y++;
                        }
                    }
                    portals.Add(con.NodeA);
                    connections.Single(x => x.HasConnectionTo(con.NodeA) && !ReferenceEquals(con, x)).RefreshDistance();
                    Console.WriteLine(con.NodeA.PortalCode);
                }
            }

            foreach (Node node in unused)
            {
                connections = connections.Where(x => !x.HasConnectionTo(node)).ToList();
                nodes.Remove(node);
            }
            Console.WriteLine("================");

            foreach (Node node in nodes.Where(x => !string.IsNullOrWhiteSpace(x.PortalCode)))
            {
                Console.Write(node.PortalCode + " ");
                var partner = nodes.FirstOrDefault(x => x.PortalCode == node.PortalCode && !ReferenceEquals(x, node));
                if (partner != null && shortcuts.FirstOrDefault(x => x.HasConnectionTo(partner)) == null)
                {
                    var con = new NodeConnection(node, partner, 1);
                    shortcuts.Add(con);
                    Console.Write(" @ing: " + con.ToString());
                }
                else
                {
                    Console.Write(" Already Connected");
                }
                Console.WriteLine();
            }

            start        = nodes.Single(x => x.PortalCode == "AA");
            end          = nodes.Single(x => x.PortalCode == "ZZ");
            portalAccess = new Dictionary <BaseNodeConnection, Tuple <List <Node>, double> >();

            pathfind = new AStar(connections);

            foreach (Node portalA in portals)
            {
                foreach (Node opposite in nodes)
                {
                    opposite.UpdateTargetDistance(portalA);
                }
                foreach (Node portalB in portals.Where(x => x != portalA))
                {
                    Console.CursorLeft = 0;
                    Console.Write(assis.GetNextProgressChar());
                    var con = new BaseNodeConnection(portalA, portalB);
                    if (portalAccess.Keys.SingleOrDefault(x => x.IsSameConnection(con)) != null)
                    {
                        continue;
                    }
                    var path = pathfind.GetPath(portalA, portalB, out double currCost).Select(x => (Node)x).ToList();
                    if (path.Last() == portalA)
                    {
                        path = null;
                    }
                    portalAccess.Add(con, new Tuple <List <Node>, double>(path, currCost));
                }
            }

            //foreach (var empty in portalAccess.Where(x => x.Value.Item1 == null).ToList())
            //    portalAccess.Remove(empty.Key);
        }
Esempio n. 3
0
        private List <Tuple <BaseNodeConnection, int> > TraceRecursively(BaseNode currNode, List <Tuple <BaseNodeConnection, int, BaseNode> > usedShortcuts, out double cost, int depth, int recursiveDepth = 0)
        {
            cost = 0;
            var cons = portalAccess.Where(x =>
                                          x.Value.Item1 != null &&
                                          x.Key.HasConnectionTo(currNode) &&
                                          (depth != 0 || !((Node)x.Key.GetOtherNode(currNode)).IsOuterPortal || (x.Key.GetOtherNode(currNode) == end))
                                          ).OrderBy(x => ((Node)x.Key.GetOtherNode(currNode)).IsOuterPortal ? 0 : 1).ToList();

            double minCost = 0;
            List <Tuple <BaseNodeConnection, int> > result = null;
            BaseNodeConnection selCon   = null;
            BaseNodeConnection selShort = null;


            double selCost = 0;

            if (recursiveDepth > 500)
            {
                return(null);
            }
            if (depth >= portals.Count)
            {
                return(null);
            }
            foreach (var con in cons)
            {
                Console.Write(assis.GetNextProgressChar());
                Console.CursorLeft = 0;
                Node partner = (Node)con.Key.GetOtherNode(currNode);
                if (partner == start)
                {
                    continue;
                }
                if (partner == end)
                {
                    if (depth <= 0)
                    {
                        cost = con.Value.Item2;
                        return(new List <Tuple <BaseNodeConnection, int> >()
                        {
                            new Tuple <BaseNodeConnection, int>(con.Key, depth)
                        });
                    }
                    else
                    {
                        continue;
                    }
                }
                if (usedShortcuts.FirstOrDefault(x => (depth == -1 && x.Item1.HasConnectionTo(partner)) ||
                                                 (x.Item2 < depth && x.Item1.IsSameConnection(con.Key) && x.Item3 == partner)) != null)
                {
                    continue;
                }
                var shortCut   = shortcuts.Single(x => x.HasConnectionTo(partner));
                var shortDepth = new Tuple <BaseNodeConnection, int, BaseNode>(depth == -1 ? shortCut : con.Key, depth, partner);
                usedShortcuts.Add(shortDepth);
                var currPath = TraceRecursively(shortCut.GetOtherNode(partner), usedShortcuts, out double currCost, depth == -1 ? -1 : (partner.IsOuterPortal ? depth - 1 : depth + 1), recursiveDepth + 1);
                usedShortcuts.RemoveAt(usedShortcuts.Count - 1);
                if (currPath != null && (currCost < minCost || minCost == 0))
                {
                    minCost  = currCost;
                    result   = currPath;
                    selCost  = con.Value.Item2;
                    selCon   = con.Key;
                    selShort = shortCut;
                }
            }
            if (result == null || selCon == null)
            {
                return(null);
            }
            cost = minCost + selCost + 1;
            result.Add(new Tuple <BaseNodeConnection, int>(selShort, depth));
            result.Add(new Tuple <BaseNodeConnection, int>(selCon, depth));
            return(result);
        }