/// <summary>
        /// Constructor.
        /// Creates and starts an AriadneController.
        /// </summary>
        /// <param name="windowHandleArg"></param>
        private ScreenSaverPreviewController(string windowHandleArg)
        {
            // Get the window in which we are supposed to paint.
            this.parentHwnd      = (IntPtr)UInt32.Parse(windowHandleArg);
            this.targetRectangle = Platform.GetClientRectangle(parentHwnd);
            //Log.WriteLine("targetRectangle = " + targetRectangle);

            // Create a MazePainter.
            this.targetGraphics = Graphics.FromHwnd(parentHwnd);
            this.painter        = new MazePainter(targetGraphics, targetRectangle, this as IMazePainterClient, true);

            // Create and display the first maze.
            this.OnNew(null, null);

            // Create an AriadneController.
            SolverController controller = new SolverController(null, painter, null);

            this.ariadneController       = new AriadneController(this, controller);
            ariadneController.RepeatMode = true;

            // Start the AriadneController.
            ariadneController.Start();

            // Start a supervisor timer.
            CreateSupervisorTimer();
        }
Esempio n. 2
0
        /// <summary>
        /// Coordinate shared resources of embedded objects with the master object.
        /// E.g. all solvers should share a common DeadEndChecker.
        /// </summary>
        /// <param name="masterCtrl"></param>
        private void CoordinateEmbeddedControllers(SolverController masterCtrl)
        {
            if (masterCtrl != this)
            {
                // Use the same progress bar.
                this.visitedProgressBar = masterCtrl.visitedProgressBar;
            }

            foreach (SolverController ctrl in embeddedControllers)
            {
                ctrl.CoordinateEmbeddedControllers(masterCtrl);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Returns the controller who should execute the next step.
        /// Finished and not ready controllers are skipped.
        /// Increments this.doStepTurn.
        /// </summary>
        /// <returns></returns>
        private SolverController ChooseDueController()
        {
            if (embeddedControllers.Count == 0)
            {
                return(this);
            }

            SolverController result = null;

            for (int n = 0; n <= embeddedControllers.Count; n++)
            {
                result     = (doStepTurn == 0 ? this : embeddedControllers[doStepTurn - 1]);
                doStepTurn = (doStepTurn + 1) % (embeddedControllers.Count + 1);

                if (result.IsActive)
                {
                    break;
                }
            }

            return(result);
        }
Esempio n. 4
0
        /// <summary>
        /// Advance a single step.
        /// The traveled steps are not rendered until FinishPath() is called.
        /// Returns the number of steps actually executed.
        /// </summary>
        /// <returns></returns>
        public int DoStep()
        {
            int result = 0;

            if (RunParallelSolvers)
            {
                // All controllers run in parallel.
                // Forward the message to the embedded controllers.
                foreach (EmbeddedSolverController item in embeddedControllers)
                {
                    if (item.IsActive)
                    {
                        result += item.DoStep();
                    }
                }
            }
            else
            {
                SolverController ctrl = ChooseDueController();

                if (ctrl != this)
                {
                    return(ctrl.DoStep());
                }
            }

            if (this.Maze.IsSolved)
            {
                return(result);
            }

            MazeSquare sq1, sq2;
            bool       forward;

            solver.Step(out sq1, out sq2, out forward);
            mazePainter.DrawStep(sq1, sq2, forward);
            ++result;

            // Increment the step counter.
            ++countSteps;

            // Increment forward and backward counters.
            if (forward)
            {
                ++countForward;
                if (visitedProgressBar != null)
                {
                    visitedProgressBar.PerformStep(); // next visited square
                }

                // Let all embedded controllers know how far we have advanced.
                foreach (EmbeddedSolverController ctrl in embeddedControllers)
                {
                    ctrl.HostStep(sq2);
                }
            }
            else
            {
                ++countBackward;
            }

            currentBackwardSquare = (forward ? null : sq2);

            if (this.Maze.IsSolved)
            {
                FinishPath();
                mazePainter.DrawSolvedPath(solutionPath);
                currentBackwardSquare = null;

                if (this.Maze.MazeId != MazeSquare.PrimaryMazeId)
                {
                    mazePainter.DrawRemainingSquares();
                }

#if DEBUG
                if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_LOG_SOLVER_STATISTICS))
                {
                    LogSolverStatistics();
                }
#endif
            }

            // Draw the background image inside the reserved areas.
            // If the background image was covered by a ContourImage, that border will be drawn smoothly instead of jagged.
            if (this.Maze.MazeId == MazeSquare.PrimaryMazeId && this.Maze.IsFinished)
            {
                mazePainter.DrawRemainingBackgroundSquares(MazeSquare.ReservedMazeId);
            }

            return(result);
        }
        /// <summary>
        /// Creates a ScreenSaverController instance,
        /// draws an initial maze
        /// and starts an AriadneController.
        /// </summary>
        /// <param name="windowHandleArg">The MazePainter will draw on this window.</param>
        /// <remarks>
        /// If this is not the primary screen, no cotroller is started,
        /// the application will terminate and the screen will stay blank.
        /// </remarks>
        public ScreenSaverController(string windowHandleArg)
        {
            #region Evaluate the given window's properties.
            var windowHandle    = (IntPtr)UInt32.Parse(windowHandleArg);
            var targetGraphics  = Graphics.FromHwnd(windowHandle);
            var targetRectangle = Platform.GetClientRectangle(windowHandle);
            //Log.WriteLine("targetRectangle = " + targetRectangle, true); // {X=0,Y=0,Width=1366,Height=768}
            #endregion

#if true
            #region Blank secondary screen(s).
            // ... because more than one of these mazes is just too distracting.  :-)
            if (!IsOnPrimaryScreen(windowHandle))
            {
                // We don't have to do anything, really.
                // xscreensaver has given us a blank (black) window and we may
                // terminate the application
                //Log.WriteLine("Goodbye on " + targetRectangle, true);
                //Application.Run();
                Application.Exit();
            }
            #endregion
#endif

            // Create an ImageLoader, now that it is clear that we will need it.
            Directory.ResultValidForSeconds = -1;
            var imageLoader = ImageLoader.GetScreenSaverImageLoader(Screen.PrimaryScreen.Bounds);

            #region Create a MazePainter.
            this.painter = new MazePainter(targetGraphics, targetRectangle, this as IMazePainterClient);
            #endregion

            #region Create a MazeUserControl.
            this.mazeUserControl             = new MazeUserControl(painter, targetRectangle.Size);
            this.mazeUserControl.ImageLoader = imageLoader;
            this.mazeUserControl.MazeForm    = this;
            #endregion

            #region Apply some registered options.
            if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_PAINT_ALL_WALLS) == false)
            {
                painter.RandomizeWallVisibility = true;
            }
            ContourImage.DisplayProcessedImage = RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_IMAGE_SUBTRACT_BACKGROUND);

            // Load background images.
            if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_BACKGROUND_IMAGES))
            {
                string imageFolder = RegisteredOptions.GetStringSetting(RegisteredOptions.OPT_BACKGROUND_IMAGE_FOLDER);
                if (imageFolder == "")
                {
                    imageFolder = RegisteredOptions.GetStringSetting(RegisteredOptions.OPT_IMAGE_FOLDER);
                }
                int percentage = ((RegisteredOptions.GetIntSetting(RegisteredOptions.OPT_IMAGE_NUMBER) > 0) ? 20 : 100);
                painter.CreateBackgroundImageLoader(imageFolder, percentage);
            }

            if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_SHOW_DETAILS_BOX))
            {
                this.infoPanelPainter = new InfoPanelPainter(painter);
            }
            #endregion

            // Create and display the first maze.
            this.OnNew(null, null);

            #region Create and start an AriadneController.
            SolverController controller = new SolverController(this, painter, null);
            this.ariadneController       = new AriadneController(this, controller);
            ariadneController.RepeatMode = true;
            ariadneController.Start();
            #endregion
        }
 public EmbeddedSolverController(SolverController hostController, SWA.Ariadne.Gui.Mazes.MazePainter mazePainter)
     : base(null, mazePainter, null)
 {
     this.hostController = hostController;
     this.startDelayRelativeDistance = 1.0;
 }