Пример #1
0
        /// <summary>
        /// Gets random based ball position on a free grid position on the specified window
        /// </summary>
        /// <param name="window">The window.</param>
        /// <returns>The ball position within the grid</returns>
        public static Point?GetRandomBallPosition(Window window)
        {
            if (window == null)
            {
                return(null);
            }

            var validBallPositions = new List <int[]>();

            for (var row = 0; row < GameConfiguration.GameGridSize; row++)
            {
                for (var column = 0; column < GameConfiguration.GameGridSize; column++)
                {
                    if (window.Holes.FirstOrDefault(hole => hole.X == row && hole.Y == column) == null)
                    {
                        validBallPositions.Add(new[] { row, column });
                    }
                }
            }

            if (!validBallPositions.Any())
            {
                return(null);
            }

            var random             = new Random(DateTime.Now.GetHashCode());
            var randomBallPosition = validBallPositions.ElementAt(random.Next(0, validBallPositions.Count));

            return(new Point(randomBallPosition[0], randomBallPosition[1]));
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MapSelectionWindow"/> class.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="mapWindow">The map window.</param>
        /// <param name="holeDiameter">The hole diameter.</param>
        public MapSelectionWindow(int x, int y, Window mapWindow, double holeDiameter)
        {
            this.X     = x;
            this.Y     = y;
            this.Holes = new ObservableCollection <MapSelectionWindowHole>();

            if (mapWindow != null)
            {
                this.IsClickable = true;
                this.Id          = mapWindow.Id;
                foreach (var hole in mapWindow.Holes)
                {
                    this.Holes.Add(hole.ToMapSelectionWindowHole(holeDiameter));
                }
            }
            else
            {
                this.IsChecked = false;
            }

            this.SetBackground();
        }
Пример #3
0
        /// <summary>
        /// Gets a random ball direction which does not end up in a hole within the first direction.
        /// If no valid direction is found within the defined calculation steps, the last calculated direction is returned.
        /// </summary>
        /// <param name="window">The window.</param>
        /// <param name="ballPosition">The ball position.</param>
        /// <param name="maxCalculationSteps">The maximum calculation steps.</param>
        /// <returns>
        /// The direction
        /// </returns>
        public static Vector GetRandomBallDirection(Window window, Point ballPosition, int maxCalculationSteps = 2000)
        {
            if (window == null)
            {
                throw new ArgumentNullException("window");
            }

            var directionsCalculated = 0;
            var random = new Random(DateTime.Now.GetHashCode());

            while (true)
            {
                var clickPosition = new Point(
                    random.Next(0, GameConfiguration.GameWindowWidth),
                    random.Next(0, GameConfiguration.GameWindowHeight));

                // Set the direction and negate it, because the ball has to move away from the queue
                var direction = new Vector(clickPosition.X, clickPosition.Y)
                                - new Vector(ballPosition.X, ballPosition.Y);
                direction.Negate();
                directionsCalculated++;

                // The direction is valid if there are no holes in the window
                if (!window.Holes.Any())
                {
                    return(direction);
                }

                // Create a fake point outside of the window in the ball direction
                var intersectionTestPoint = ballPosition + (direction * 10);
                var intersectionFound     = false;

                // Check for an intersection between the ball and a hole in the set direction
                foreach (var hole in window.Holes)
                {
                    Point?firstIntersection;
                    Point?secondIntersection;

                    var intersection = CalculationHelpers.CalculateLineSphereIntersection(
                        hole.CenterPosition,
                        hole.Radius,
                        ballPosition,
                        intersectionTestPoint,
                        out firstIntersection,
                        out secondIntersection);

                    // Cancel the check because we have an intersection
                    if (intersection > 0)
                    {
                        Tracer.Debug(string.Format("GameHelpers :: GetRandomBallDirection :: Found an intersection between click position {0}, ball position {1}, direction {2} and hole position {3}", clickPosition, ballPosition, direction, hole.CenterPosition));
                        intersectionFound = true;
                        break;
                    }
                }

                // Return the current direction if there was no valid direction within the defined tries
                if (directionsCalculated == maxCalculationSteps)
                {
                    Tracer.Debug(string.Format("GameHelpers :: GetRandomBallDirection :: Returning direction {0} because the amount of tries is reached", direction));
                    return(direction);
                }

                // If we have a intersection, we need another try to find a valid direction
                if (intersectionFound)
                {
                    continue;
                }

                Tracer.Debug(string.Format("GameHelpers :: GetRandomBallDirection :: Returning direction {0} after {1} tries", direction, directionsCalculated));
                return(direction);
            }
        }