Beispiel #1
0
 bool IsAtGoal(byte[] key, int piece, solveType type, int pos)
 {
     if (type != solveType.AllNonSpecificSolutions)
     {
         return(pos == key[this.piecePositions[this.isA[piece - 1, 0] - 1] + this.isA[piece - 1, 1] - 1]);
     }
     else
     {
         foreach (byte p2 in this.aIs[this.isA[piece - 1, 0] - 1])
         {
             if (pos == key[this.piecePositions[this.isA[p2 - 1, 0] - 1] + this.isA[p2 - 1, 1] - 1])
             {
                 return(true);
             }
         }
         return(false);
     }
 }
Beispiel #2
0
        static void Main(string[] args)
        {
            //Solve type
            solveType type         = solveType.Diameter;
            int       goalPosition = 13;
            int       goalPiece    = 1;     //Only needed if solveType=1 or 2.
            int       NumSolutions = 0;     //Only for solveType.AllSolutions
            Boolean   WriteToFile  = false; //TODO: Actually use this
            Boolean   verbose      = false;



            DateTime startTime = DateTime.Now;
            DateTime moveTime;

            Globals.boards            = new Dictionary <byte[], int[]>(new IntArrayComparer()); //At some point I should change the second type to a smaller type.
            Globals.lastboards        = new Dictionary <byte[], int[]>(new IntArrayComparer()); //Maybe tomorrow.
            Globals.newboards         = new Dictionary <byte[], int[]>(new IntArrayComparer());
            Globals.PuzzlesConsidered = 0;
            Globals.TotalPuzzles      = 0;
            //System.IO.TextWriter tw = new System.IO.StreamWriter("output.log"); //Start writing the log file.



            byte[,] testboard = new byte[, ]
            {
                { 1, 2, 2, 3 },
                { 1, 2, 2, 3 },
                { 0, 4, 4, 0 },
                { 5, 6, 7, 8 },
                { 5, 9, 10, 8 },
            };

            //Climb 24:{ { 1, 1, 1, 0, 1, 1, 1 }, { 2, 2, 0, 0, 0, 3, 3 }, { 4, 4, 5, 5, 5, 6, 6 }, { 4, 4, 7, 8, 8, 6, 6 }, { 9, 9, 7, 7, 8, 10, 10 }, { 11, 9, 12, 13, 14, 10, 15 }, { 11, 16, 12, 17, 14, 18, 15 }, { 16, 16, 19, 19, 19, 18, 18 }, { 20, 20, 21, 22, 23, 24, 24 }, { 20, 20, 22, 22, 22, 24, 24 } };
            //Must be the same size as Globals.y*Globals.x
            //By the way, if you're wondering why all the coordinates in the program are like (y,x), it's to make the above look nice.


            Globals.x         = 4;
            Globals.y         = 5;
            Globals.numPieces = 10;             //The maximum number of testboard

            MakePieceArray(testboard);          //Initialize all the arrays.

            byte[] packtest2 = Pack(testboard); //The only use of the pack function.
            foreach (byte k in Unpack(packtest2))
            {
                Console.Write(k + " ");
            }
            Globals.newboards.Add(packtest2, new int[0]); //Initalize the puzzle.
            int step = 1;                                 //This is the read generation

            while (Globals.newboards.Count != 0)
            {
                moveTime = DateTime.Now;
                GenerateNextBoards(); //This step takes the longest.

                //check for solutions
                if ((type != solveType.Diameter) && (type != solveType.FullList))
                {
                    if (verbose)
                    {
                        Console.WriteLine("Checking for solution...");
                    }
                    foreach (KeyValuePair <byte[], int[]> pair in Globals.newboards)
                    {
                        if (pair.Key[Globals.piecePositions[Globals.isA[goalPiece - 1, 0] - 1] + Globals.isA[goalPiece - 1, 1] - 1] == goalPosition)
                        {
                            if (type == solveType.Solve)
                            {
                                if (verbose)
                                {
                                    Console.WriteLine("FOUND SOLUTION AT {0} MOVES!", step);
                                    WriteBoard(pair);
                                }
                                goto donehere; //I am ashamed.
                            }
                            else
                            {
                                if (verbose)
                                {
                                    WriteBoard(pair);
                                }
                                NumSolutions++;
                            }
                        }
                    }
                }


                Globals.TotalPuzzles += Globals.newboards.Count;
                //tw.WriteLine(step + " steps: " + Globals.newboards.Count + " boards, " + DateTime.Now+"({0} total puzzles, {1} total puzzles considered)",Globals.TotalPuzzles,Globals.PuzzlesConsidered);
                //tw.Flush();
                Console.WriteLine(step + " steps: " + Globals.newboards.Count + " boards, " + DateTime.Now + "({0} total puzzles, {1} total puzzles considered, {2} boards per second)", Globals.TotalPuzzles, Globals.PuzzlesConsidered, Globals.newboards.Count / DateTime.Now.Subtract(moveTime).TotalSeconds);
                step++; //Fairly important.
            }
donehere:
            if (type == solveType.Diameter)
            {
                //Write out the moves to get to the positions which are hardest to get to.
                Console.WriteLine("Finished diameter search! Total time: {0}", DateTime.Now.Subtract(startTime));

                foreach (KeyValuePair <byte[], int[]> temp in Globals.boards)
                {
                    WriteBoard(temp);
                }
            }
            else
            {
                Console.WriteLine("Done! Total time: {0}", DateTime.Now.Subtract(startTime));
                if (type == solveType.AllSolutions)
                {
                    Console.WriteLine("{0} solutions found", NumSolutions);
                }
            }
            Console.WriteLine("Press enter to exit...");

            Console.ReadLine();
        }
