예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
 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);
         }
     }
 }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }