コード例 #1
0
        private static void recurSolverStarter(BlockPuzzle blockPuzzle)
        {
            List <Point> startingPoints = new List <Point>()
            {
                new Point(0, 0, 0),
                new Point(0, 1, 0),
                new Point(1, 0, 0),
                new Point(1, 1, 0),
                //new Point(0,0,1),
                //new Point(0,1,1),
                new Point(1, 0, 1),
                new Point(1, 1, 1),
            };

            foreach (Point startingPoint in startingPoints)
            {
                BlockLine startingBlock = new BlockLine(BlockOrder[0] + 1, BlockLine.Orientation.Back);
                startingBlock.startPoint = startingPoint;
                startingBlock.endPoint   = new Point(startingPoint.xPos, startingPoint.yPos + 2, startingPoint.zPos);

                blockPuzzle.AddBlockLineDirectly(startingBlock);

                StackSolver(blockPuzzle, BlockLine.Orientation.Left);
                StackSolver(blockPuzzle, BlockLine.Orientation.Right);
                StackSolver(blockPuzzle, BlockLine.Orientation.Up);
                StackSolver(blockPuzzle, BlockLine.Orientation.Down);
                StackSolver(blockPuzzle, BlockLine.Orientation.Front);
                StackSolver(blockPuzzle, BlockLine.Orientation.Back);

                blockPuzzle.RemoveLastBlockLine();
                Console.WriteLine("Just finished up the pass for starting point {0}, {1}, {2} : {3}",
                                  startingPoint.xPos, startingPoint.yPos, startingPoint.zPos, System.DateTime.Now.ToLongTimeString());
            }
        }
コード例 #2
0
        static void Main(string[] args)
        {
            System.Console.WriteLine("Starting at {0}.", System.DateTime.Now.ToLongTimeString());
            BlockPuzzle FourByFour = new BlockPuzzle(BlockOrder);

            recurSolverStarter(FourByFour);
            System.Console.WriteLine("Ending at {0}.", System.DateTime.Now.ToLongTimeString());
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: jhnieman/4x4x4
        public static void Main(string[] args)
        {
            // Start time
            System.Console.WriteLine("Program starting at {0}.", System.DateTime.Now.ToLongTimeString());

            // Set up the puzzle
            BlockPuzzle FourByFourbyFour = new BlockPuzzle(BlockOrder);

            // Solve it!
            BlockPuzzle.Solve(FourByFourbyFour);

            // End time
            System.Console.WriteLine("Program ending at {0}.", System.DateTime.Now.ToLongTimeString());
            System.Console.WriteLine("{0} total positions considered!", FourByFourbyFour.PositionCount);
            System.Console.ReadLine();
        }
コード例 #4
0
        private static void StackSolver(BlockPuzzle blockPuzzle, BlockLine.Orientation nextOrientation)
        {
            if (!blockPuzzle.isFinished)
            {
                if (blockPuzzle.AddBlockLine(nextOrientation))
                {
                    StackSolver(blockPuzzle, BlockLine.Orientation.Left);
                    StackSolver(blockPuzzle, BlockLine.Orientation.Right);
                    StackSolver(blockPuzzle, BlockLine.Orientation.Up);
                    StackSolver(blockPuzzle, BlockLine.Orientation.Down);
                    StackSolver(blockPuzzle, BlockLine.Orientation.Front);
                    StackSolver(blockPuzzle, BlockLine.Orientation.Back);

                    blockPuzzle.RemoveLastBlockLine();
                }
            }
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: jhnieman/4x4x4
        public static void Main(string[] args)
        {
            // Start the timer
            Stopwatch stopwatch = Stopwatch.StartNew();

            // Go!
            Console.WriteLine("Program starting at {0}.", DateTime.Now.ToLongTimeString());

            // Solve it!
            BlockPuzzle.Solve(BlockOrder);

            // End time
            stopwatch.Stop();
            Console.WriteLine("Program ending at {0}.", DateTime.Now.ToLongTimeString());
            Console.WriteLine("Total program time was {0:hh\\:mm\\:ss}", stopwatch.Elapsed);

            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();
        }
コード例 #6
0
        // This part does the work and is called link by link
        private static void PuzzleSolverInnerLoop(BlockPuzzle blockPuzzle, BlockLine.BlockLineOrientation nextOrientation)
        {
            // If you're not done, keep working!
            if (!blockPuzzle.IsFinished)
            {
                // Try to add the requested orientation
                if (blockPuzzle.AddBlockLine(nextOrientation))
                {
                    // If adding the requested block succeeds, try to add another block in each direction!
                    PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Left);
                    PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Right);
                    PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Up);
                    PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Down);
                    PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Front);
                    PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Back);

                    // Once all directions have been tried, unroll the block you just placed from the master list
                    blockPuzzle.RemovePreviousBlockLine();
                }
            }
        }
