示例#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
文件: Program.cs 项目: jhnieman/4x4x4
        // Is there space to add the blockline (input)? If so, return true, false if not
        public bool SpaceCheck(BlockLine blockLine)
        {
            bool  open       = true;
            Point checkPoint = blockLine.StartPoint;

            // Get a delta point to step in the right direction
            Point unitStep = Point.DeltaPoints[blockLine.Orientation];

            // Skip the starting point, because it's shared by the endpoint of the last block line, meaning that it's obviously not empty
            // start the for loop at 1
            checkPoint = checkPoint + unitStep;

            // Check if it's open
            for (int i = 1; i < blockLine.NumBlocks; i++)
            {
                if (this.TheGrid[checkPoint.XPos, checkPoint.YPos, checkPoint.ZPos])
                {
                    open = false;
                    break;
                }
                checkPoint = checkPoint + unitStep;
            }

            return(open);
        }
示例#3
0
        public bool AddBlockLineDirectly(BlockLine addedBlock)
        {
            bool added = false;

            if (this.BoundsCheck(addedBlock))
            {
                if (this.SpaceCheck(addedBlock, Point.deltaPoints[addedBlock.orientation]))
                {
                    this.listOfBlocks.Add(addedBlock);
                    this.endingPoint = addedBlock.endPoint;
                    this.blockLineIndex++;

                    added = true;

                    //Console.WriteLine("Just added block {0} with orientation {1}.", this.blockLineIndex, addedBlock.orientation);

                    if (this.blockLineOrder[blockLineIndex - 1] == 0)
                    {
                        this.isFinished = true;
                    }
                }
            }

            return(added);
        }
示例#4
0
        // Add a block line by taking in a BlockLine, not the next orientation
        // Used primarily for the first block in the puzzle.
        // Returns true if the line is added, false otherwise
        public bool AddBlockLineDirectly(BlockLine addedBlock)
        {
            // For fun, increment the number of total positions considered
            this.PositionCount++;

            bool added = false;

            if (this.BoundsCheck(addedBlock))
            {
                if (this.SpaceCheckAndReserve(addedBlock, Point.DeltaPoints[addedBlock.Orientation]))
                {
                    this.ListOfBlocks.Add(addedBlock);
                    this.EndingPoint = addedBlock.EndPoint;
                    this.BlockLineIndex++;

                    added = true;

                    // Just in case, check if this is the last block
                    if (this.BlockLineOrder[BlockLineIndex - 1] == 0)
                    {
                        this.IsFinished = true;
                    }
                }
            }

            return(added);
        }
示例#5
0
        public bool SpaceCheck(BlockLine blockLine, Point deltaPoint)
        {
            bool open = true;
            int  xVal = blockLine.startPoint.xPos;
            int  yVal = blockLine.startPoint.yPos;
            int  zVal = blockLine.startPoint.zPos;

            // Check if it's open
            for (int i = 0; i < blockLine.numBlocks; i++)
            {
                if (this.theGrid[xVal, yVal, zVal])
                {
                    open = false;
                    break;
                }
                xVal = xVal + deltaPoint.xPos;
                yVal = yVal + deltaPoint.yPos;
                zVal = zVal + deltaPoint.zPos;
            }

            // If so, write the ones going back through the blocks
            if (open)
            {
                xVal = blockLine.startPoint.xPos;
                yVal = blockLine.startPoint.yPos;
                zVal = blockLine.startPoint.zPos;

                for (int i = 0; i < blockLine.numBlocks; i++)
                {
                    this.theGrid[xVal, yVal, zVal] = true;

                    xVal = xVal + deltaPoint.xPos;
                    yVal = yVal + deltaPoint.yPos;
                    zVal = zVal + deltaPoint.zPos;
                }
            }

            return(open);
        }
示例#6
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());
            }
        }
示例#7
0
 public bool BoundsCheck(BlockLine block)
 {
     return((block.endPoint.xPos > -1 && block.endPoint.xPos < 4) &&
            (block.endPoint.yPos > -1 && block.endPoint.yPos < 4) &&
            (block.endPoint.zPos > -1 && block.endPoint.zPos < 4));
 }
