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... }
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);
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); }
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; } } }
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); } } }
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++; } }
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); }
/// <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); } } }
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); }
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); }
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); }
//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()); }
// 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); }
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)); }
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); }
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); }
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); } }
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); }
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
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); }
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); }
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); }