コード例 #7
0
        // Start off by enumerating all the starting positions and adding them to the list
        private static void PuzzleSolver(BlockPuzzle blockPuzzle)
        {
            // These are the unique starting points, based on the first block size
            List <Point> startingPoints = new List <Point>()
            {
                new Point(0, 0, 0),
                new Point(0, 1, 0),
                new Point(1, 0, 0),
                new Point(1, 1, 0),
                new Point(1, 0, 1),
                new Point(1, 1, 1),
            };

            // for each starting point, kick off the inner solver
            foreach (Point startingPoint in startingPoints)
            {
                // Start by going any direction, back chosen at random
                BlockLine startingBlock = new BlockLine(BlockOrder[0] + 1, BlockLine.BlockLineOrientation.Back);
                startingBlock.StartPoint = startingPoint;
                startingBlock.EndPoint   = new Point(startingPoint.XPos, startingPoint.YPos + BlockOrder[0], startingPoint.ZPos);

                // Add the first block to the stack
                blockPuzzle.AddBlockLineDirectly(startingBlock);

                // Throw each next direction onto the depth-first queue
                PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Left);
                PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Right);
                PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Up);
                PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Down);
                PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Front);
                PuzzleSolverInnerLoop(blockPuzzle, BlockLine.BlockLineOrientation.Back);

                // Remove the first block to trigger the end of the routine
                blockPuzzle.RemovePreviousBlockLine();
                Console.WriteLine("Just finished up the pass for starting point {0}, {1}, {2} : {3}",
                                  startingPoint.XPos, startingPoint.YPos, startingPoint.ZPos, System.DateTime.Now.ToLongTimeString());
            }
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: jhnieman/4x4x4
        private BlockPuzzle Puzzle; // keep a ref to the master puzzle

        public BlockLine(int numBlocks, int blockIndex, BlockPuzzle puzzle)
        {
            this.NumBlocks  = numBlocks;
            this.BlockIndex = blockIndex;
            this.Puzzle     = puzzle;
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: jhnieman/4x4x4
        // Start off by enumerating all the starting positions and adding them to the list
        public static void Solve(BlockPuzzle blockPuzzle)
        {
            bool blockAdded    = false;
            bool solutionFound = false;
            uint solutionCount = 0;

            // These are the unique starting points
            // all other starting points are equivalent by symmetry in a 4x4x4 cube
            // TODO: Build up a general model for unique starting points for cube size n
            // NOTE: This will spit out some solutions that are mirrors of each other. Although they're still "unique",
            //       future work would be to prune out the mirrors.
            //       (Ex: "start in the corner (0,0,0) and move left" is rotationally symmetric to "start in the corner (0,0,0) and move right")
            //       (Ex: "start at 0,1,0, move up, then left" is vertically symmetric to "start at 0,1,0, move up, then right"
            List <Point> startingPoints = new List <Point>()
            {
                new Point(0, 0, 0),
                new Point(0, 1, 0),
                new Point(1, 1, 0),
                new Point(1, 1, 1),
            };

            // for each starting point, kick off the inner solver
            foreach (Point startingPoint in startingPoints)
            {
                // Start time
                System.Console.WriteLine("Beginning pass with start point {0}, {1}, {2} at {3}. ====================",
                                         startingPoint.XPos, startingPoint.YPos, startingPoint.ZPos, System.DateTime.Now.ToLongTimeString());

                // Update the starting point for the puzzle and the first block line
                blockPuzzle.StartingPoint = startingPoint;
                blockPuzzle.BlockLineList[0].StartPoint = startingPoint;

                // Since that's the starting point and we *know* that a block will be there, set that block in the grid
                blockPuzzle.TheGrid[blockPuzzle.StartingPoint.XPos, blockPuzzle.StartingPoint.YPos, blockPuzzle.StartingPoint.ZPos] = true;

                // Reset the starting link and orientation
                blockPuzzle.BlockLineIndex = 0;
                blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex].ZeroOrientation(); // no prior orientation

                // This is the main loop!
                while (blockPuzzle.BlockLineIndex >= 0)
                {
                    // Try the next link and orientation. Does it fit? If so, add it in!
                    blockAdded = blockPuzzle.AddBlockLine(blockPuzzle.BlockLineIndex);

                    if (blockAdded)
                    {
                        // increment the link index
                        blockPuzzle.BlockLineIndex++;

                        // Are we done? Is that the last block? IS THAT A SOLUTION???
                        solutionFound = blockPuzzle.BlockLineIndex >= blockPuzzle.BlockLineList.Count;
                        if (solutionFound)
                        {
                            Console.WriteLine("Solution #" + (solutionCount++ + 1) + " ================================================================"); // Add one to start with "Solution 1"
                            blockPuzzle.PrintPuzzle();
                            // special last block line case, take the index back down to the last block
                            blockPuzzle.BlockLineIndex--;
                        }
                        // if not, reset the new link's start pos and orientation in light of the last link's orientation
                        else
                        {
                            blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex].StartPoint          = blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex - 1].EndPoint;
                            blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex].LastLineOrientation = blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex - 1].Orientation;
                            blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex].ZeroOrientation();
                        }
                    }

                    // if the blockline couldn't be added OR we found a solution, rotate the block line in question in prep for next attempt
                    if (!blockAdded || solutionFound)
                    {
                        // rotate the link
                        if (blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex].RotateBlockLine())
                        {
                            // exit this loop, go back up to the top of the loop, and try again!
                        }
                        // if that was the last rotation, there are no more options for this link. back up one link and rotate
                        else
                        {
                            do
                            {
                                // back up one
                                --(blockPuzzle.BlockLineIndex);
                            }while ((blockPuzzle.BlockLineIndex >= 0) &&                                         // as long as you're not past the beginning
                                    (!blockPuzzle.BlockLineList[blockPuzzle.BlockLineIndex].RotateBlockLine())); // rotate and check, until there are no more rotates
                        }
                    }
                }

                // Clean up the starting point that we added in the beginning
                blockPuzzle.TheGrid[blockPuzzle.StartingPoint.XPos, blockPuzzle.StartingPoint.YPos, blockPuzzle.StartingPoint.ZPos] = false;

                // End time
                System.Console.WriteLine("Ending pass with start point {0}, {1}, {2} at {3}. =======================",
                                         startingPoint.XPos, startingPoint.YPos, startingPoint.ZPos, System.DateTime.Now.ToLongTimeString());
            }
        }