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