예제 #1
0
 public Path(TilePos initialPosition, TilePos initialDirection)
 {
     Cost  = 0;
     Steps = new List <Step> {
         new Step(initialPosition, initialDirection, false)
     };
 }
예제 #2
0
        private void AddNewPathToContinue(TilePos pos, TilePos moveDirection, Path path)
        {
            var rotationDifference = path.GetRotationDifference(moveDirection);
            var stepCost           = 1 + rotationDifference;

            _pathsToContinue.Add(path.Branch(stepCost, pos, moveDirection));
        }
예제 #3
0
        public static Entity PushableItemAt(this Pool pool, TilePos position, TilePos moveDirection)
        {
            var newPosition             = position + moveDirection;
            var entitiesAtPosition      = pool.GetEntitiesAt(position, x => x.isBox).ToList();
            var openSpaceAtNextPosition = pool.OpenTileAt(newPosition);
            var stillInsidePuzzle       = pool.IsStillInsideSamePuzzle(position, newPosition);

            return(openSpaceAtNextPosition && stillInsidePuzzle?entitiesAtPosition.SingleOrDefault() : null);
        }
예제 #4
0
        public static bool KnockObjectsInFront(this Pool pool, TilePos position, TilePos forwardDirection, bool immediate, float knockWait)
        {
            var knockable = pool.GetEntityAt(position + forwardDirection, x => x.isBlockingTile);

            if (knockable != null)
            {
                knockable.ReplaceKnocked(forwardDirection, immediate, knockWait);
                return(true);
            }
            return(false);
        }
예제 #5
0
        public static bool IsStillInsideSamePuzzle(this Pool pool, TilePos currentPosition, TilePos nextPosition)
        {
            var currentPuzzle = pool.GetEntityAt(currentPosition, x => x.isPuzzleArea && x.hasBossConnection);
            var nextPuzzle    = pool.GetEntityAt(nextPosition, x => x.isPuzzleArea && x.hasBossConnection);

            if (currentPuzzle != null && nextPuzzle != null)
            {
                return(nextPuzzle.bossConnection.BossId == currentPuzzle.bossConnection.BossId);
            }

            return(currentPuzzle == nextPuzzle);
        }
예제 #6
0
        public static List <Entity> GetEntitiesAt(this Pool pool, TilePos position, Func <Entity, bool> entityMatcher = null)
        {
            if (!pool.objectPositionCache.Cache.ContainsKey(position))
            {
                return(new List <Entity>());
            }

            return(pool.objectPositionCache
                   .Cache[position]
                   .Where(x => x.hasGameObject && !x.isDestroyed && (entityMatcher == null || entityMatcher(x)))
                   .ToList());
        }
예제 #7
0
        public static Entity GetEntityAt(this Pool pool, TilePos position, Func <Entity, bool> entityMatcher = null)
        {
            var entitiesAtPosition = pool
                                     .GetEntitiesAt(position, entityMatcher)
                                     .ToList();

            if (entitiesAtPosition.Count() > 1)
            {
                throw new MoreThanOneMatchException(entitiesAtPosition);
            }

            return(entitiesAtPosition.SingleOrDefault());
        }
예제 #8
0
        public Path CalculateMoveToTarget(
            TilePos initialPosition,
            TilePos initialDirection,
            TilePos targetPosition)
        {
            _targetPosition = targetPosition;
            var victoryPath = new Path(initialPosition, initialDirection);

            SetInitialState(initialPosition, initialDirection);
            while (_pathsToContinue.Count > 0)
            {
                var path = PopPathToContinue();
                var pos  = path.GetLastPosition();

                if (pos == _targetPosition)
                {
                    victoryPath = SelectLateTurnPathWithSameCost(path);
                    break;
                }

                foreach (var moveDirection in LocalDirections.GetAll())
                {
                    var newPos = pos + moveDirection;
                    if (_walkValidator.CanMoveTo(newPos) && !_visited.Contains(newPos))
                    {
                        AddNewPathToContinue(newPos, moveDirection, path);
                    }
                }

                _visited.Add(pos);
                OrderByCost();
            }

            victoryPath.Steps.RemoveAt(0);
            return(victoryPath);
        }
예제 #9
0
 public bool Equals(TilePos other)
 {
     return(X == other.X && Z == other.Z);
 }
예제 #10
0
 public int RotationDifference(TilePos otherDirection)
 {
     return(Mathf.Max(Mathf.Abs(X - otherDirection.X), Mathf.Abs(Z - otherDirection.Z)));
 }
예제 #11
0
 public bool CanMoveTo(TilePos position)
 {
     return(_pool.OpenTileAt(position));
 }
예제 #12
0
 private Entity CreateEntity(TilePos position)
 {
     return(_pool.CreateEntity().AddPosition(position).AddRotation(0));
 }
예제 #13
0
 public Path Branch(int cost, TilePos position, TilePos direction)
 {
     return(new Path(this, cost, position, direction));
 }
예제 #14
0
        public int GetRotationDifference(TilePos direction)
        {
            var lastDirection = Steps[Steps.Count - 1].Direction;

            return(lastDirection.RotationDifference(direction));
        }
예제 #15
0
 public static void DoForAllAtPosition(this Pool pool, TilePos position, Action <Entity> entityAction)
 {
     pool.objectPositionCache.Cache[position].ForEach(entityAction);
 }
예제 #16
0
 protected Path(Path path, int cost, TilePos position, TilePos direction)
 {
     Cost  = path.Cost + cost;
     Steps = path.Steps.Concat(new[] { new Step(position, direction, path.GetRotationDifference(direction) > 0) }).ToList();
 }
예제 #17
0
 public Step(TilePos position, TilePos direction, bool turned)
 {
     Position  = position;
     Direction = direction;
     Turned    = turned;
 }
예제 #18
0
 public static Entity GetAreaAt(this Pool pool, TilePos position)
 {
     return(pool.GetEntityAt(position, x => x.gameObject.Type == ObjectType.Area));
 }
예제 #19
0
 private void SetInitialState(TilePos initialPosition, TilePos initialDirection)
 {
     _visited         = new HashSet <TilePos>();
     _pathsToContinue = new List <Path>();
     _pathsToContinue.Add(new Path(initialPosition, initialDirection));
 }
예제 #20
0
 public static int ToRotation(TilePos direction)
 {
     return(DirectionRotation.Single(x => x.Item1 == direction).Item2);
 }
예제 #21
0
        public static bool OpenTileAt(this Pool pool, TilePos position)
        {
            var entitiesAtPosition = pool.GetEntitiesAt(position).ToList();

            return(entitiesAtPosition.Any(x => x.gameObject.Type == ObjectType.Tile) && entitiesAtPosition.All(x => !x.isBlockingTile));
        }