Пример #1
0
        // Search for the start and end points.
        // Done together for efficiency.
        private void FindStartAndEnd()
        {
            Vector2Int startPos = new Vector2Int(), endPos = new Vector2Int();
            bool       foundStart = false, foundEnd = false;

            for (int row = 0; row < _map.GetLength(0); row++)
            {
                if (foundStart && foundEnd)
                {
                    break;
                }

                for (int col = 0; col < _map.GetLength(1); col++)
                {
                    if (foundStart && foundEnd)
                    {
                        break;
                    }

                    var current = _map[row, col];
                    if (current.Equals('S'))
                    {
                        startPos   = new Vector2Int(col, row);
                        foundStart = true;
                    }
                    else if (current.Equals('E'))
                    {
                        endPos   = new Vector2Int(col, row);
                        foundEnd = true;
                    }
                }
            }

            if (!foundStart || !foundEnd)
            {
                throw new Exception("No start and end points!");
            }

            _end   = new WeighedBlock(endPos, null);
            _start = new WeighedBlock(startPos, _end);
        }
Пример #2
0
        // Creates WeighedBlocks only for the positions checked.
        public void FindPath()
        {
            FindStartAndEnd();

            // Now we need to weigh the blocks starting from the Start block
            _queue.SortedAddFront(_start);
            bool atEnd = false;

            while (_queue.Count > 0)
            {
                /* For debugging purposes.
                 * Console.Clear();
                 * Console.WriteLine($"Cleared screen! {_queue.Count}");
                 * foreach (var b in _queue)
                 * {
                 *  var prev = b.PrevBlock != null ? b.PrevBlock.Position.ToString() : "null";
                 *  Console.WriteLine($"Pos: {b.Position}, Prev: {prev}, Step: {b.StepWeight}, Dist: {b.DistanceWeight}, Total: {b.TotalWeight}");
                 * }
                 * /**/

                var block = _queue.PopFront();

                // Now we get the surrounding blocks
                var positions = block.GetSurroundingLocations();
                var sizeX     = _map.GetLength(1);
                var sizeY     = _map.GetLength(0);

                foreach (var pos in positions)
                {
                    // Skips the positions outside our map
                    if (pos.x < 0 || pos.x >= sizeX)
                    {
                        continue;
                    }
                    if (pos.y < 0 || pos.y >= sizeY)
                    {
                        continue;
                    }

                    // Skips the previous block that this block is linked to
                    if (block.PrevBlock != null && pos == block.PrevBlock.Position)
                    {
                        continue;
                    }

                    // Skips walls
                    var mapValue = _map[pos.y, pos.x];
                    if (mapValue.Equals('W'))
                    {
                        continue;
                    }

                    // Breaks out of this for loop when one of the neighboring
                    // blocks is the end block.
                    if (mapValue.Equals('E'))
                    {
                        Console.WriteLine("Found end!\n");
                        _end.StepWeight = block.StepWeight + 1;
                        _end.PrevBlock  = block;
                        atEnd           = true;
                        break;
                    }

                    // Skips if the new block has already been processed
                    // or is in the queue of being processed.
                    var newBlock = new WeighedBlock(pos, _end);
                    if (_finishedBlocks.Contains(newBlock))
                    {
                        continue;
                    }
                    if (_queue.Contains(newBlock))
                    {
                        continue;
                    }

                    newBlock.StepWeight = block.StepWeight + 1;
                    newBlock.PrevBlock  = block;

                    _queue.SortedAddFront(newBlock);
                }

                if (atEnd)
                {
                    break;
                }

                _finishedBlocks.Add(block);
            }

            TracePath();
        }