示例#1
0
        public List <int> FindPath(int s, int fx, int fy, int dist = 0)
        {
            if (_lastPath != null && fx == _lastFx && fy == _lastFy && _lastPath.Count > 0)
            {
                var(sx, sy, jj, pp)     = NavigationUtils.DecodeState(s);
                var(sx1, sy1, jj1, pp1) = NavigationUtils.DecodeState(_lastPath[0]);
                if (sx == sx1 && sy == sy1)
                {
                    _lastPath.RemoveAt(0);
                    return(_lastPath);
                }
            }

            var order = new LinkedList <int>();

            order.AddLast(s);

            var parent = new Dictionary <int, int>();

            parent.Add(s, s);
            int f = -1;

            while (order.Count > 0)
            {
                var currentCode = order.First.Value;
                order.RemoveFirst();
                var(x, y, j, p) = NavigationUtils.DecodeState(currentCode);
                if (Math.Abs(x - fx) <= dist && Math.Abs(y - fy) <= dist)
                {
                    f = currentCode;
                    break;
                }

                var currentPoint = NavigationUtils.EncodePoint(x, y);
                for (int move = 0; move < PointMaster.Moves; ++move)
                {
                    if (!_pointMaster.IsValidMove(currentPoint, move))
                    {
                        continue;
                    }
                    var newCode = ApplyMove(x, y, j, p, move);
                    if (newCode < 0 || parent.ContainsKey(newCode))
                    {
                        continue;
                    }
                    var(nx, ny, nj, np) = NavigationUtils.DecodeState(newCode);
                    parent[newCode]     = currentCode;
                    order.AddLast(newCode);
                }

                if (j == 1 && p == 1)
                {
                    var newCode = NavigationUtils.EncodeState(x, y, 0, 0);
                    if (newCode < 0 || parent.ContainsKey(newCode))
                    {
                        continue;
                    }
                    parent[newCode] = currentCode;
                    order.AddLast(newCode);
                }
            }

            if (f == -1)
            {
                return(null);
            }

            var path = new List <int>();
            var cur  = f;

            while (cur != s)
            {
                cur = parent[cur];
                if (cur == s)
                {
                    break;
                }
                path.Add(cur);
            }
            path.Reverse();


            order.Clear();
            parent.Clear();

            _lastFx   = fx;
            _lastFy   = fy;
            _lastPath = path;

            return(path);
        }
示例#2
0
        public void BuildPoints()
        {
            var oldWidth  = _game.Level.Tiles.Length;
            var oldHeight = _game.Level.Tiles[0].Length;

            _width  = oldWidth * Divisor;
            _height = oldHeight * Divisor;

            for (var i = 0; i < oldWidth; ++i)
            {
                for (var j = 0; j < oldHeight; ++j)
                {
                    if (_game.Level.Tiles[i][j] == Tile.JumpPad)
                    {
                        for (int i1 = Math.Max(0, i * Divisor - UnitHalfWidth); i1 <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++i1)
                        {
                            for (int j1 = Math.Max(0, j * Divisor - UnitHeight); j1 <= (j + 1) * Divisor; ++j1)
                            {
                                _jumpPoints.Set(NavigationUtils.EncodePoint(i1, j1), true);
                            }
                        }
                    }

                    if (_game.Level.Tiles[i][j] == Tile.Ladder)
                    {
                        for (int i1 = Math.Max(0, i * Divisor + 1), k = 0; i1 <= Math.Min((i + 1) * Divisor - 1, _width); ++i1, ++k)
                        {
                            for (int j1 = Math.Max(0, j * Divisor - UnitHalfHeight); j1 <= (j + 1) * Divisor; ++j1)
                            {
                                _groundPoints.Set(NavigationUtils.EncodePoint(i1, j1), true);
                                _dropPoints.Set(NavigationUtils.EncodePoint(i1, j1), true);
                                _ladderPoints.Set(NavigationUtils.EncodePoint(i1, j1), true);
                            }
                        }
                    }

                    if (_game.Level.Tiles[i][j] == Tile.Platform)
                    {
                        for (int k = Math.Max(0, i * Divisor - UnitHalfWidth); k <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++k)
                        {
                            _groundPoints.Set(NavigationUtils.EncodePoint(k, (j + 1) * Divisor), true);
                            _dropPoints.Set(NavigationUtils.EncodePoint(k, (j + 1) * Divisor), true);
                        }
                    }

                    if (_game.Level.Tiles[i][j] == Tile.Wall)
                    {
                        for (int i1 = Math.Max(0, i * Divisor - UnitHalfWidth); i1 <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++i1)
                        {
                            for (int j1 = Math.Max(0, j * Divisor - UnitHeight); j1 < (j + 1) * Divisor; ++j1)
                            {
                                _blockPoints.Set(NavigationUtils.EncodePoint(i1, j1), true);
                            }
                        }

                        var bottomExists = j * Divisor > UnitHeight;

                        for (int i1 = Math.Max(0, i * Divisor - UnitHalfWidth); i1 <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++i1)
                        {
                            _groundPoints.Set(NavigationUtils.EncodePoint(i1, (j + 1) * Divisor), true);
                            if (bottomExists)
                            {
                                _bottomPoints.Set(NavigationUtils.EncodePoint(i1, j * Divisor - UnitHeight - 1), true);
                            }
                        }

                        if (bottomExists)
                        {
                            if (i * Divisor > UnitHalfWidth)
                            {
                                _sharpLeftPoints.Set(
                                    NavigationUtils.EncodePoint(i * Divisor - UnitHalfWidth - 1,
                                                                j * Divisor - UnitHeight - 1), true);
                            }

                            if ((i + 1) * Divisor < _width - UnitHalfWidth)
                            {
                                _sharpRightPoints.Set(
                                    NavigationUtils.EncodePoint((i + 1) * Divisor + UnitHalfWidth + 1,
                                                                j * Divisor - UnitHeight - 1), true);
                            }
                        }
                    }
                }
            }
        }
