예제 #1
0
        public static SearchRegion <Tile> OpenUniformCost(this TileMap map, Tile startTile, int move)
        {
            var searchRegion = new SearchRegion <Tile>(new TileEqualityComparer());
            var closed       = new List <Tile>();
            var open         = new SimplePriorityQueue <Tile>();

            searchRegion.Add(startTile, null);
            open.Enqueue(startTile, 0);
            while (open.Count > 0)
            {
                var parentPriority = open.GetPriority(open.First);
                var parentTile     = open.Dequeue();

                var adjacent = map.GetAdjacent(parentTile)
                               .Where(a => !closed.Contains(a));
                foreach (var a in adjacent)
                {
                    var priority = a.MoveCost + parentPriority;
                    if (priority <= move)
                    {
                        searchRegion.Add(a, parentTile);
                        open.Enqueue(a, priority);
                    }
                }
                closed.Add(parentTile);
            }

            return(searchRegion);
        }
        //HashSet<Edge> Edges = new HashSet<Edge>();

        public ArtistsConnectionsForm()
        {
            InitializeComponent();
            var config = SpotifyClientConfig.CreateDefault().WithAuthenticator(new ClientCredentialsAuthenticator("e6bf2e305d98443190c472ee318fd511", "96bad35ecf9c41f581a761eb3a85348b"));

            Spotify = new SpotifyClient(config);
            ArtistsToCheck.Enqueue("4JxdBEK730fH7tgcyG3vuv", 0);
            int n = 0;

            while (ArtistsToCheck.Count > 0 && ArtistsToCheck.GetPriority(ArtistsToCheck.First) <= 2)
            {
                string first    = ArtistsToCheck.First;
                float  priority = ArtistsToCheck.GetPriority(first);
                ArtistsToCheck.Dequeue();
                Task <List <string> > artistsTask = FindAllConnectedArtists(first, priority);
                artistsTask.Wait();
                n++;
            }
            List <string> edges = new List <string>();

            foreach (Edge edge in ArtistsGraph.Edges)
            {
                string sourceName;
                string targetName;
                ArtistIdToName.TryGetValue(edge.Source, out sourceName);
                ArtistIdToName.TryGetValue(edge.Source, out targetName);
                edges.Add(sourceName + " - " + edge.LabelText + " - " + targetName);
            }
            ListBox1.DataSource = edges;
            while (ArtistsToCheck.Count > 0)
            {
                string name;
                ArtistIdToName.TryGetValue(ArtistsToCheck.First, out name);
                float priority = ArtistsToCheck.GetPriority(ArtistsToCheck.First);
                ArtistsToCheck.Dequeue();
                ListBox3.Items.Add(name + " - " + priority);
            }
            foreach (string id in CheckedArtists)
            {
                string name;
                ArtistIdToName.TryGetValue(id, out name);
                ListBox2.Items.Add(name);
            }
            label1.Text = ListBox1.Items.Count.ToString();
            label2.Text = ListBox2.Items.Count.ToString();
            label3.Text = ListBox3.Items.Count.ToString();
        }
    public void Search()
    {
        previous[source] = source;
        //we have to continue until we pop the target
        while (Unvisited.Contains(target) || Unvisited.Count == 0)
        {
            // If we don't have any nodes left to find a path to, then stop
            if (Unvisited.Count == 0)
            {
                return;
            }

            //before we mess with it we need to get the distance to the node at the front of the priority queue
            dist[Unvisited.First] = Unvisited.GetPriority(Unvisited.First);

            //take it off the top, let's see what we can do with it.
            //the int refers to the id of the node we dequeue
            int lastChosen = Unvisited.Dequeue();


            //now that we have it, what are its neighbors?
            //we need to update the previous and distances to all of these objects
            foreach (GraphEdge e in graph.edges[lastChosen])
            {
                // I need to refrain from looking at nodes already visited, otherwise ignore per the foreach
                if (Unvisited.Contains(e.to))
                {
                    // put in words: if the cost of the edge + the distance from the source to the "from" of the current edge < the previously known cost to the "to" of the edge.
                    if (dist[lastChosen] + e.cost < Unvisited.GetPriority(e.to))
                    {
                        // if we've made it into this loop, then we've found an improvement for the path to this node

                        //first, update what is pointing at the current node
                        previous[e.to] = e.from;
                        //update the priority with the new calculated cost
                        Unvisited.UpdatePriority(e.to, dist[lastChosen] + e.cost);
                    }
                }
            }
        }

        //TODO : if unvisited.count == 0...return;///////

        //else
        //we are done and have the data...
    }
