Пример #1
0
        public void SolveTenBlockPuzzle(out FiveBlocks bottomLayerOfSolution, out FiveBlocks topLayerOfSolution)
        {
            // get the blocks needed for the 10 piece wooden puzzle
            BlockFactory blockFactory = new BlockFactory();
            TenBlocks    tenBlocks    = blockFactory.GetPuzzleWithTenBlocks();

            // get a collection of all 5 block variations including all possible flipped blocks.
            // each of these FiveBlocks objects forms the bottom of a potential solution, until disproved
            HashSet <FiveBlocks> listsOfFiveBlocks = CalculateAllFiveBlockVariationsIncludingReversals(tenBlocks);

            CalculateLayerOfSolution(out bottomLayerOfSolution, out topLayerOfSolution, tenBlocks, listsOfFiveBlocks);
        }
Пример #2
0
        public TenBlocks GetPuzzleWithTenBlocks()
        {
            List <Block> blocks = new List <Block>();

            // creating blocks from real blocks. turning the blocks so that the more "interesting" stuff is on the left, just to make recognising blocks easier.
            blocks.Add(
                CreateBlock(
                    1, CreateBlockSlotArray1()));
            blocks.Add(
                CreateBlock(
                    2, CreateBlockSlotArray2()));
            blocks.Add(
                CreateBlock(
                    3, CreateBlockSlotArray3()));
            blocks.Add(
                CreateBlock(
                    4, CreateBlockSlotArray4()));
            blocks.Add(
                CreateBlock(
                    5, CreateBlockSlotArray5()));
            blocks.Add(
                CreateBlock(
                    6, CreateBlockSlotArray6()));
            blocks.Add(
                CreateBlock(
                    7, CreateBlockSlotArray7()));
            blocks.Add(
                CreateBlock(
                    8, CreateBlockSlotArray8()));
            blocks.Add(
                CreateBlock(
                    9, CreateBlockSlotArray9()));
            blocks.Add(
                CreateBlock(
                    10, CreateBlockSlotArray10()));

            TenBlocks tenBlocks = new TenBlocks(blocks);

            return(tenBlocks);
        }
Пример #3
0
        private void CalculateLayerOfSolution(out FiveBlocks bottomLayerOfSolution, out FiveBlocks topLayerOfSolution, TenBlocks tenBlocks, HashSet <FiveBlocks> listsOfFiveBlocks)
        {
            bottomLayerOfSolution = null;
            topLayerOfSolution    = null;
            foreach (var bottomFiveBlocks in listsOfFiveBlocks)
            {
                // now get the remaining five blocks
                FiveBlocks topFiveBlocks = new FiveBlocks(tenBlocks.Where(b => !bottomFiveBlocks.Contains(b)).ToList());

                Dictionary <Block, int> blockToIndexMaping = GetTopLayerBlockMappingToBottomLayerIndex(bottomFiveBlocks, topFiveBlocks);

                if (blockToIndexMaping.Count == 5)
                {
                    // this means we've matched all 5! we're done!
                    // assign the layers
                    bottomLayerOfSolution = bottomFiveBlocks;
                    topLayerOfSolution    = new FiveBlocks(blockToIndexMaping.Keys.ToList());
                    break;
                }
            }
        }
Пример #4
0
        private HashSet <FiveBlocks> CalculateAllFiveBlockVariationsIncludingReversals(TenBlocks tenBlocks)
        {
            // all variations of true and false:
            //  - true  = not reversed block
            //  - false = reversed block
            Variations <bool> flagVariations = CalculateAndPrintFlagVariations();

            var blockVariations = new Variations <Block>(tenBlocks, 5);
            HashSet <FiveBlocks> listsOfFiveBlocks = new HashSet <FiveBlocks>();

            foreach (var variation in blockVariations)
            {
                // now we have an ordered list of 5 blocks.
                // for each permutation, there 2 ^ 5 = 32 ways to flip the pieces
                foreach (List <bool> flagVariation in flagVariations)
                {
                    List <Block> finalFixedList = new List <Block>();
                    for (int i = 0; i < flagVariation.Count; i++)
                    {
                        // use the flag to choose reversed block or not
                        // TODO: memoization can easily be used here to not keep reversing the blocks
                        finalFixedList.Add(flagVariation[i] ? variation[i] : new Block(variation[i]));
                    }

                    // final list for the bottom is built
                    listsOfFiveBlocks.Add(new FiveBlocks(finalFixedList));
                }
            }

            return(listsOfFiveBlocks);
        }