示例#3
0
        private int ApplyMove(int x, int y, int j, int p, int move)
        {
            if (move <= 5 && j != 0)
            {
                return(-1);
            }
            if (move >= 6 && move <= 7 && p != 0)
            {
                return(-1);
            }
            if (move >= 8 && move <= 10 && !(j > 0 && p == 0))
            {
                return(-1);
            }
            if (move >= 14 && !(j > 1 && p == 1))
            {
                return(-1);
            }

            switch (move)
            {
            case 0: return(NavigationUtils.EncodeState(x - 1, y, 0, 0));

            case 1: return(NavigationUtils.EncodeState(x + 1, y, 0, 0));

            case 2: return(NavigationUtils.EncodeState(x - 1, y + 1, 32, 0));

            case 3: return(NavigationUtils.EncodeState(x + 1, y + 1, 32, 0));

            case 4: return(NavigationUtils.EncodeState(x, y + 1, 32, 0));

            case 5: return(NavigationUtils.EncodeState(x - 1, y - 1, 0, 0));

            case 6: return(NavigationUtils.EncodeState(x + 1, y - 1, 0, 0));

            case 7: return(NavigationUtils.EncodeState(x, y - 1, 0, 0));

            case 8: return(NavigationUtils.EncodeState(x - 1, y + 1, j - 1, 0));

            case 9: return(NavigationUtils.EncodeState(x + 1, y + 1, j - 1, 0));

            case 10: return(NavigationUtils.EncodeState(x, y + 1, j - 1, 0));

            case 11: return(NavigationUtils.EncodeState(x - 1, y + 2, 31, 1));

            case 12: return(NavigationUtils.EncodeState(x + 1, y + 2, 31, 1));

            case 13: return(NavigationUtils.EncodeState(x, y + 2, 31, 1));

            case 14: return(NavigationUtils.EncodeState(x - 1, y + 2, j - 1, 1));

            case 15: return(NavigationUtils.EncodeState(x + 1, y + 2, j - 1, 1));

            case 16: return(NavigationUtils.EncodeState(x, y + 2, j - 1, 1));

            case 17: return(NavigationUtils.EncodeState(x, y, 0, 0));

            default:
                //impossible
                return(-1);
            }
        }
示例#4
0
 public bool IsPointLadder(int x, int y) => _ladderPoints.Get(NavigationUtils.EncodePoint(x, y));
示例#5
0
 public bool IsValidMove(int x, int y, int move) =>
 _goodMoves.Get(NavigationUtils.EncodePoint(x, y) * Moves + move);
示例#6
0
 public bool IsPointBottom(int x, int y) => _bottomPoints.Get(NavigationUtils.EncodePoint(x, y));
示例#7
0
 public bool IsSharpRight(int x, int y) => _sharpRightPoints.Get(NavigationUtils.EncodePoint(x, y));
示例#8
0
 public bool IsPointDrop(int x, int y) => _dropPoints.Get(NavigationUtils.EncodePoint(x, y));
