private static void ExpandNode(PlaceNode currentNode, PlaceNode end, PriorityQueue openList, List <PlaceNode> closeList) { foreach (var successor in currentNode.GetReachableNeighbours()) { if (closeList.Contains(successor)) { continue; } var tentativeG = successor.CostToReach + 1; if (openList.Contains(successor) && tentativeG >= successor.CostToReach) { continue; } if (openList.Contains(successor)) { openList.Remove(successor); } successor.CostToReach = tentativeG; successor.F = tentativeG + CalculateHeuristic(successor.TilePosition, end.TilePosition); openList.Enqueue(successor); } }
public List <PlaceNode> FindWayTo(Point start, PlaceNode end) { var openList = new PriorityQueue(); var closeList = new List <PlaceNode>(); var startNode = _nodesByTilePosition[start]; startNode.F = 0; openList.Enqueue(startNode); while (openList.Count > 0) { var currentNode = (PlaceNode)openList.Dequeue(); if (currentNode.TilePosition == end.TilePosition) { closeList.Add(currentNode); break; } ExpandNode(currentNode, end, openList, closeList); closeList.Add(currentNode); } return(closeList); }
private void CreatePlaceNodeObjects() { //todo: refactor magic numbers for (var x = 0; x < 15; x++) { for (var y = 0; y < 13; y++) { var node = new PlaceNode(new Point(x, y)); _nodesByTilePosition.Add(node.TilePosition, node); } } }
private void FillToAvoidWithExplosionRadius(HashSet <Point> pointsToAvoid, PlaceNode bombNode) { var currentUp = bombNode; var currentDown = bombNode; var currentLeft = bombNode; var currentRight = bombNode; pointsToAvoid.Add(bombNode.TilePosition); for (var i = 0; i < ((BombImp)bombNode.Bomb).ExplosionRange; i++) { currentLeft = AddDirective(pointsToAvoid, currentLeft, p2 => p2.Left); currentRight = AddDirective(pointsToAvoid, currentRight, p2 => p2.Right); currentUp = AddDirective(pointsToAvoid, currentUp, p2 => p2.Up); currentDown = AddDirective(pointsToAvoid, currentDown, p2 => p2.Down); } }
private static PlaceNode GetMinCostNode(IEnumerable <PlaceNode> nodes) { PlaceNode min = null; foreach (var placeNode in nodes) { if (min == null) { min = placeNode; } else if (min.CostToReach > placeNode.CostToReach) { min = placeNode; } } return(min); }
private PlaceNode AddDirective(HashSet <Point> pointsToAvoid, PlaceNode node, Func <PlaceNode, PlaceNode> navi) { if (node == null) { return(null); } var placeNode = navi(node); if (!placeNode.IsReachable) { return(null); } pointsToAvoid.Add(placeNode.TilePosition); return(placeNode); }
public PlaceNode GetLowestCostNeighbour() { PlaceNode current = null; foreach (var placeNode in GetReachableNeighbours()) { if (current == null) { current = placeNode; } else if (placeNode.CostToReach < current.CostToReach) { current = placeNode; } } return(current); }
private void ScanRecursive(LevelImp level, PlaceNode currentNode, int depth) { if (currentNode.IsReachable) { return; } if (level.IsCollidable(currentNode.TilePosition)) { var b = level.GetFringe(currentNode.TilePosition); if (b.Type == BlockType.Box && b.IsActive) { currentNode.IsBoxToDestroy = true; ReachableBoxNodes.Add(currentNode); return; } currentNode.Bomb = level.ActualBombs.FirstOrDefault(bb => bb.TilePosition == currentNode.TilePosition); if (currentNode.Bomb != null) { BombNodes.Add(currentNode); } if (depth > 0) { return; } } var item = level.GetItemData(currentNode.TilePosition); if (item.IsActive && item.Type != ItemType.Empty) { currentNode.ItemType = item.Type; ItemNodes.Add(currentNode); } currentNode.IsReachable = true; currentNode.CostToReach = depth; ReachableNodes.Add(currentNode.TilePosition, currentNode); ScanRecursive(level, currentNode.Left, depth + 1); ScanRecursive(level, currentNode.Right, depth + 1); ScanRecursive(level, currentNode.Up, depth + 1); ScanRecursive(level, currentNode.Down, depth + 1); }