예제 #4
0
    private NevPoint[] aStarSearch(NevPoint from, NevPoint to)
    {
        SimplePriorityQueue <NevPoint>            searchQueue = new SimplePriorityQueue <NevPoint>();
        Dictionary <NevPoint, NevPoint>           last        = new Dictionary <NevPoint, NevPoint>();
        Dictionary <NevPoint, float>              dis         = new Dictionary <NevPoint, float>();
        Action <NevPoint, NevPoint, float, float> insertPoint = (point, lastPoint, _dis, priority) => {
            searchQueue.Enqueue(point, priority);
            last.Add(point, lastPoint);
            dis.Add(point, _dis);
        };

        insertPoint(from, from, 0, 0);
        while (searchQueue.Count != 0)
        {
            NevPoint point = searchQueue.Dequeue();
            if (point == to)
            {
                break;
            }
            foreach (var dir in Dirs)
            {
                if (point.GetAroundFlag(dir))
                {
                    NevPoint tar      = GetClosestNevPoint(point.pos + dir * step);
                    float    nowDis   = dis[point] + step;
                    float    priority = nowDis + (to.pos - tar.pos).magnitude;
                    bool     contain  = last.ContainsKey(tar);
                    if (!contain)
                    {
                        insertPoint(tar, point, nowDis, priority);
                    }
                    else if (searchQueue.Contains(tar) && searchQueue.GetPriority(tar) > priority)
                    {
                        searchQueue.UpdatePriority(tar, priority);
                        last[tar] = point;
                        dis[tar]  = nowDis;
                    }
                }
            }
        }
        Action <Action <NevPoint> > doeachPathNode = (a) => {
            var node = to;
            while (last[node] != from)
            {
                node = last[node];
                a(node);
            }
        };
        int pathSize = 0;

        doeachPathNode((p) => pathSize++);
        NevPoint[] result = new NevPoint[pathSize];         //Not contain from and to
        doeachPathNode((p) => {
            pathSize--;
            result[pathSize] = p;
        });
        return(result);
    }
        //method returns minimum path and total cost of the same path (long)
        public long PrimsSpanningTree(List <Edges>[] graphAdjList
                                      , out List <KeyValuePair <int, int> > pathList, int startNode = 0)
        {
            //path will be stored
            //KeyValuePair<fromVer,toVer>
            List <KeyValuePair <int, int> > path = new List <KeyValuePair <int, int> >();

            int  N         = graphAdjList.Length;
            int  edgeCount = 0; //in order to check edgeCount!=N-1
            long mstCost   = 0; //minimun spanning tree total cost

            bool[] visited = new bool[N];

            //using Priority_Queue; you may add it to your project as a NuGet
            SimplePriorityQueue <KeyValuePair <int, int>, long> priorityQueue =
                new SimplePriorityQueue <KeyValuePair <int, int>, long>();

            foreach (var edges in graphAdjList[startNode])
            {
                priorityQueue.Enqueue(new KeyValuePair <int, int>(edges.fromVer, edges.toVer)
                                      , edges.cost);
            }

            visited[startNode] = true;

            //if priorityQueue isn't empty
            while (priorityQueue.Count != 0 && edgeCount != N - 1)
            {
                var cost = priorityQueue.GetPriority(priorityQueue.First);
                var edge = priorityQueue.Dequeue();
                //edge.Value refers to toVer on graphAdjList
                if (visited[edge.Value])
                {
                    continue;
                }
                //adding path , edge.Key :fromVer , endge.Value:toVer
                path.Add(new KeyValuePair <int, int>(edge.Key, edge.Value));

                visited[edge.Value] = true;

                mstCost += cost;
                edgeCount++;

                //add the values to priority queue again
                foreach (var e in graphAdjList[edge.Value])
                {
                    priorityQueue.Enqueue(new KeyValuePair <int, int>(e.fromVer, e.toVer)
                                          , e.cost);
                }
            }

            pathList = path;        //out List<KeyValuePair<int,int>> pathList

            if (edgeCount != N - 1) //if edgeCount is any different than N-1 , there must be a cycle!
            {
                return(default);
예제 #6
0
        public void PlayerDeterministicIterateDequeueAndUpdateAndEnqueue(int loopCount, decimal spd)
        {
            var         sheets      = TableSheetsImporter.ImportSheets();
            TableSheets tableSheets = new TableSheets(sheets);

            Player[] players = new[]
            {
                new Player(
                    1,
                    tableSheets.CharacterSheet,
                    tableSheets.CharacterLevelSheet,
                    tableSheets.EquipmentItemSetEffectSheet),
                new Player(
                    2,
                    tableSheets.CharacterSheet,
                    tableSheets.CharacterLevelSheet,
                    tableSheets.EquipmentItemSetEffectSheet),
                new Player(
                    3,
                    tableSheets.CharacterSheet,
                    tableSheets.CharacterLevelSheet,
                    tableSheets.EquipmentItemSetEffectSheet),
            };

            List <Player> results1 = new List <Player>();
            List <Player> results2 = new List <Player>();

            for (int i = 0; i < 2; i++)
            {
                List <Player> targetResults = i == 0
                    ? results1
                    : results2;

                SimplePriorityQueue <Player, decimal> queue = new SimplePriorityQueue <Player, decimal>();
                for (int j = 0; j < players.Length; j++)
                {
                    queue.Enqueue(players[j], spd);
                }

                for (int j = 0; j < loopCount; j++)
                {
                    Assert.True(queue.TryDequeue(out Player player));
                    targetResults.Add(player);

                    foreach (Player otherPlayer in queue)
                    {
                        decimal priority = queue.GetPriority(otherPlayer);
                        queue.UpdatePriority(otherPlayer, priority);
                    }

                    queue.Enqueue(player, spd);
                }
            }

            Assert.Equal(results1, results2);
        }
예제 #7
0
        private void Encoding()
        {
            var heap = new SimplePriorityQueue <int, uint>();

            for (int i = 0; i < Length; i++)
            {
                heap.Enqueue(i, tree[i].weight);
            }
            for (int i = 0; i < tree.Length; i++)
            {
                tree[i].parent = -1;
            }
            for (int i = Length; i < tree.Length; i++)
            {
                uint w1    = heap.GetPriority(heap.First);
                int  item1 = heap.Dequeue();
                uint w2    = heap.GetPriority(heap.First);
                int  item2 = heap.Dequeue();
                tree[i].weight     = w1 + w2;
                tree[i].left       = item1;
                tree[i].right      = item2;
                tree[item1].parent = tree[item2].parent = i;
                heap.Enqueue(i, tree[i].weight);
            }
            for (int i = 0; i < Length; i++)
            {
                tree[i].code = "";
                int curr = i;
                while (tree[curr].parent != -1)
                {
                    int parent = tree[curr].parent;
                    if (tree[parent].left == curr)
                    {
                        tree[i].code = '0' + tree[i].code;
                    }
                    else
                    {
                        tree[i].code = '1' + tree[i].code;
                    }
                    curr = parent;
                }
            }
        }
예제 #8
0
        private static int LeastManaSpend(int hitPointsPenalty)
        {
            // Holds seqeunces, where index in a sequence determines round number and its value is casted spell
            SimplePriorityQueue <List <SpellType> > paths = new SimplePriorityQueue <List <SpellType> >();

            // Push onto stack empty path
            paths.Enqueue(new List <SpellType>(), 0);

            while (true)
            {
                // Pick a path
                List <SpellType> path = paths.First;
                int spent             = (int)Math.Round(paths.GetPriority(path));
                paths.Dequeue();

                // Create characters
                Character player = CharacterFactory.CreatePlayer();
                Character boss   = CharacterFactory.CreateBoss();

                // Do the fight
                bool win = Fight(player, boss, hitPointsPenalty, (round, attacker, victim, isBoss) =>
                {
                    // Boss has one type of spell only
                    if (isBoss)
                    {
                        return(SpellFactory.CreateSpell(SpellType.BossDamage, attacker, victim));
                    }

                    // Divide round number as the player goes every second round
                    round /= 2;

                    // Either send spell in the path
                    if (round < path.Count)
                    {
                        return(SpellFactory.CreateSpell(path[round], attacker, victim));
                    }

                    // Otherwise push onto stack new path where we can move in this round
                    foreach (Spell spell in PlayersSpells.Select(x => SpellFactory.CreateSpell(x, attacker, victim)).Where(x => attacker.CanCastSpell(x)))
                    {
                        paths.Enqueue(path.Concat(new SpellType[] { spell.SpellType }).ToList(), spent + spell.Cost);
                    }

                    // End this fight as losing one
                    return(null);
                });

                // We finally won
                if (win)
                {
                    return(spent);
                }
            }
        }
예제 #9
0
        void UCSearch(City root, City destiny, List <City> cities)
        {
            SimplePriorityQueue <City> Frontier = new SimplePriorityQueue <City>();

            root.PathCost = 0;
            Frontier.Enqueue(root, 0);
            float sum;

            while (Frontier.Count != 0)
            {
                sum = Frontier.GetPriority(Frontier.First);
                City parent = (City)Frontier.Dequeue();
                tbResult.Text += ("\n Expando el nodo de: " + parent.CityName + " Llevando un costo actual de: " + sum);
                tbOrder.Text  += ("\n" + parent.CityName + " Costo: " + sum + "\n ↓");
                if (parent == destiny)
                {
                    tbResult.Text += ("\n Llegue al destino con un costo total de: " + sum);
                    break;
                }
                cities.Add(parent);
                foreach (var tempRute in parent.Rutes)
                {
                    if (!cities.Contains(tempRute.DestinationCity))
                    {
                        if (!Frontier.Contains(tempRute.DestinationCity))
                        {
                            Frontier.Enqueue(tempRute.DestinationCity, sum + tempRute.Cost);
                        }
                        else
                        {
                            if (Frontier.GetPriority(tempRute.DestinationCity) > sum + tempRute.Cost)
                            {
                                Frontier.TryUpdatePriority(tempRute.DestinationCity, sum + tempRute.Cost);
                            }
                        }
                    }
                }
            }
        }
    public void refershSimilarMapsBatch()
    {
        int i = 0;

        TileObject[,] tmpStrAlias;
        Vector2Int startMainMap = ParameterManager.Instance.StartCell;

        GeneratorUIManager.Instance.deleteMapOnUI(AliasDragAreas[1].GetChild(0));
        AliasDragAreas[1].GetComponent <MapListManager>().dictionaryMap.Clear();

        if (SimilarMapsQueue.Count <= 0)
        {
            GenerateAndTestAliasMaps();
        }

        while (i < BatchAliasNumber)
        {
            float dst = SimilarMapsQueue.GetPriority(SimilarMapsQueue.First());
            tmpStrAlias = SimilarMapsQueue.Dequeue();

            Utility.renderAliasOnUI(AliasDragAreas[1].GetChild(0).GetComponent <RectTransform>(), ParameterManager.Instance.GridType, new StructuredAlias(tmpStrAlias, startMainMap, ParameterManager.Instance.EndCell, dst), AliasPrefab, true);
            i++;
        }
    }
예제 #11
0
        public void Simulate()
        {
            var priority            = buffer.GetPriority(buffer.First);
            var linkerName          = buffer.Dequeue();
            var current_simulations = onSimulationTuples.Select(x => x.Item2.Count).ToArray();
            var target = Array.IndexOf(current_simulations, current_simulations.Min());

            var target_queue = onSimulationTuples[target].Item1;
            var target_set   = onSimulationTuples[target].Item2;

            target_set.Add(linkerName);
            Submitlammps(linkerName, target_queue);

            Console.WriteLine("Job " + linkerName + " Submmitted with Priority " + priority);
            Console.WriteLine("Current " + target_queue + " on simulation " + target_set.Count);
        }
예제 #12
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="elapsed">time since update was last called, in microseconds</param>
 public void Update(double elapsed)
 {
     if (Playing)
     {
         Time += elapsed / Tempo * PPQ;
         while (tasks.Count > 0)
         {
             Scheduled nxt = tasks.First;
             if (tasks.GetPriority(nxt) > Time)
             {
                 break;
             }
             nxt();
             tasks.Remove(nxt);
         }
     }
 }
예제 #13
0
        private static SimplePriorityQueue <string> PopulatePriorityQueue(List <string> senders)
        {
            SimplePriorityQueue <string> queue = new SimplePriorityQueue <string>();

            //If sender exists in queue, increment priority, else add to queue with value 1
            foreach (string sender in senders)
            {
                if (queue.Contains(sender))
                {
                    float priority = queue.GetPriority(sender);
                    queue.UpdatePriority(sender, priority++);
                }
                else
                {
                    queue.Enqueue(sender, 1);
                }
            }

            return(queue);
        }
예제 #14
0
        private static List <MessagePrioritiesModel> PriorityQueueToList(SimplePriorityQueue <string> senderQueue)
        {
            List <MessagePrioritiesModel> senderPriorities = new List <MessagePrioritiesModel>();

            while (senderQueue.Count != 0)
            {
                string first    = senderQueue.First;
                float  priority = senderQueue.GetPriority(first);
                MessagePrioritiesModel newMessagePriorities = new MessagePrioritiesModel()
                {
                    categoryName     = first,
                    categoryPriority = priority
                };
                senderPriorities.Add(newMessagePriorities);

                senderQueue.Dequeue();
            }

            return(senderPriorities);
        }
예제 #15
0
        public void GuidDeterministicIterateDequeueAndUpdateAndEnqueue(int loopCount, decimal spd)
        {
            List <Guid> results1 = new List <Guid>();
            List <Guid> results2 = new List <Guid>();

            Guid[] guids = new[]
            {
                Guid.NewGuid(),
                   Guid.NewGuid(),
                   Guid.NewGuid(),
            };

            for (int i = 0; i < 2; i++)
            {
                List <Guid> targetResults = i == 0
                    ? results1
                    : results2;

                SimplePriorityQueue <Guid, decimal> queue = new SimplePriorityQueue <Guid, decimal>();
                for (int j = 0; j < guids.Length; j++)
                {
                    queue.Enqueue(guids[j], spd);
                }

                for (int j = 0; j < loopCount; j++)
                {
                    Assert.True(queue.TryDequeue(out Guid guid));
                    targetResults.Add(guid);

                    foreach (Guid otherGuid in queue)
                    {
                        decimal priority = queue.GetPriority(otherGuid);
                        queue.UpdatePriority(otherGuid, priority);
                    }

                    queue.Enqueue(guid, spd);
                }
            }

            Assert.Equal(results1, results2);
        }
예제 #16
0
    //HillClimber improve the evaluation so MAXIMIZE!
    public Dictionary <int, StructuredAlias> RandomRestartHillClimber(StructuredAlias realMap, EvaluateNode Eval)
    {
        AliasChallengePriorityQueue = new SimplePriorityQueue <Dictionary <int, StructuredAlias> >();
        iterationRandomRestart      = 0;
        graphPlot.Clear();
        ParameterManager pMan = ParameterManager.Instance;

        System.Diagnostics.Stopwatch sWatch = StopwatchProxy.Instance.Stopwatch;
        sWatch.Stop();
        sWatch.Reset();
        sWatch.Start();

        int totalIterations = 0;

        while (iterationRandomRestart < maxIterations)
        {
            try
            {
                if (sWatch.ElapsedMilliseconds > pMan.timeCap * 1000f && pMan.timeCap >= 0)
                {
                    throw new Exception("Time cap elapsed.\n");
                }
                AliasChallengePriorityQueue.Enqueue(HillClimber(realMap, Eval), -(float)returnEval);
            }
            catch (Exception e)
            {
                ErrorManager.ManageError(ErrorManager.Error.SOFT_ERROR, e.Message + sWatch.ElapsedMilliseconds / 1000f + "s #iteration: " + iterationRandomRestart + " (" + totalIterations + returnIter + ")." + SaveAliasChallengeOptimization());
                sWatch.Stop();
                sWatch.Reset();
                return(AliasChallengePriorityQueue.Dequeue());
            }
            totalIterations += returnIter;
            iterationRandomRestart++;
        }

        GeneratorUIManager.Instance.showMessageDialogBox("F= " + Mathf.Abs(AliasChallengePriorityQueue.GetPriority(AliasChallengePriorityQueue.First)) + "\nExecution time: " + sWatch.ElapsedMilliseconds / 1000f + "s #iteration: " + iterationRandomRestart + " (" + maxIterations * pMan.hillClimberNumBatch + ")." + SaveAliasChallengeOptimization());
        sWatch.Stop();
        sWatch.Reset();
        return(AliasChallengePriorityQueue.Dequeue());
    }
예제 #17
0
        // TODO: use a population map to guide randomness
        private IEnumerable <Road> CreateRoads()
        {
            // Algorithm from http://nothings.org/gamedev/l_systems.html
            var potentialRoads = new SimplePriorityQueue <Road>();
            var acceptedRoads  = new List <Road>();

            var StartX = Rand.Next(20, EngineConsts.MAP_WIDTH - 20);
            var StartY = Rand.Next(20, EngineConsts.MAP_HEIGHT - 20);
            var Length = Rand.NextDouble() * 15 + 10;
            var Angle  = Math.PI / 2 * Rand.Next(0, 4);
            var r1     = new Road(0, StartX, StartY, Length, Angle, 5, 0, 0);
            var r2     = new Road(0, StartX, StartY, Length, Angle + Math.PI, 5, 0, 0);

            potentialRoads.Enqueue(r1, 0);
            potentialRoads.Enqueue(r2, 0);

            while (potentialRoads.Count > 0)
            {
                Road  road = potentialRoads.First;
                float prio = potentialRoads.GetPriority(road);
                potentialRoads.Dequeue();

                if (CheckLocalConstraints(road, acceptedRoads, out Road newRoad))
                {
                    acceptedRoads.Add(newRoad);
                    ProjectRoadToMap(newRoad);

                    foreach (Road rq in SolveGlobalGoals(newRoad))
                    {
                        if (rq != null)
                        {
                            potentialRoads.Enqueue(rq, prio + 1);
                        }
                    }
                }
            }

            return(acceptedRoads);
        }
예제 #18
0
        public static Path <Tile> AStar(this TileMap map, Tile startTile, Tile endTile)
        {
            var complete     = false;
            var searchRegion = new SearchRegion <Tile>(new TileEqualityComparer());
            var closed       = new List <Tile>();
            var open         = new SimplePriorityQueue <Tile>();

            open.Enqueue(startTile, 0);
            while (open.Count > 0)
            {
                var parentPriority = open.GetPriority(open.First);
                var parentTile     = open.Dequeue();

                if (complete || parentTile == endTile)
                {
                    break;
                }

                var adjacent = map.GetAdjacent(parentTile)
                               .Where(a => !closed.Contains(a));
                foreach (var a in adjacent)
                {
                    searchRegion.Add(a, parentTile);
                    if (a == endTile)
                    {
                        complete = true;
                        break;
                    }

                    var priority = a.MoveCost + parentPriority + ManhattanDistance(a.Location, endTile.Location);
                    open.Enqueue(a, priority);
                }

                closed.Add(parentTile);
            }

            return(searchRegion.GetPath(endTile));
        }
예제 #19
0
        public List <PathNode> GetPath(Vector3Int from, Vector3Int to)
        {
            // We will allow paths that start and end at map objects but NOT go through them.

            // If the from and to are the same, then the path is just the from
            if (from == to)
            {
                return new List <PathNode> {
                           from
                }
            }
            ;

            // Visited will store black nodes
            HashSet <PathNode>             visited = new HashSet <PathNode>();
            SimplePriorityQueue <PathNode> queue   = new SimplePriorityQueue <PathNode>();

            queue.Enqueue(from, 0);

            while (queue.Count > 0)
            {
                // Getting a node from the queue means that there is no better path to this
                // node. This means that it is done being visited, so we can turn it black and
                // add it to the visited set.
                PathNode current = queue.Dequeue();

                visited.Add(current);

                if (current.x == to.x && current.y == to.y)
                {
                    List <PathNode> path = new List <PathNode>();
                    while (current != null)
                    {
                        path.Insert(0, current);
                        current = current.prev;
                    }
                    return(path);
                }

                for (int x = current.x - 1; x <= current.x + 1; x++)
                {
                    for (int y = current.y - 1; y <= current.y + 1; y++)
                    {
                        if (x == current.x && y == current.y)
                        {
                            continue;                                   // Skip center
                        }
                        if (x != current.x && y != current.y)
                        {
                            continue;                                   // Skip diagonals
                        }
                        PathNode next = new PathNode {
                            x = x, y = y, prev = current, cost = current.cost + 1
                        };

                        if (level.IsMapObject(next) && !(next.x == to.x && next.y == to.y))
                        {
                            continue;                                                                 // Skip map objects unless it's the goal
                        }
                        if (level.IsOutOfBounds(next))
                        {
                            continue;                            // Skip out of bounds locations
                        }
                        // Gray node - in the middle of processing
                        if (queue.Contains(next))
                        {
                            if (queue.GetPriority(next) > next.cost)
                            {
                                queue.Remove(next);
                                queue.Enqueue(next, next.cost);
                            }
                        }
                        // White node - never seen before
                        else if (!visited.Contains(next))
                        {
                            queue.Enqueue(next, next.cost);
                        }
                    }
                }
            }

            return(null);
        }
    }
    public void CollabGameGeneration()
    {
        mainMap          = ParameterManager.Instance.MapToPlay;
        gridType         = ParameterManager.Instance.GridType;
        SimilarMapsQueue = new SimplePriorityQueue <TileObject[, ]>();

        K_CollisionSet = MapEvaluator.BuildKCollisionVec(mainMap, gridType, ParameterManager.Instance.StartCell, Mathf.Max(ParameterManager.Instance.minStepsSolution, ParameterManager.Instance.maxStepsSolution));

        if (ParameterManager.Instance.isOptimizerOn)
        {
            List <TileObject[, ]> alises = new List <TileObject[, ]>();
            BaseAliasCollisionMask = getMainMapKMaxMinCells(mainMap, gridType, ParameterManager.Instance.minStepsSolution, ParameterManager.Instance.minStepsSolution, ParameterManager.Instance.StartCell, 0f);

            int experimentsNum = 1;
            while (experimentsNum > 0)
            {
                foreach (var a in AliasGeneratorManager.Instance.GetComponent <AliasGameEvaluator>().AliasGameOptimizerHandler())
                {
                    SimilarMapsQueue.Enqueue(a.Value.AliasMap, a.Value.similarityDistance);
                }
                experimentsNum--;
            }
        }
        else
        {
            GenerateAndTestAliasMaps();
        }


        int        i            = 0;
        Vector2Int startMainMap = ParameterManager.Instance.StartCell;

        TileObject[,] tmpStrAlias;
        while (i < ParameterManager.Instance.aliasNum)
        {
            if (ParameterManager.Instance.considerSimilar)
            {
                float dst = SimilarMapsQueue.GetPriority(SimilarMapsQueue.First());
                tmpStrAlias = SimilarMapsQueue.Dequeue();

                Utility.renderAliasOnUI(AliasDragAreas[0].GetChild(0).GetComponent <RectTransform>(), ParameterManager.Instance.GridType, new StructuredAlias(tmpStrAlias, startMainMap, ParameterManager.Instance.EndCell, dst), AliasPrefab, true);
                i++;
            }

            if (ParameterManager.Instance.considerNovelty && i < ParameterManager.Instance.aliasNum)
            {
                tmpStrAlias = SimilarMapsQueue.Last();
                float dst = SimilarMapsQueue.GetPriority(tmpStrAlias);
                SimilarMapsQueue.Remove(tmpStrAlias);

                Utility.renderAliasOnUI(AliasDragAreas[0].GetChild(0).GetComponent <RectTransform>(), ParameterManager.Instance.GridType, new StructuredAlias(tmpStrAlias, startMainMap, ParameterManager.Instance.EndCell, dst), AliasPrefab, true);
                i++;
            }
        }

        i = 0;
        while (SimilarMapsQueue.Count > 0 && i < BatchAliasNumber)
        {
            float dst = SimilarMapsQueue.GetPriority(SimilarMapsQueue.First());
            tmpStrAlias = SimilarMapsQueue.Dequeue();

            Utility.renderAliasOnUI(AliasDragAreas[1].GetChild(0).GetComponent <RectTransform>(), ParameterManager.Instance.GridType, new StructuredAlias(tmpStrAlias, startMainMap, ParameterManager.Instance.EndCell, dst), AliasPrefab, true);
            i++;
        }

        i = 0;
        while (SimilarMapsQueue.Count > 0 && i < BatchAliasNumber)
        {
            tmpStrAlias = SimilarMapsQueue.Last();
            float dst = SimilarMapsQueue.GetPriority(tmpStrAlias);
            SimilarMapsQueue.Remove(tmpStrAlias);

            Utility.renderAliasOnUI(AliasDragAreas[2].GetChild(0).GetComponent <RectTransform>(), ParameterManager.Instance.GridType, new StructuredAlias(tmpStrAlias, startMainMap, ParameterManager.Instance.EndCell, dst), AliasPrefab, true);

            i++;
        }

        //reset horizontal and vertical bars if exists
        ScrollRect sR = AliasDragAreas[0].GetComponent <ScrollRect>();

        if (sR != null)
        {
            Scrollbar hSb = sR.horizontalScrollbar;
            Scrollbar vSb = sR.verticalScrollbar;

            if (hSb != null)
            {
                hSb.value = .99f;
            }

            if (vSb != null)
            {
                vSb.value = .99f;
            }
        }

        gameObject.GetComponent <AliasGameEvaluator>().AliasGameEvaluatorHandler();
    }
    public Dictionary <int, StructuredAlias> GenerateNRandomAliasFromRealMap(StructuredAlias realMap, int N)
    {
        mainMap  = realMap.AliasMap;
        gridType = ParameterManager.Instance.GridType;
        Vector2Int startMainMap = realMap.start;
        int        width        = realMap.AliasMap.GetLength(0);
        int        height       = realMap.AliasMap.GetLength(1);

        //Map initialization.
        int i = 0;

        Dictionary <int, StructuredAlias> AliasBatch = new Dictionary <int, StructuredAlias>();

        Vector2Int startAlias = realMap.start;
        Vector2Int endAlias   = realMap.end;
        SimplePriorityQueue <TileObject[, ]> tmpPQ = new SimplePriorityQueue <TileObject[, ]>();
        bool isAliasSameAsReal = true;

        while (i < N)
        {
            //define here the width, height, start and end  of the chosen map
            TileObject[,] aliasMap = new TileObject[width, height];

            genMan.connectedGenerator.setBaseGeneratorParameters(gridType, width, height, startAlias, endAlias, (i % 2 == 0?1:-1) * RNG_Alias.Next(), false);
            genMan.cellularAutomataGenerator.setBaseGeneratorParameters(gridType, width, height, startAlias, endAlias, (i % 2 == 0 ? 1 : -1) * RNG_Alias.Next(), false);
            genMan.primGenerator.setBaseGeneratorParameters(gridType, width, height, startAlias, endAlias, (i % 2 == 0 ? 1 : -1) * RNG_Alias.Next(), false);

            switch (i % 3)
            {
            case 0:
                aliasMap = genMan.connectedGenerator.generateMapGeneral(ParameterManager.Instance.IsTrapsOnMapBorder, (float)RNG_Alias.NextDouble());
                break;

            case 1:
                float prcObsCA = (float)RNG_Alias.NextDouble();
                aliasMap = genMan.cellularAutomataGenerator.generateMapGeneral(ParameterManager.Instance.IsTrapsOnMapBorder, prcObsCA, 1 + (prcObsCA <= .5f && !(i % 2 == 1)?0:RNG_Alias.Next(0, 6)), 5, i % 2 == 1, 0, 0);
                break;

            case 2:
                aliasMap = genMan.primGenerator.generateMapGeneral(ParameterManager.Instance.IsTrapsOnMapBorder, (float)RNG_Alias.NextDouble());
                break;

            default:
                ErrorManager.ManageError(ErrorManager.Error.HARD_ERROR, "AliasManager: no map generator found.");
                break;
            }

            foreach (var m in BaseAliasCollisionMask)
            {
                if (Utility.in_bounds_General(new Vector2Int(startMainMap.x + m.x, startMainMap.y + m.y), mainMap.GetLength(0), mainMap.GetLength(1)) &&
                    Utility.in_bounds_General(new Vector2Int(startAlias.x + m.x, startAlias.y + m.y), aliasMap.GetLength(0), aliasMap.GetLength(1)))
                {
                    aliasMap[startAlias.x + m.x, startAlias.y + m.y].type = realMap.AliasMap[startMainMap.x + m.x, startMainMap.y + m.y].type;
                }
            }

            for (int h = 0; h < width; h++)
            {
                for (int k = 0; k < height; k++)
                {
                    isAliasSameAsReal &= (aliasMap[h, k].type == realMap.AliasMap[h, k].type);

                    if (!isAliasSameAsReal)
                    {
                        break;
                    }
                }
                if (!isAliasSameAsReal)
                {
                    break;
                }
            }

            if (MapEvaluator.isEndReachable(aliasMap, gridType, startAlias, endAlias, ParameterManager.Instance.allowAutosolverForAlias).First() == endAlias && !isAliasSameAsReal)
            {
                //if the map has a path from start to end, add it
                float dst = MapEvaluator.BinaryMapSimilarity(mainMap, aliasMap, startMainMap, startAlias);
                tmpPQ.Enqueue(aliasMap, dst);


                i++;
            }
        }

        i = 0;
        TileObject[,] tmpStrAlias;
        while (i < N)
        {
            if (ParameterManager.Instance.considerSimilar)
            {
                float dst = tmpPQ.GetPriority(tmpPQ.First());
                tmpStrAlias = tmpPQ.Dequeue();

                AliasBatch.Add(Guid.NewGuid().GetHashCode(), new StructuredAlias(tmpStrAlias, startAlias, endAlias, dst));

                i++;
            }

            if (ParameterManager.Instance.considerNovelty && i < N)
            {
                tmpStrAlias = tmpPQ.Last();
                float dst = tmpPQ.GetPriority(tmpStrAlias);
                tmpPQ.Remove(tmpStrAlias);

                AliasBatch.Add(Guid.NewGuid().GetHashCode(), new StructuredAlias(tmpStrAlias, startAlias, endAlias, dst));

                i++;
            }
        }

        return(AliasBatch);
    }
예제 #22
0
        public Player Simulate5()
        {
            Log.worldId           = WorldId;
            Log.stageId           = StageId;
            Log.waveCount         = _waves.Count;
            Log.clearedWaveNumber = 0;
            Log.newlyCleared      = false;
            Player.SpawnV2();
            TurnNumber = 0;
            for (var i = 0; i < _waves.Count; i++)
            {
                Characters = new SimplePriorityQueue <CharacterBase, decimal>();
                Characters.Enqueue(Player, TurnPriority / Player.SPD);

                WaveNumber = i + 1;
                WaveTurn   = 1;
                _waves[i].SpawnV2(this);
                while (true)
                {
                    // 제한 턴을 넘어서는 경우 break.
                    if (TurnNumber > TurnLimit)
                    {
                        if (i == 0)
                        {
                            Result = BattleLog.Result.Lose;
                            if (StageId < GameConfig.MimisbrunnrStartStageId)
                            {
                                Player.GetExp((int)(Exp * 0.3m), true);
                            }
                        }
                        else
                        {
                            Result = BattleLog.Result.TimeOver;
                        }
                        break;
                    }

                    // 캐릭터 큐가 비어 있는 경우 break.
                    if (!Characters.TryDequeue(out var character))
                    {
                        break;
                    }

                    character.Tick();

                    // 플레이어가 죽은 경우 break;
                    if (Player.IsDead)
                    {
                        if (i == 0)
                        {
                            Result = BattleLog.Result.Lose;
                            if (StageId < GameConfig.MimisbrunnrStartStageId)
                            {
                                Player.GetExp((int)(Exp * 0.3m), true);
                            }
                        }
                        else
                        {
                            Result = BattleLog.Result.Win;
                        }
                        break;
                    }

                    // 플레이어의 타겟(적)이 없는 경우 break.
                    if (!Player.Targets.Any())
                    {
                        Result = BattleLog.Result.Win;
                        Log.clearedWaveNumber = WaveNumber;

                        switch (WaveNumber)
                        {
                        case 1:
                            if (StageId < GameConfig.MimisbrunnrStartStageId)
                            {
                                Player.GetExp(Exp, true);
                            }

                            break;

                        case 2:
                        {
                            ItemMap = Player.GetRewards(_waveRewards);
                            var dropBox = new DropBox(null, _waveRewards);
                            Log.Add(dropBox);
                            var getReward = new GetReward(null, _waveRewards);
                            Log.Add(getReward);
                            break;
                        }

                        default:
                            if (WaveNumber == _waves.Count)
                            {
                                if (!IsCleared)
                                {
                                    Log.newlyCleared = true;
                                }
                            }

                            break;
                        }

                        break;
                    }

                    foreach (var other in Characters)
                    {
                        var current = Characters.GetPriority(other);
                        var speed   = current * 0.6m;
                        Characters.UpdatePriority(other, speed);
                    }

                    Characters.Enqueue(character, TurnPriority / character.SPD);
                }

                // 제한 턴을 넘거나 플레이어가 죽은 경우 break;
                if (TurnNumber > TurnLimit ||
                    Player.IsDead)
                {
                    break;
                }
            }

            Log.result = Result;
            return(Player);
        }
예제 #23
0
    public Dictionary <int, StructuredAlias> PurelyRandom(StructuredAlias realMap, EvaluateNode Eval)
    {
        AliasChallengePriorityQueue = new SimplePriorityQueue <Dictionary <int, StructuredAlias> >();
        iterationRandomRestart      = 0;
        graphPlot.Clear();

        ParameterManager pMan = ParameterManager.Instance;

        TimeCap      = pMan.timeCap;
        BatchAliases = pMan.aliasNum;
        System.Diagnostics.Stopwatch sWatch = StopwatchProxy.Instance.Stopwatch;
        AliasGeneratorManager        aGMan  = AliasGeneratorManager.Instance;

        sWatch.Stop();
        sWatch.Reset();
        sWatch.Start();

        int totalIterations = 0;

        while (totalIterations < randomIterations)
        {
            Dictionary <int, StructuredAlias> randomAliases = aGMan.GenerateNRandomAliasFromRealMap(realMap, BatchAliases);

            try
            {
                if (sWatch.ElapsedMilliseconds > pMan.timeCap * 1000f && pMan.timeCap >= 0)
                {
                    throw new Exception("Time cap elapsed.\n");
                }
                float tmpEval = (float)Eval(realMap, randomAliases);
                AliasChallengePriorityQueue.Enqueue(randomAliases, -(float)tmpEval);
                graphPlot.Add(new Tuple <float, float>(iterationRandomRestart, Mathf.Abs((float)tmpEval)));
            }
            catch (Exception e)
            {
                ErrorManager.ManageError(ErrorManager.Error.SOFT_ERROR, e.Message + sWatch.ElapsedMilliseconds / 1000f + "s #iteration: " + totalIterations + SaveAliasPurelyRandom());
                sWatch.Stop();
                sWatch.Reset();
                return(AliasChallengePriorityQueue.Dequeue());
            }
            totalIterations++;
        }



        GeneratorUIManager.Instance.showMessageDialogBox("SIMPLERANDOM-F= " + Mathf.Abs(AliasChallengePriorityQueue.GetPriority(AliasChallengePriorityQueue.First)) + "\nExecution time: " + sWatch.ElapsedMilliseconds / 1000f + "s #iteration: " + totalIterations + SaveAliasPurelyRandom());
        sWatch.Stop();
        sWatch.Reset();
        return(AliasChallengePriorityQueue.Dequeue());
    }
    private static PathfindingResult RunPathfinder(Axial start, Axial end)
    {
        SimplePriorityQueue <Node> openNodes   = new SimplePriorityQueue <Node>();
        Dictionary <Axial, Node>   closedNodes = new Dictionary <Axial, Node>();

        Node startNode = new Node(start, 0, GetHeuristic(start, end));
        Node current   = null;

        openNodes.Enqueue(startNode, startNode.Cost);

        while (openNodes.Count > 0)
        {
            current = openNodes.Dequeue();
            closedNodes.Add(current.Position, current);

            if (current == end) // Reached end
            {
                break;
            }

            foreach (AxialDirection direction in AxialDirection.AllDirections)
            {
                Axial neighborPosition = current.Position + direction;

                if (!Utility.IsAxialPositionWalkable(neighborPosition))
                {
                    continue;
                }

                float newNeighborCost = current.Cost + GetMovementCost(current, direction);
                float heuristic       = GetHeuristic(neighborPosition, end);
                Node  neighbor        = new Node(neighborPosition, newNeighborCost, heuristic, current);

                // Update surrounding nodes if we have a better path, even if they've already been evaluated
                if (openNodes.Contains(neighbor))
                {
                    // The heuristic is deterministic, so this will get us the pure cost of the node
                    float currentCost = openNodes.GetPriority(neighbor) - heuristic;

                    if (newNeighborCost < currentCost)
                    {
                        openNodes.Remove(neighbor);
                    }
                }
                if (closedNodes.ContainsKey(neighborPosition))
                {
                    float currentCost = closedNodes[neighborPosition].Cost;
                    if (newNeighborCost < currentCost)
                    {
                        closedNodes.Remove(neighborPosition);
                    }
                }

                // Add them to the queue if applicable
                if (!openNodes.Contains(neighbor) && !closedNodes.ContainsKey(neighbor.Position))
                {
                    openNodes.Enqueue(neighbor, neighbor.FullValue);
                }
            }
        }

        return(CalculateResults(current));

        PathfindingResult CalculateResults(Node endNode)
        {
            if (endNode == null)
            {
                Debug.LogError($"Couldn't calculate path between {start} and {end}");
                return(null);
            }

            PathfindingResult result = new PathfindingResult()
            {
                OpenNodes   = openNodes,
                CloesdNodes = closedNodes,
            };

            result.FinishedPath = new LinkedList <Vector2>();
            result.FinishedPath.AddFirst(endNode);

            Node currentNode = endNode;

            while (currentNode.Parent != null)
            {
                currentNode = closedNodes[currentNode.Parent.Value];
                result.FinishedPath.AddFirst(currentNode);
            }

            // We're already in the first node, walking to it would just force us to walk to the center of the node, and we don't want that.
            result.FinishedPath.RemoveFirst();

            return(result);
        }
    }
예제 #25
0
        public Player SimulateV4()
        {
#if TEST_LOG
            var sb = new System.Text.StringBuilder();
#endif
            Log.stageId = _stageId;
            Spawn();
            Characters = new SimplePriorityQueue <CharacterBase, decimal>();
            Characters.Enqueue(Player, TurnPriority / Player.SPD);
            Characters.Enqueue(_enemyPlayer, TurnPriority / _enemyPlayer.SPD);
            TurnNumber = 1;
            WaveNumber = 1;
            WaveTurn   = 1;
#if TEST_LOG
            sb.Clear();
            sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
            sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
            sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
            sb.Append($" / {nameof(WaveNumber)} Start");
            UnityEngine.Debug.LogWarning(sb.ToString());
#endif
            while (true)
            {
                if (TurnNumber > MaxTurn)
                {
                    Result = BattleLog.Result.TimeOver;
#if TEST_LOG
                    sb.Clear();
                    sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                    sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                    sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                    sb.Append($" / {nameof(MaxTurn)}: {MaxTurn}");
                    sb.Append($" / {nameof(Result)}: {Result.ToString()}");
                    UnityEngine.Debug.LogWarning(sb.ToString());
#endif
                    break;
                }

                // 캐릭터 큐가 비어 있는 경우 break.
                if (!Characters.TryDequeue(out var character))
                {
                    break;
                }

                character.Tick();

                // 플레이어가 죽은 경우 break;
                if (Player.IsDead)
                {
                    Result = BattleLog.Result.Lose;
#if TEST_LOG
                    sb.Clear();
                    sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                    sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                    sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                    sb.Append($" / {nameof(Player)} Dead");
                    sb.Append($" / {nameof(Result)}: {Result.ToString()}");
                    UnityEngine.Debug.LogWarning(sb.ToString());
#endif
                    break;
                }

                // 플레이어의 타겟(적)이 없는 경우 break.
                if (!Player.Targets.Any())
                {
                    Result = BattleLog.Result.Win;
                    Log.clearedWaveNumber = WaveNumber;

                    break;
                }

                foreach (var other in Characters)
                {
                    var current = Characters.GetPriority(other);
                    var speed   = current * 0.6m;
                    Characters.UpdatePriority(other, speed);
                }

                Characters.Enqueue(character, TurnPriority / character.SPD);
            }

            Log.diffScore = _arenaInfo.UpdateV4(_enemyInfo, Result);
            Log.score     = _arenaInfo.Score;

            var itemSelector = new WeightedSelector <StageSheet.RewardData>(Random);
            var rewardSheet  = WeeklyArenaRewardSheet;
            foreach (var row in rewardSheet.OrderedList)
            {
                var reward = row.Reward;
                if (reward.RequiredLevel <= Player.Level)
                {
                    itemSelector.Add(reward, reward.Ratio);
                }
            }

            var max = _arenaInfo.GetRewardCount();
            _reward = SetRewardV2(itemSelector, max, Random, MaterialItemSheet);
            var getReward = new GetReward(null, _reward);
            Log.Add(getReward);
            Log.result = Result;
#if TEST_LOG
            sb.Clear();
            sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
            sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
            sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
            sb.Append($" / {nameof(Simulate)} End");
            sb.Append($" / {nameof(Result)}: {Result.ToString()}");
            UnityEngine.Debug.LogWarning(sb.ToString());
#endif
            return(Player);
        }
예제 #26
0
        public Player Simulate3()
        {
#if TEST_LOG
            var sb = new System.Text.StringBuilder();
#endif
            Log.worldId           = WorldId;
            Log.stageId           = StageId;
            Log.waveCount         = _waves.Count;
            Log.clearedWaveNumber = 0;
            Log.newlyCleared      = false;
            Player.SpawnV2();
            TurnNumber = 0;
            for (var i = 0; i < _waves.Count; i++)
            {
                Characters = new SimplePriorityQueue <CharacterBase, decimal>();
                Characters.Enqueue(Player, TurnPriority / Player.SPD);

                WaveNumber = i + 1;
                WaveTurn   = 1;
                _waves[i].SpawnV2(this);
#if TEST_LOG
                sb.Clear();
                sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                sb.Append(" / Wave Start");
                UnityEngine.Debug.LogWarning(sb.ToString());
#endif
                while (true)
                {
                    // 제한 턴을 넘어서는 경우 break.
                    if (TurnNumber > TurnLimit)
                    {
                        if (i == 0)
                        {
                            Result = BattleLog.Result.Lose;
                            if (StageId < GameConfig.MimisbrunnrStartStageId)
                            {
                                Player.GetExp3((int)(Exp * 0.3m), true);
                            }
                        }
                        else
                        {
                            Result = BattleLog.Result.TimeOver;
                        }
#if TEST_LOG
                        sb.Clear();
                        sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                        sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                        sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                        sb.Append($" / {nameof(TurnLimit)}: {TurnLimit}");
                        sb.Append($" / {nameof(Result)}: {Result.ToString()}");
                        UnityEngine.Debug.LogWarning(sb.ToString());
#endif
                        break;
                    }

                    // 캐릭터 큐가 비어 있는 경우 break.
                    if (!Characters.TryDequeue(out var character))
                    {
                        break;
                    }
#if TEST_LOG
                    var turnBefore = TurnNumber;
#endif
                    character.Tick();
#if TEST_LOG
                    var turnAfter = TurnNumber;
                    if (turnBefore != turnAfter)
                    {
                        sb.Clear();
                        sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                        sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                        sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                        sb.Append(" / Turn End");
                        UnityEngine.Debug.LogWarning(sb.ToString());
                    }
#endif

                    // 플레이어가 죽은 경우 break;
                    if (Player.IsDead)
                    {
                        if (i == 0)
                        {
                            Result = BattleLog.Result.Lose;
                            if (StageId < GameConfig.MimisbrunnrStartStageId)
                            {
                                Player.GetExp3((int)(Exp * 0.3m), true);
                            }
                        }
                        else
                        {
                            Result = BattleLog.Result.Win;
                        }
#if TEST_LOG
                        sb.Clear();
                        sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                        sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                        sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                        sb.Append($" / {nameof(Player)} Dead");
                        sb.Append($" / {nameof(Result)}: {Result.ToString()}");
                        UnityEngine.Debug.LogWarning(sb.ToString());
#endif
                        break;
                    }

                    // 플레이어의 타겟(적)이 없는 경우 break.
                    if (!Player.Targets.Any())
                    {
                        Result = BattleLog.Result.Win;
                        Log.clearedWaveNumber = WaveNumber;

                        switch (WaveNumber)
                        {
                        case 1:
                            if (StageId < GameConfig.MimisbrunnrStartStageId)
                            {
                                Player.GetExp3(Exp, true);
                            }

                            break;

                        case 2:
                        {
                            ItemMap = Player.GetRewards2(_waveRewards);
                            var dropBox = new DropBox(null, _waveRewards);
                            Log.Add(dropBox);
                            var getReward = new GetReward(null, _waveRewards);
                            Log.Add(getReward);
                            break;
                        }

                        default:
                            if (WaveNumber == _waves.Count)
                            {
                                if (!IsCleared)
                                {
                                    Log.newlyCleared = true;
                                }
                            }

                            break;
                        }

                        break;
                    }

                    foreach (var other in Characters)
                    {
                        var current = Characters.GetPriority(other);
                        var speed   = current * 0.6m;
                        Characters.UpdatePriority(other, speed);
                    }

                    Characters.Enqueue(character, TurnPriority / character.SPD);
                }

                // 제한 턴을 넘거나 플레이어가 죽은 경우 break;
                if (TurnNumber > TurnLimit ||
                    Player.IsDead)
                {
                    break;
                }
            }

            Log.result = Result;
#if TEST_LOG
            sb.Clear();
            sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
            sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
            sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
            sb.Append($" / {nameof(Simulate)} End");
            sb.Append($" / {nameof(Result)}: {Result.ToString()}");
            UnityEngine.Debug.LogWarning(sb.ToString());
#endif
            return(Player);
        }
        public void Execute(int _SourceNodeId, int _TargetNodeId)
        {
            Console.WriteLine("Start Dijkstra");
            try
            {
                foreach (var hEdge in FUsedGraph.GetEdgeIndices())
                {
                    if (hEdge.GetWeightValue() < 0.0)
                    {
                        throw new DijkastraException("Negative Kantengewichte gefunden. Der Dijkstra-Algorithmus kann nicht mit mit negativen Werten umgehen.");
                    }
                }

                var  hNodeDictionary = FUsedGraph.GetNodeDictionary();
                var  hStartNode      = hNodeDictionary[_SourceNodeId];
                var  hTargetNode     = hNodeDictionary[_TargetNodeId];
                bool hTargetFound    = false;

                var hCostDictionary    = new Dictionary <INode, double>();
                var hParentNodeEdge    = new Dictionary <INode, Edge>(); // Speichert mit welcher Kante ein Knoten erreicht wurde
                var hNodePriorityQueue = new SimplePriorityQueue <INode, double>();
                var hVisitedNodes      = new HashSet <INode>();

                // Initialisierung
                foreach (var hNode in hNodeDictionary.Values)
                {
                    hParentNodeEdge.Add(hNode, null);
                    hCostDictionary.Add(hNode, Double.PositiveInfinity);
                }

                hNodePriorityQueue.Enqueue(hStartNode, 0.0);
                hCostDictionary[hStartNode] = 0.0;


                while (!hTargetFound)
                {
                    var hCurrentNode = hNodePriorityQueue.Dequeue();
                    hVisitedNodes.Add(hCurrentNode);

                    if (hCurrentNode == hTargetNode)
                    {
                        hTargetFound = true;
                        // break
                    }

                    foreach (var hNeighborEdge in hCurrentNode.NeighbourEdges)
                    {
                        if (!hVisitedNodes.Contains(hNeighborEdge.Node))
                        {
                            // Nachbar ist noch nicht besucht worden
                            var hTourCostToNeighbor = hCostDictionary[hCurrentNode] + hNeighborEdge.Edge.GetWeightValue();

                            // Ist der Nachbar schon in der Priority Queue drin und hab einen besseren Weg gefunden?
                            if (hNodePriorityQueue.Contains(hNeighborEdge.Node) && (hTourCostToNeighbor < hNodePriorityQueue.GetPriority(hNeighborEdge.Node)))
                            {
                                hNodePriorityQueue.UpdatePriority(hNeighborEdge.Node, hTourCostToNeighbor);
                                hParentNodeEdge[hNeighborEdge.Node] = hNeighborEdge.Edge;
                                hCostDictionary[hNeighborEdge.Node] = hTourCostToNeighbor;
                            }
                            else if (!hNodePriorityQueue.Contains(hNeighborEdge.Node))
                            {
                                // Nachbarknoten wurde noch garnicht bemerkt. Also mit den gerade gefunden Kosten in die Priority Queue
                                hNodePriorityQueue.Enqueue(hNeighborEdge.Node, hTourCostToNeighbor);
                                hParentNodeEdge[hNeighborEdge.Node] = hNeighborEdge.Edge;
                                hCostDictionary[hNeighborEdge.Node] = hTourCostToNeighbor;
                            }
                        }
                    }
                }

                // Jetzt vom Zielknonten zurück zum Startknoten ;)
                var hTmpNode           = hTargetNode;
                var hShortestPathStack = new Stack <int>();
                var hCosts             = 0.0;
                while (hTmpNode != hStartNode)
                {
                    hCosts += hParentNodeEdge[hTmpNode].GetWeightValue();
                    hShortestPathStack.Push(hTmpNode.Id);

                    // "Knoten davor"
                    if (hParentNodeEdge[hTmpNode] is DirectedEdge)
                    {
                        DirectedEdge hEdge = (DirectedEdge)hParentNodeEdge[hTmpNode];
                        hTmpNode = hEdge.GetEdgeSource();
                    }
                    else if (hParentNodeEdge[hTmpNode] is UndirectedEdge)
                    {
                        UndirectedEdge hEdge = (UndirectedEdge)hParentNodeEdge[hTmpNode];
                        hTmpNode = hParentNodeEdge[hTmpNode].GetOtherEndpoint(hTmpNode);
                    }
                }

                hShortestPathStack.Push(hStartNode.Id);

                // Ausgabe
                Console.WriteLine("Kürzeste Route:\t" + string.Join(",", hShortestPathStack));
                Console.WriteLine("Kosten:\t" + hCosts);
            }
            catch (DijkastraException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }  // Execute
예제 #28
0
        public override Player Simulate()
        {
#if TEST_LOG
            var sb = new System.Text.StringBuilder();
#endif
            Log.stageId = stageId;
            Spawn();
            Characters = new SimplePriorityQueue <CharacterBase, decimal>();
            Characters.Enqueue(Player, TurnPriority / Player.SPD);
            Characters.Enqueue(_enemyPlayer, TurnPriority / _enemyPlayer.SPD);
            TurnNumber = 1;
            WaveNumber = 1;
            WaveTurn   = 1;
#if TEST_LOG
            sb.Clear();
            sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
            sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
            sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
            sb.Append($" / {nameof(WaveNumber)} Start");
            UnityEngine.Debug.LogWarning(sb.ToString());
#endif
            while (true)
            {
                if (TurnNumber > MaxTurn)
                {
                    Result = BattleLog.Result.TimeOver;
#if TEST_LOG
                    sb.Clear();
                    sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                    sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                    sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                    sb.Append($" / {nameof(MaxTurn)}: {MaxTurn}");
                    sb.Append($" / {nameof(Result)}: {Result.ToString()}");
                    UnityEngine.Debug.LogWarning(sb.ToString());
#endif
                    break;
                }

                // 캐릭터 큐가 비어 있는 경우 break.
                if (!Characters.TryDequeue(out var character))
                {
                    break;
                }

                character.Tick();

                // 플레이어가 죽은 경우 break;
                if (Player.IsDead)
                {
                    Result = BattleLog.Result.Lose;
#if TEST_LOG
                    sb.Clear();
                    sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
                    sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
                    sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
                    sb.Append($" / {nameof(Player)} Dead");
                    sb.Append($" / {nameof(Result)}: {Result.ToString()}");
                    UnityEngine.Debug.LogWarning(sb.ToString());
#endif
                    break;
                }

                // 플레이어의 타겟(적)이 없는 경우 break.
                if (!Player.Targets.Any())
                {
                    Result = BattleLog.Result.Win;
                    Log.clearedWaveNumber = WaveNumber;

                    break;
                }

                foreach (var other in Characters)
                {
                    var current = Characters.GetPriority(other);
                    var speed   = current * 0.6m;
                    Characters.UpdatePriority(other, speed);
                }

                Characters.Enqueue(character, TurnPriority / character.SPD);
            }

            Log.result = Result;
#if TEST_LOG
            sb.Clear();
            sb.Append($"{nameof(TurnNumber)}: {TurnNumber}");
            sb.Append($" / {nameof(WaveNumber)}: {WaveNumber}");
            sb.Append($" / {nameof(WaveTurn)}: {WaveTurn}");
            sb.Append($" / {nameof(Simulate)} End");
            sb.Append($" / {nameof(Result)}: {Result.ToString()}");
            UnityEngine.Debug.LogWarning(sb.ToString());
#endif
            return(Player);
        }
예제 #29
0
        public List <Vector2> GetPath(Vector2 from, Vector2 to)
        {
            List <Vector2> returnList = new List <Vector2>()
            {
                from
            };

            Vector2            vectorFrom = TranslateToNavGrid(from);
            NavigationGridCell cellFrom   = GetCell((short)vectorFrom.X, (short)vectorFrom.Y);

            Vector2            vectorTo = TranslateToNavGrid(to);
            NavigationGridCell goal     = GetCell((short)vectorTo.X, (short)vectorTo.Y);

            if (cellFrom != null && goal != null)
            {
                SimplePriorityQueue <Stack <NavigationGridCell> > priorityQueue = new SimplePriorityQueue <Stack <NavigationGridCell> >();
                Stack <NavigationGridCell>           start      = new Stack <NavigationGridCell>();
                Dictionary <int, NavigationGridCell> closedList = new Dictionary <int, NavigationGridCell>();
                Stack <NavigationGridCell>           path       = null;

                start.Push(cellFrom);
                priorityQueue.Enqueue(start, NavigationGridCell.Distance(cellFrom, goal));
                closedList.Add(cellFrom.ID, cellFrom);

                // while there are still paths to explore
                while (true)
                {
                    if (!priorityQueue.TryFirst(out _))
                    {
                        // no solution
                        return(null);
                    }

                    float currentCost = priorityQueue.GetPriority(priorityQueue.First);
                    priorityQueue.TryDequeue(out path);

                    NavigationGridCell cell = path.Peek();

                    currentCost -= (NavigationGridCell.Distance(cell, goal) + cell.Heuristic); // decrease the heuristic to get the cost

                    // found the min solution return it (path)
                    if (cell.ID == goal.ID)
                    {
                        break;
                    }

                    foreach (NavigationGridCell neighborCell in GetCellNeighbors(cell))
                    {
                        // if the neighbor in the closed list - skip
                        if (closedList.TryGetValue(neighborCell.ID, out _))
                        {
                            continue;
                        }

                        // not walkable - skip
                        if (neighborCell.HasFlag(NavigationGridCellFlags.NOT_PASSABLE) || neighborCell.HasFlag(NavigationGridCellFlags.SEE_THROUGH))
                        {
                            closedList.Add(neighborCell.ID, neighborCell);
                            continue;
                        }

                        // calculate the new path and cost +heuristic and add to the priority queue
                        Stack <NavigationGridCell> npath = new Stack <NavigationGridCell>(new Stack <NavigationGridCell>(path));

                        npath.Push(neighborCell);
                        // add 1 for every cell used
                        priorityQueue.Enqueue(npath, currentCost + 1 + neighborCell.Heuristic + neighborCell.ArrivalCost + neighborCell.AdditionalCost
                                              + NavigationGridCell.Distance(neighborCell, goal));
                        closedList.Add(neighborCell.ID, neighborCell);
                    }
                }

                NavigationGridCell[] pathArray = path.ToArray();
                Array.Reverse(pathArray);

                List <NavigationGridCell> pathList = SmoothPath(new List <NavigationGridCell>(pathArray));

                pathList.RemoveAt(0); // removes the first point

                foreach (NavigationGridCell navGridCell in pathList.ToArray())
                {
                    returnList.Add(TranslateFrmNavigationGrid(navGridCell.Locator));
                }

                return(returnList);
            }

            return(null);
        }
예제 #30
0
        IEnumerable <Point> CalculatePath(Maze maze, Point source, Point destination)
        {
            List <Point> pathSteps = new List <Point>();
            SimplePriorityQueue <Node, int> openSet = new SimplePriorityQueue <Node, int>();
            HashSet <Point> closedSet = new HashSet <Point>();

            // Start from the endpoint, so that later traversing the parents we get the real path
            openSet.Enqueue(new Node(maze.GetTile(destination), null), 0);

            Node finalNode = null;

            while (openSet.Count != 0)
            {
                Node currentNode = openSet.Dequeue();
                closedSet.Add(currentNode.Tile.Position);

                foreach (var point in currentNode.Tile.AccessibleTiles)
                {
                    if (closedSet.Contains(point))
                    {
                        // Already traversed
                        continue;
                    }

                    Node adjacentNode = new Node(maze.GetTile(point), currentNode, currentNode.G + 1);
                    if (point.Equals(source))
                    {
                        finalNode = adjacentNode;
                        break;
                    }

                    int newPriority = CalculatePriority(point, destination, adjacentNode.G);
                    if (openSet.Contains(adjacentNode))
                    {
                        if (newPriority < openSet.GetPriority(adjacentNode))
                        {
                            openSet.UpdatePriority(adjacentNode, newPriority);
                        }
                    }
                    else
                    {
                        openSet.Enqueue(adjacentNode, newPriority);
                    }
                }

                if (finalNode != null)
                {
                    break;
                }
            }

            Node current = finalNode?.Parent;

            while (current != null)
            {
                pathSteps.Add(current.Tile.Position);
                current = current.Parent;
            }

            return(pathSteps);
        }