示例#9
0
 public bool IsPointJump(int x, int y) => _jumpPoints.Get(NavigationUtils.EncodePoint(x, y));
示例#10
0
 public bool IsPointGround(int x, int y) => _groundPoints.Get(NavigationUtils.EncodePoint(x, y));
示例#11
0
 public bool IsPointBlocking(int x, int y) => _blockPoints.Get(NavigationUtils.EncodePoint(x, y));
示例#12
0
        public void CheckMoves()
        {
            for (int x = 0; x <= _width; ++x)
            {
                for (int y = 0; y <= _height; ++y)
                {
                    var point  = NavigationUtils.EncodePoint(x, y);
                    var offset = point * Moves;

                    if (!IsPointJump(point))
                    {
                        if (x > 0 && IsPointGround(point) && !IsPointBlocking(x - 1, y))
                        {
                            _goodMoves.Set(offset + 0, true);
                        }
                        if (x < _width && IsPointGround(point) && !IsPointBlocking(x + 1, y))
                        {
                            _goodMoves.Set(offset + 1, true);
                        }
                        if (x > 0 && y < _height && IsPointGround(point) && !IsSharpLeft(x - 1, y) && !IsPointBlocking(x - 1, y + 1))
                        {
                            _goodMoves.Set(offset + 2, true);
                        }
                        if (x < _width && y < _height && IsPointGround(point) && !IsSharpRight(x + 1, y) && !IsPointBlocking(x + 1, y + 1))
                        {
                            _goodMoves.Set(offset + 3, true);
                        }
                        if (y < _height && IsPointGround(point) && !IsPointBlocking(x, y + 1))
                        {
                            _goodMoves.Set(offset + 4, true);
                        }
                        if (x > 0 && y > 0 && (IsPointDrop(point) || !IsPointGround(point)) && !IsSharpRight(x, y - 1) && !IsPointBlocking(x - 1, y - 1))
                        {
                            _goodMoves.Set(offset + 5, true);
                        }
                        if (x < _width && y > 0 && (IsPointDrop(point) || !IsPointGround(point)) && !IsSharpLeft(x, y - 1) && !IsPointBlocking(x + 1, y - 1))
                        {
                            _goodMoves.Set(offset + 6, true);
                        }
                        if (y > 0 && (IsPointDrop(point) || !IsPointGround(point)) && !IsPointBlocking(x, y - 1))
                        {
                            _goodMoves.Set(offset + 7, true);
                        }
                        if (x > 0 && y < _height && !IsSharpLeft(x - 1, y) && !IsPointBlocking(x - 1, y + 1))
                        {
                            _goodMoves.Set(offset + 8, true);
                        }
                        if (x < _width && y < _height && !IsSharpRight(x + 1, y) && !IsPointBlocking(x + 1, y + 1))
                        {
                            _goodMoves.Set(offset + 9, true);
                        }
                        if (y < _height && !IsPointBlocking(x, y + 1))
                        {
                            _goodMoves.Set(offset + 10, true);
                        }
                        if (x > 0 && y + 1 < _height && !IsSharpLeft(x - 1, y) && !IsSharpLeft(x - 1, y + 1) && !IsPointBlocking(x - 1, y + 2))
                        {
                            _goodMoves.Set(offset + 14, true);
                        }
                        if (x < _width && y + 1 < _height && !IsSharpRight(x + 1, y) && !IsSharpRight(x + 1, y + 1) && !IsPointBlocking(x + 1, y + 2))
                        {
                            _goodMoves.Set(offset + 15, true);
                        }
                        if (y + 1 < _height && !IsPointBlocking(x, y + 2))
                        {
                            _goodMoves.Set(offset + 16, true);
                        }
                        if (IsPointBottom(x, y + 1))
                        {
                            _goodMoves.Set(offset + 17, true);
                        }
                    }
                    else
                    {
                        if (x > 0 && y + 1 < _height && !IsSharpLeft(x - 1, y) && !IsSharpLeft(x - 1, y + 1) && !IsPointBlocking(x - 1, y + 2))
                        {
                            _goodMoves.Set(offset + 11, true);
                        }
                        if (x < _width && y + 1 < _height && !IsSharpRight(x + 1, y) && !IsSharpRight(x + 1, y + 1) && !IsPointBlocking(x + 1, y + 2))
                        {
                            _goodMoves.Set(offset + 12, true);
                        }
                        if (y + 1 < _height && !IsPointBlocking(x, y + 2))
                        {
                            _goodMoves.Set(offset + 13, true);
                        }
                    }
                }
            }
        }