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()); } }
// 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); }
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); }
// 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); }
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); }
// 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()); } }
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)); }
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); }
// 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)); }
// 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); }