public Offset Execute(GhostMovementContext context)
            {
                const int tilesAhead      = 4;
                var       pacManDirection = context.Map.PacMan.State.Direction;
                var       shift           = pacManDirection.ToOffset().Extend(tilesAhead);
                var       ghostTarget     = context.Map.PacMan.Position.Shift(shift);

                return(ghostTarget);
            }
Exemple #2
0
            public Offset Execute(GhostMovementContext context)
            {
                const int pokeyConfortableDistance = 8 * Tile.SIZE;
                var       pacManPosition           = context.Map.PacMan.Position;
                var       ghostPosition            = context.Ghost.Position;
                var       distance    = ghostPosition.ManhattanDistance(pacManPosition);
                var       ghostTarget = distance > pokeyConfortableDistance ? pacManPosition : _patrollingTarget;

                return(ghostTarget);
            }
            public Offset Execute(GhostMovementContext context)
            {
                const int timesAhead  = 2;
                var       shadow      = context.Map.Ghosts.OfType <SpeedyGhost>().Single();
                var       shift       = shadow.State.Target.Subtract(shadow.Position);
                var       extended    = shift.Extend(timesAhead);
                var       ghostTarget = shadow.Position.Shift(extended);

                return(ghostTarget);
            }
            public Offset Execute(GhostMovementContext context)
            {
                var currentVertex  = context.Ghost.Position.ToTile();
                var currentTile    = context.Map[currentVertex.Y, currentVertex.X];
                var ghostPosition  = context.Ghost.Position;
                var ghostDirection = context.Ghost.State.Direction;

                var neighbors = context.Map.GetNeighbors(currentVertex)
                                .Where(neighbor => !neighbor.IsWall)
                                .ToList();

                var allowedDirections = neighbors
                                        .Select(neighbor => ghostPosition.ToDirection(neighbor.Position))
                                        .Where(direction => direction != ghostDirection.ToOpposite())
                                        .Where(direction => direction != currentTile.Restriction)
                                        .ToList();

                int randomIndex   = _randomGenerator.Next(allowedDirections.Count);
                var nextDirection = allowedDirections.Any() ? allowedDirections[randomIndex] : ghostDirection;
                var ghostTarget   = ghostPosition.Shift(nextDirection.ToOffset());

                return(ghostTarget);
            }
        public void Move(SelfMovementContext context)
        {
            // get next target based on ghost mode and corresponding movement strategy
            var currentVertex = Position.ToTile();
            var currentTile   = context.Map[currentVertex.Y, currentVertex.X];

            // check if ghost needs to change the direction
            if (Position.Equals(currentTile.Position))
            {
                CheckTimeoutBeforeBeingComforted(DateTime.Now);
                CheckTimeoutBeforeChangingMode(DateTime.Now);

                var movementContext = new GhostMovementContext(context.EventSink, context.Map, this);
                var target          = _currentMode.Execute(movementContext);
                var ghostPosition   = Position;
                var ghostDirection  = State.Direction;

                var graph     = context.Map;
                var neighbors = graph.GetNeighbors(currentVertex)
                                .Where(neighbor => !neighbor.IsWall)
                                .ToList();

                var allowedDirections = neighbors
                                        .Select(neighbor => ghostPosition.ToDirection(neighbor.Position))
                                        .Where(direction => direction != ghostDirection.ToOpposite())
                                        .Where(direction => direction != currentTile.Restriction)
                                        .ToList();

                if (allowedDirections.Count == 1)
                {
                    // there is only one way to go/turn - go/turn that way
                    State = State with {
                        Direction = allowedDirections.Single()
                    };
                }
                else if (allowedDirections.Count == 0)
                {
                    // there were no ways to go/turn, choosing the direction closest to target
                    var targetDirection = neighbors
                                          .Select(neighbor => neighbor.Position)
                                          .OrderBy(neighbor => neighbor.EuclideanDistance(target))
                                          .First();

                    State = State with {
                        Direction = ghostPosition.ToDirection(targetDirection)
                    };
                }
                else if (neighbors.Count >= 3)
                {
                    // current tile is the tile in which we need to decide where to go/turn
                    // TODO: check the direction accroding to the priorities below
                    // Direction.Up, Direction.Left, Direction.Down
                    var targetDirection = allowedDirections
                                          .Select(direction => Position.Shift(direction.ToOffset()))
                                          .OrderBy(neighbor => neighbor.EuclideanDistance(target))
                                          .First();

                    State = State with {
                        Direction = ghostPosition.ToDirection(targetDirection)
                    };
                }
            }

            var nextPosition = Position.Shift(State.Direction.ToOffset());
            var afterVertex  = nextPosition.ToTile();
            var afterTile    = context.Map[afterVertex.Y, afterVertex.X];

            Position = afterTile.IsWall ? Position : nextPosition;
        }
 public Offset Execute(GhostMovementContext context) => _respawnTarget;
 public Offset Execute(GhostMovementContext context) => _target;
 public Offset Execute(GhostMovementContext context) => context.Map.PacMan.Position;