Exemplo n.º 1
0
        /// <summary>
        /// Create a pruning table using corner permutation and equator order.
        /// Every table entry contains the exact number of moves required to
        /// solve the position represented by said coordinates.
        /// </summary>
        /// <returns>
        /// Create a pruning table using corner permutation equator order.
        /// </returns>
        public static byte[] CreatePhase2CornerEquatorTable()
        {
            byte invalid = 255;

            byte[] pruningTable = Enumerable
                                  .Repeat(invalid, PruningTableConstants.CornerEquatorPruningTableSizePhase2)
                                  .ToArray();

            TableController.InitializeCornerPermutationMoveTable();
            TableController.InitializeEquatorOrderMoveTable();

            pruningTable[0] = 0; //solved
            int done  = 1;
            int depth = 0;

            string outputFormat = "depth: {0}, done: {1}/" + PruningTableConstants.CornerEquatorPruningTableSizePhase2 + " ({2:P})";

            Console.WriteLine(string.Format(outputFormat, depth, done, done / (double)PruningTableConstants.CornerEquatorPruningTableSizePhase2));

            while (done < PruningTableConstants.CornerEquatorPruningTableSizePhase2)
            {
                for (int cornerPermutation = 0; cornerPermutation < NumCornerPermutations; cornerPermutation++)
                {
                    for (int equatorPermutation = 0; equatorPermutation < NumEquatorOrders; equatorPermutation++)
                    {
                        int index = NumEquatorOrders * cornerPermutation + equatorPermutation;
                        if (pruningTable[index] == depth)
                        {
                            foreach (int move in TwoPhaseConstants.Phase2Moves)
                            {
                                int newCornerPermutation = TableController.CornerPermutationMoveTable[cornerPermutation, move];
                                int newEquatorOrder      = TableController.EquatorOrderMoveTable[equatorPermutation, move];
                                int newIndex             = NumEquatorOrders * newCornerPermutation + newEquatorOrder;

                                if (pruningTable[newIndex] == invalid)
                                {
                                    pruningTable[newIndex] = (byte)(depth + 1);
                                    done++;
                                }
                            }
                        }
                    }
                }
                depth++;
                Console.WriteLine(string.Format(outputFormat, depth, done, done / (double)PruningTableConstants.CornerEquatorPruningTableSizePhase2));
            }

            return(pruningTable);
        }
Exemplo n.º 2
0
        //Not used
        /// <summary>
        /// Create a weighted pruning table using U- and D-edge order and
        /// equator edge order. Every table entry contains the minimum cost
        /// required to solve the position represented by said coordinates.
        /// </summary>
        /// <param name="weights">The weights to use.</param>
        /// <returns>
        /// A weighted pruning table using U- and D-edge order and equator edge
        /// order.
        /// </returns>
        /// <exception cref="InvalidWeightsException">
        /// Thrown if <paramref name="weights"/> is invalid.
        /// </exception>
        public static float[] CreateWeightedPhase2UdEquatorTable(float[] weights)
        {
            MoveWeightsUtils.ValidateWeights(weights);

            float invalid = float.NaN;

            float[] pruningTable = Enumerable
                                   .Repeat(invalid, PruningTableConstants.UdEquatorPruningTableSizePhase2)
                                   .ToArray();

            TableController.InitializeUdEdgeOrderMoveTable();
            TableController.InitializeEquatorOrderMoveTable();

            pruningTable[0] = 0f;
            int numChanged = -1;

            while (numChanged != 0)
            {
                numChanged = 0;
                for (int udEdgeOrder = 0; udEdgeOrder < NumUdEdgeOrders; udEdgeOrder++)
                {
                    for (int equatorOrder = 0; equatorOrder < NumEquatorOrders; equatorOrder++)
                    {
                        int index = NumEquatorOrders * udEdgeOrder + equatorOrder;
                        if (pruningTable[index] != invalid)
                        {
                            foreach (int move in TwoPhaseConstants.Phase2Moves)
                            {
                                int newUdEdgeOrder  = TableController.UdEdgeOrderMoveTable[udEdgeOrder, MoveTables.Phase1IndexToPhase2Index[move]];
                                int newEquatorOrder = TableController.EquatorOrderMoveTable[equatorOrder, move];
                                int newIndex        = NumEquatorOrders * newUdEdgeOrder + newEquatorOrder;

                                float newPruningValue = pruningTable[index] + weights[move];

                                if (pruningTable[newIndex] == invalid || pruningTable[newIndex] > newPruningValue)
                                {
                                    pruningTable[newIndex] = newPruningValue;
                                    numChanged++;
                                }
                            }
                        }
                    }
                }
            }

            return(pruningTable);
        }