示例#8
0
        public bool AddBlockLine(BlockLine.Orientation orientation)
        {
            BlockLine.Orientation lastBlockOrientation;
            bool additionSuccess = false;

            int       numBlocks  = this.blockLineOrder[this.blockLineIndex];
            BlockLine addedBlock = new BlockLine(numBlocks, orientation);

            if (this.listOfBlocks.Count == 0)
            {
                // This is the first block, so we need to add one block
                addedBlock.numBlocks++;
                addedBlock.startPoint = new Point(0, 0, 0);
                addedBlock.endPoint   = new Point(0, 0, addedBlock.numBlocks - 1);
                this.SpaceCheck(addedBlock, new Point(0, 0, 1));
                additionSuccess = true;
            }
            else
            {
                lastBlockOrientation = listOfBlocks[listOfBlocks.Count - 1].orientation;

                switch (orientation)
                {
                case BlockLine.Orientation.Back:
                    if (lastBlockOrientation != BlockLine.Orientation.Back && lastBlockOrientation != BlockLine.Orientation.Front)
                    {
                        addedBlock.startPoint = new Point(this.endingPoint.xPos, this.endingPoint.yPos + 1, this.endingPoint.zPos);
                        addedBlock.endPoint   = new Point(this.endingPoint.xPos, this.endingPoint.yPos + numBlocks, this.endingPoint.zPos);
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheck(addedBlock, new Point(0, 1, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.Orientation.Front:
                    if (lastBlockOrientation != BlockLine.Orientation.Back && lastBlockOrientation != BlockLine.Orientation.Front)
                    {
                        addedBlock.startPoint = new Point(this.endingPoint.xPos, this.endingPoint.yPos - 1, this.endingPoint.zPos);
                        addedBlock.endPoint   = new Point(this.endingPoint.xPos, this.endingPoint.yPos - numBlocks, this.endingPoint.zPos);
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheck(addedBlock, new Point(0, -1, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.Orientation.Left:
                    if (lastBlockOrientation != BlockLine.Orientation.Left && lastBlockOrientation != BlockLine.Orientation.Right)
                    {
                        addedBlock.startPoint = new Point(this.endingPoint.xPos - 1, this.endingPoint.yPos, this.endingPoint.zPos);
                        addedBlock.endPoint   = new Point(this.endingPoint.xPos - numBlocks, this.endingPoint.yPos, this.endingPoint.zPos);
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheck(addedBlock, new Point(-1, 0, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.Orientation.Right:
                    if (lastBlockOrientation != BlockLine.Orientation.Left && lastBlockOrientation != BlockLine.Orientation.Right)
                    {
                        addedBlock.startPoint = new Point(this.endingPoint.xPos + 1, this.endingPoint.yPos, this.endingPoint.zPos);
                        addedBlock.endPoint   = new Point(this.endingPoint.xPos + numBlocks, this.endingPoint.yPos, this.endingPoint.zPos);
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheck(addedBlock, new Point(1, 0, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.Orientation.Up:
                    if (lastBlockOrientation != BlockLine.Orientation.Up && lastBlockOrientation != BlockLine.Orientation.Down)
                    {
                        addedBlock.startPoint = new Point(this.endingPoint.xPos, this.endingPoint.yPos, this.endingPoint.zPos + 1);
                        addedBlock.endPoint   = new Point(this.endingPoint.xPos, this.endingPoint.yPos, this.endingPoint.zPos + numBlocks);
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheck(addedBlock, new Point(0, 0, 1)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.Orientation.Down:
                    if (lastBlockOrientation != BlockLine.Orientation.Up && lastBlockOrientation != BlockLine.Orientation.Down)
                    {
                        addedBlock.startPoint = new Point(this.endingPoint.xPos, this.endingPoint.yPos, this.endingPoint.zPos - 1);
                        addedBlock.endPoint   = new Point(this.endingPoint.xPos, this.endingPoint.yPos, this.endingPoint.zPos - numBlocks);
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheck(addedBlock, new Point(0, 0, -1)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;
                }
            }

            if (additionSuccess)
            {
                this.listOfBlocks.Add(addedBlock);
                this.endingPoint = addedBlock.endPoint;

                //Console.WriteLine("Just added block {0} with orientation {1}.", this.blockLineIndex, addedBlock.orientation);

                this.blockLineIndex++;

                if (this.blockLineOrder[this.blockLineIndex] == 0)
                {
                    this.isFinished = true;
                    Console.WriteLine("==Solution==================================================================================");
                    this.PrintPuzzle();
                }
            }

            return(additionSuccess);
        }
示例#9
0
文件: Program.cs 项目: jhnieman/4x4x4
 // Checks to make sure that all the blocks are in bounds (within the 4x4 cube dimensions)
 public bool BoundsCheck(BlockLine block)
 {
     return((block.EndPoint.XPos > -1 && block.EndPoint.XPos < 4) &&
            (block.EndPoint.YPos > -1 && block.EndPoint.YPos < 4) &&
            (block.EndPoint.ZPos > -1 && block.EndPoint.ZPos < 4));
 }
示例#10
0
        // Add the next blockline in the direction provided
        public bool AddBlockLine(BlockLine.BlockLineOrientation orientation)
        {
            // For fun, increment the number of total positions considered
            this.PositionCount++;

            BlockLine.BlockLineOrientation lastBlockOrientation;
            bool additionSuccess = false;

            int       numBlocks  = this.BlockLineOrder[this.BlockLineIndex];
            BlockLine addedBlock = new BlockLine(numBlocks, orientation);

            if (this.ListOfBlocks.Count == 0)
            {
                // This is the first block, so we need to add one block
                addedBlock.NumBlocks++;
                addedBlock.StartPoint = new Point(0, 0, 0);
                addedBlock.EndPoint   = new Point(0, 0, addedBlock.NumBlocks - 1);
                this.SpaceCheckAndReserve(addedBlock, new Point(0, 0, 1));
                additionSuccess = true;
            }
            else
            {
                // Find out what direction the last block line went in order to determine where the next one can go
                // Block lines are always at 90 degress to the last line
                lastBlockOrientation = ListOfBlocks[ListOfBlocks.Count - 1].Orientation;
                switch (orientation)
                {
                case BlockLine.BlockLineOrientation.Back:
                    if (lastBlockOrientation != BlockLine.BlockLineOrientation.Back && lastBlockOrientation != BlockLine.BlockLineOrientation.Front)
                    {
                        addedBlock.StartPoint = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos + 1, this.EndingPoint.ZPos);
                        addedBlock.EndPoint   = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos + numBlocks, this.EndingPoint.ZPos);

                        // Will it fit in the 4x4 grid? And is there space?
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheckAndReserve(addedBlock, new Point(0, 1, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.BlockLineOrientation.Front:
                    if (lastBlockOrientation != BlockLine.BlockLineOrientation.Back && lastBlockOrientation != BlockLine.BlockLineOrientation.Front)
                    {
                        addedBlock.StartPoint = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos - 1, this.EndingPoint.ZPos);
                        addedBlock.EndPoint   = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos - numBlocks, this.EndingPoint.ZPos);

                        // Will it fit in the 4x4 grid? And is there space?
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheckAndReserve(addedBlock, new Point(0, -1, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.BlockLineOrientation.Left:
                    if (lastBlockOrientation != BlockLine.BlockLineOrientation.Left && lastBlockOrientation != BlockLine.BlockLineOrientation.Right)
                    {
                        addedBlock.StartPoint = new Point(this.EndingPoint.XPos - 1, this.EndingPoint.YPos, this.EndingPoint.ZPos);
                        addedBlock.EndPoint   = new Point(this.EndingPoint.XPos - numBlocks, this.EndingPoint.YPos, this.EndingPoint.ZPos);

                        // Will it fit in the 4x4 grid? And is there space?
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheckAndReserve(addedBlock, new Point(-1, 0, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.BlockLineOrientation.Right:
                    if (lastBlockOrientation != BlockLine.BlockLineOrientation.Left && lastBlockOrientation != BlockLine.BlockLineOrientation.Right)
                    {
                        addedBlock.StartPoint = new Point(this.EndingPoint.XPos + 1, this.EndingPoint.YPos, this.EndingPoint.ZPos);
                        addedBlock.EndPoint   = new Point(this.EndingPoint.XPos + numBlocks, this.EndingPoint.YPos, this.EndingPoint.ZPos);

                        // Will it fit in the 4x4 grid? And is there space?
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheckAndReserve(addedBlock, new Point(1, 0, 0)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.BlockLineOrientation.Up:
                    if (lastBlockOrientation != BlockLine.BlockLineOrientation.Up && lastBlockOrientation != BlockLine.BlockLineOrientation.Down)
                    {
                        addedBlock.StartPoint = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos, this.EndingPoint.ZPos + 1);
                        addedBlock.EndPoint   = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos, this.EndingPoint.ZPos + numBlocks);

                        // Will it fit in the 4x4 grid? And is there space?
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheckAndReserve(addedBlock, new Point(0, 0, 1)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;

                case BlockLine.BlockLineOrientation.Down:
                    if (lastBlockOrientation != BlockLine.BlockLineOrientation.Up && lastBlockOrientation != BlockLine.BlockLineOrientation.Down)
                    {
                        addedBlock.StartPoint = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos, this.EndingPoint.ZPos - 1);
                        addedBlock.EndPoint   = new Point(this.EndingPoint.XPos, this.EndingPoint.YPos, this.EndingPoint.ZPos - numBlocks);

                        // Will it fit in the 4x4 grid? And is there space?
                        if (this.BoundsCheck(addedBlock))
                        {
                            if (this.SpaceCheckAndReserve(addedBlock, new Point(0, 0, -1)))
                            {
                                additionSuccess = true;
                            }
                        }
                    }
                    break;
                }
            }

            // Add the block to the list
            if (additionSuccess)
            {
                this.ListOfBlocks.Add(addedBlock);
                this.EndingPoint = addedBlock.EndPoint;

                this.BlockLineIndex++;

                // If you find the 0 termination at the end of the list, you're done!
                if (this.BlockLineOrder[this.BlockLineIndex] == 0)
                {
                    this.IsFinished = true;
                    Console.WriteLine("==Solution==================================================================================");
                    this.PrintPuzzle();
                }
            }

            return(additionSuccess);
        }