Beispiel #3
0
        /// <summary>
        /// Solve a sliding-block puzzle given the puzzle, solve type, goal position, goal piece, and different pieces (oh and also if it should spew things to the screen)
        /// </summary>
        /// <param name="startboards">The initial state(s) of the puzzle to be solved.</param>
        /// <param name="type">The type of solution to give.</param>
        /// <param name="goalPosition">Where the goal piece should be moved.</param>
        /// <param name="goalPiece">The goal piece.</param>
        /// <param name="verbose">Should I tell you everything about the number 42 and this puzzle?</param>
        /// <param name="differentPieces">The pieces which are painted differently from the others.</param>
        public void SolveBoard(List <byte[, ]> startboards, solveType type, int goalPosition, int goalPiece, Verbosity verbosity, byte[] differentPieces, Func <byte[, ], bool> checkfunc)
        {
            //Solve type
            //solveType type = solveType.Solve;
            //int goalPosition = 2;
            //int goalPiece = 22; //Only needed if solveType=1 or 2.
            int     NumSolutions = 0;     //Only for solveType.AllSolutions
            Boolean WriteToFile  = false; //TODO: Actually use this

            //Boolean verbose = true;

            results   = new List <byte[, ]>();
            resultnum = 0;

            this.startTime = DateTime.Now;
            DateTime moveTime;


            //System.IO.TextWriter tw = new System.IO.StreamWriter("output.log"); //Start writing the log file.

            //testboard Must be the same size as Globals.y*Globals.x
            //By the way, if you're wondering why all the coordinates in the program are like (y,x), it's to make the above look nice.


            //Globals.x = 7;
            //Globals.y = 10;
            Globals.x      = (byte)startboards[0].GetLength(1);
            Globals.y      = (byte)startboards[0].GetLength(0);
            this.numPieces = Max(startboards[0]);            //The maximum number of testboard

            MakePieceArray(startboards[0], differentPieces); //Initialize all the arrays.

            comparer               = new IntArrayComparer(piecePositions);
            this.boards            = new Dictionary <byte[], int[]>(comparer); //At some point I should change the second type to a smaller type.
            this.lastboards        = new Dictionary <byte[], int[]>(comparer); //Maybe tomorrow.
            this.newboards         = new Dictionary <byte[], int[]>(comparer);
            this.PuzzlesConsidered = 0;
            this.TotalPuzzles      = 0;

            byte[] packtest2;
            for (int i = 0; i < startboards.Count; i++)
            {
                packtest2 = Pack(startboards[i]); //The only use of the pack function.
                if (verbosity == Verbosity.Verbose)
                {
                    foreach (byte k in Unpack(packtest2))
                    {
                        Console.Write(k + " ");
                    }
                }
                this.newboards.Add(packtest2, new int[0]); //Initalize the puzzle (s).
            }
            int step = 0;                                  //This is the read generation

            moveTime = DateTime.Now;
            while (this.newboards.Count != 0)
            {
                //check for solutions
                if ((type != solveType.Diameter) && (type != solveType.FullList))
                {
                    if (verbosity == Verbosity.Verbose)
                    {
                        Console.WriteLine("Checking for solution...");
                    }
                    foreach (KeyValuePair <byte[], int[]> pair in this.newboards)
                    {
                        if (IsAtGoal(pair.Key, goalPiece, type, goalPosition))
                        {
                            byte[,] unpackedBoard = Unpack(pair.Key);
                            bool isOK = false;
                            if (checkfunc == null)
                            {
                                isOK = true;
                            }
                            else if (checkfunc(unpackedBoard))
                            {
                                isOK = true;
                            }
                            if (isOK)
                            {
                                if (type == solveType.Solve)
                                {
                                    if (verbosity != Verbosity.Silent)
                                    {
                                        Console.WriteLine("FOUND SOLUTION AT {0} MOVES!", step);
                                        WriteBoard(pair);
                                    }
                                    results.Add(Unpack(pair.Key));

                                    goto donehere; //I am ashamed.
                                }
                                else
                                {
                                    if (verbosity == Verbosity.Verbose)
                                    {
                                        WriteBoard(pair);
                                    }
                                    results.Add(Unpack(pair.Key));
                                    resultnum = step;
                                    NumSolutions++;
                                }
                            }
                        }
                    }
                }


                this.TotalPuzzles += this.newboards.Count;
                //tw.WriteLine(step + " steps: " + this.newboards.Count + " boards, " + DateTime.Now+"({0} total puzzles, {1} total puzzles considered)",this.TotalPuzzles,this.PuzzlesConsidered);
                //tw.Flush();
                if (verbosity == Verbosity.Verbose)
                {
                    Console.WriteLine(step + " steps: " + this.newboards.Count + " boards, " + DateTime.Now + "({0} total puzzles, {1} total puzzles considered, {2} boards per second)", this.TotalPuzzles, this.PuzzlesConsidered, this.newboards.Count / DateTime.Now.Subtract(moveTime).TotalSeconds);
                }
                step++; //Fairly important.

                moveTime = DateTime.Now;

                GenerateNextBoards(); //This step takes the longest.
            }
donehere:
            //Write out results to the results class


            switch (type)
            {
            case solveType.Solve:
                resultnum = step;
                break;

            case solveType.Diameter:
                resultnum = step - 1;
                break;
            }

            if (type == solveType.Diameter)
            {
                foreach (KeyValuePair <byte[], int[]> key in this.boards)
                {
                    results.Add(Unpack(key.Key)); //Yeah, this line isn't confusing at all.
                }
            }



            if (type == solveType.Diameter && verbosity != Verbosity.Silent)
            {
                //Write out the moves to get to the positions which are hardest to get to.
                Console.WriteLine("Finished diameter search! Total time: {0}", DateTime.Now.Subtract(this.startTime));

                foreach (KeyValuePair <byte[], int[]> temp in this.boards)
                {
                    WriteBoard(temp);
                }
            }
            else
            {
                if (verbosity != Verbosity.Silent)
                {
                    Console.WriteLine("Done! Total time: {0}", DateTime.Now.Subtract(this.startTime));
                }
                if (type == solveType.AllNonSpecificSolutions)
                {
                    if (verbosity != Verbosity.Silent)
                    {
                        Console.WriteLine("{0} solutions found", NumSolutions);
                    }
                    resultnum = step - 1;
                }
            }
            //Console.WriteLine("Press enter to exit...");

            //Console.ReadLine();
        }