/// <summary>
        /// Checks whether the monster can move in the specified direction.
        /// If it can't, it will try other directions in turn until it finds a direction that is available.
        /// </summary>
        /// <param name="m">The monster that is moving</param>
        /// <param name="intendedDirection">The direction the monster hopes to move in</param>
        /// <param name="feasibleDirection">The direction the monster can move in, or Direction.None if it's unable to move</param>
        /// <returns>True if the monster can move in the intendedDirection, or False otherwise</returns>
        public static bool ConfirmDirectionToMoveIn(this Monster m, IDirectionChosen intendedDirection, out ConfirmedDirection feasibleDirection)
        {
            if (intendedDirection.Direction == Direction.None)
            {
                feasibleDirection = ConfirmedDirection.None;
                return(true);
            }

            if (intendedDirection is ConfirmedDirection confirmedDirection)
            {
                feasibleDirection = confirmedDirection;
                return(true);
            }

            if (m.CanMoveInDirection(intendedDirection.Direction))
            {
                feasibleDirection = intendedDirection.Confirm();
                return(true);
            }

            var directionToTry = new PossibleDirection(intendedDirection.Direction);

            for (int i = 0; i < 3; i++)
            {
                directionToTry = GetNextDirection(directionToTry);
                if (m.CanMoveInDirection(directionToTry.Direction))
                {
                    feasibleDirection = directionToTry.Confirm();
                    return(false);
                }
            }

            feasibleDirection = ConfirmedDirection.None;
            return(false);
        }
        private PossibleDirection GetIntendedDirection()
        {
            TilePos tp = this.Monster.TilePosition;

            PossibleDirection newDirection;
            TilePos           playerPosition = GlobalServices.GameState.Player.TilePosition;
            int yDiff = tp.Y - playerPosition.Y;    // +ve and the player is above, -ve and the player is below
            int xDiff = tp.X - playerPosition.X;    // +ve and the player is to the left, -ve and the player is to the right

            // if on the same row or column as the player then will be at risk of being shot
            if ((xDiff == 0 || yDiff == 0) && ShouldMakeMoveToAvoidTrouble())
            {
                newDirection = GetRandomPerpendicularDirection(this.CurrentDirection);
            }
            else if ((this.CurrentDirection == Direction.Left && xDiff <= -5) || (this.CurrentDirection == Direction.Right && xDiff >= 5))
            {
                newDirection = yDiff > 0 ? PossibleDirection.Up : PossibleDirection.Down;
            }
            else if ((this.CurrentDirection == Direction.Up && yDiff <= -5) || (this.CurrentDirection == Direction.Down && yDiff >= 5))
            {
                newDirection = xDiff > 0 ? PossibleDirection.Left : PossibleDirection.Right;
            }
            else if (GlobalServices.Randomness.Next(16) == 0)
            {
                newDirection = GetRandomPerpendicularDirection(this.CurrentDirection);
            }
            else
            {
                newDirection = new PossibleDirection(this.CurrentDirection);
            }

            return(newDirection);
        }
        private static PossibleDirection GetNextDirection(PossibleDirection d)
        {
            switch (d.Direction)
            {
            case Direction.Left:
                return(PossibleDirection.Right);

            case Direction.Right:
                return(PossibleDirection.Up);

            case Direction.Up:
                return(PossibleDirection.Down);

            case Direction.Down:
                return(PossibleDirection.Left);

            default:
                throw new InvalidOperationException();
            }
        }