示例#1
0
        public static void FujisanMain()
        {
            int TRIALS = 1;
            int EXP    = 100;

            // Choose here the setup algorithm you wish to use
            FujisanSetup setup = FujisanSetup.PIECEPACK;

            // Choose here the search algorithm for the solver
            Search search = Search.ASTAR;

            List <int> hist         = new List <int>();
            List <int> countermoves = new List <int>();
            Random     random       = new Random();

            // Easy output for copying into a spreadsheet
            Console.WriteLine("solved\tdead\tavelen\tsconn\tfconn");

            // Run the specified number of experiments within the number
            // of specified trials
            for (int t = 0; t < TRIALS; t++)
            {
                int    count  = 0;
                int    lensum = 0;
                int    dead   = 0;
                double sconn  = 0;
                double fconn  = 0;
                int    max    = 0;

                Parallel.For(0, EXP, i =>
                             //for (int i = 0; i < EXP; i++)
                {
                    // Total count of boards, for HashSet later
                    int bcount = 0;

                    // Store all boards seen in found
                    HashSet <Board> found = new HashSet <Board>();

                    // Keep track of board states to explore in frontier
                    // Sort them by heuristic plus current path length for A*
                    SortedList <double, Board> frontier = new SortedList <double, Board>();

                    // Create a new board and place it in the frontier
                    Board start = new Board(random, setup);
                    Console.WriteLine(start);
                    Console.WriteLine("Starting:");
                    Console.WriteLine(start + "\n");
                    frontier.Add(start.length + start.Heuristic() + (1e-12 * bcount), start);

                    // Keep searching the frontier until it is empty or
                    // a solution is found
                    bool solved = false;
                    while (frontier.Count > 0)
                    {
                        // Take the most promising board state, remove from
                        // frontier and add it to the found set
                        var keys    = frontier.Keys;
                        var first   = keys[0];
                        Board board = frontier[first];
                        frontier.Remove(first);
                        found.Add(board);

                        // Find the children of the current board
                        List <Board> children = board.GetChildren();
                        List <Board> stuff    = new List <Board>();
                        if (search == Search.ASTAR)
                        {
                            stuff = children;
                        }
                        else  // Pick a child randomly
                        {
                            if (children.Count > 0)
                            {
                                stuff.Add(children[random.Next(0, children.Count)]);
                            }
                        }
                        Console.WriteLine(frontier.Count);
                        foreach (Board b in stuff)
                        {
                            // Did you find a solution?
                            if (b.Solved())
                            {
                                // Yay! Record statistics
                                solved = true;
                                Debug.WriteLine("SOLUTION!!!!");
                                Debug.WriteLine(b.Path());

                                frontier.Clear();
                                lock (random)
                                {
                                    sconn  += start.ConnectionStrength();
                                    lensum += b.length;
                                    count++;
                                    Console.WriteLine(b.length + "," +
                                                      b.countermoves + "," + b.MovePath());

                                    if (b.length > max)
                                    {
                                        Debug.WriteLine("SOLUTION!!!!");
                                        Debug.WriteLine(b.Path());
                                        max = b.length;
                                    }
                                }
                                break;
                            }

                            // If you have never seen this board before
                            // Add it to the frontier
                            if (!found.Contains(b) && !frontier.ContainsValue(b))
                            {
                                bcount++;
                                frontier.Add(b.length + b.Heuristic() + (1e-12 * bcount), b);
                            }
                            else
                            {
                                //Console.WriteLine("WOAH!");
                            }
                        }
                    }

                    // Record when no children of initial state could be found
                    if (!solved)
                    {
                        fconn += start.ConnectionStrength();
                        if (found.Count == 1)
                        {
                            lock (random)
                            {
                                dead++;
                            }
                        }
                    }
                });

                Console.WriteLine(((float)count / EXP) +
                                  "\t" + ((float)dead / EXP) +
                                  "\t" + ((float)lensum / count) +
                                  "\t" + sconn / count +
                                  "\t" + fconn / (EXP - count));
            }
            Console.WriteLine("Steps");
            foreach (int i in hist)
            {
                Console.WriteLine(i);
            }
            Console.WriteLine("CounterMoves");
            foreach (int i in countermoves)
            {
                Console.WriteLine(i);
            }
        }
示例#2
0
        /******
         * Creates a random starting board state
         */
        public Board(Random random, FujisanSetup s)
        {
            this.random = random;
            move        = "START";
            moveType    = FujisanMoveType.START;

            values = new int[2, 14];
            if (s == FujisanSetup.ENGRAVED)
            {
                // Make the 20 tiles matching domino distribution
                List <Tile> list = new List <Tile>();
                for (int i = 0; i < 6; i++)
                {
                    int start = i;
                    if (i == 0)
                    {
                        start = 1;
                    }
                    for (int j = start; j < 6; j++)
                    {
                        list.Add(new Tile(i, j));
                    }
                }

                //Console.WriteLine("AUGH!!!!" + list.Count);

                Shuffle <Tile>(list, random);

                // Fill in numbers on the left half
                int t = -1;
                for (int i = 0; i < 5; i++)
                {
                    t++;
                    if (random.NextDouble() > 0.5)
                    {
                        list[t].Rotate();
                    }
                    values[0, t + 1] = list[t].values[0, 0];
                    values[1, t + 1] = list[t].values[1, 0];
                }
                values[0, t + 2] = list[t].values[0, 1];
                values[1, t + 2] = list[t].values[1, 1];

                // Fill in numbers on the right half
                for (int i = 0; i < 5; i++)
                {
                    t++;
                    if (random.NextDouble() > 0.5)
                    {
                        list[t].Rotate();
                    }
                    values[0, 12 - i] = list[t].values[0, 1];
                    values[1, 12 - i] = list[t].values[1, 1];
                }
                values[0, 7] = list[t].values[0, 0];
                values[1, 7] = list[t].values[1, 0];
            }
            else if (s == FujisanSetup.DOMINO)
            {
                // Make the 15 tiles matching domino distribution
                List <Tile> list = new List <Tile>();
                for (int i = 0; i < 6; i++)
                {
                    int start = i + 1;
                    for (int j = start; j < 6; j++)
                    {
                        list.Add(new Tile(i, j));
                    }
                }

                //Console.WriteLine("AUGH!!!!" + list.Count);

                Shuffle <Tile>(list, random);

                // Fill in numbers on the left half
                int t = -1;
                for (int i = 0; i < 6; i++)
                {
                    t++;
                    if (random.NextDouble() > 0.5)
                    {
                        list[t].Rotate();
                    }
                    values[0, t + 1] = list[t].values[0, 0];
                    values[1, t + 1] = list[t].values[1, 0];
                }

                // Fill in numbers on the right half
                for (int i = 0; i < 6; i++)
                {
                    t++;
                    if (random.NextDouble() > 0.5)
                    {
                        list[t].Rotate();
                    }
                    values[0, 12 - i] = list[t].values[0, 1];
                    values[1, 12 - i] = list[t].values[1, 1];
                }
            }

            else if (s == FujisanSetup.PIECEPACK)
            {
                // Make the coins for the piecepack
                List <Byte>[] coins = new List <Byte> [4];
                for (int i = 0; i < 4; i++)
                {
                    coins[i] = new List <Byte>();
                }
                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        coins[j].Add((byte)i);
                    }
                }

                // Shuffle the coins within each type (sun, moon, etc)
                for (int i = 0; i < 4; i++)
                {
                    Shuffle <Byte>(coins[i], random);
                }

                // Place the coins on the board, starting at the
                // right, and filling two from each type at a time
                int where = 12;
                for (int k = 0; k < 3; k++)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        for (int j = 0; j < 2; j++)
                        {
                            values[j, where] = coins[i][j + k * 2];
                        }
                        where--;
                    }
                }
            }
            else if (s == FujisanSetup.ANYCOIN)
            {
                // Make the coins for the piecepack
                List <Byte> coins = new List <Byte>();
                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        coins.Add((byte)i);
                    }
                }

                // Shuffle the coins
                Shuffle <Byte>(coins, random);

                // Place the coins on the board, starting at the
                // right, and filling two from each type at a time
                int where = 12;
                for (int k = 0; k < 12; k++)
                {
                    for (int j = 0; j < 2; j++)
                    {
                        values[j, where] = coins[j + k * 2];
                    }
                    where--;
                }
            }
            else if (s == FujisanSetup.HARDCODE)
            {
                // Initial board from Puzzle Four
                // http://www.ludism.org/ppwiki/Fuji-san#Heading9

                values[0, 12] = 5;
                values[1, 12] = 4;
                values[0, 11] = 3;
                values[1, 11] = 5;
                values[0, 10] = 3;
                values[1, 10] = 0;
                values[0, 9]  = 4;
                values[1, 9]  = 1;
                values[0, 8]  = 2;
                values[1, 8]  = 0;
                values[0, 7]  = 2;
                values[1, 7]  = 0;
                values[0, 6]  = 2;
                values[1, 6]  = 1;
                values[0, 5]  = 0;
                values[1, 5]  = 3;
                values[0, 4]  = 1;
                values[1, 4]  = 3;
                values[0, 3]  = 1;
                values[1, 3]  = 4;
                values[0, 2]  = 5;
                values[1, 2]  = 4;
                values[0, 1]  = 5;
                values[1, 1]  = 2;
            }
            else if (s == FujisanSetup.RANDOM)
            {
                for (int i = 0; i < 2; i++)
                {
                    for (int j = 1; j < 13; j++)
                    {
                        values[i, j] = random.Next(0, 6);
                    }
                }
            }

            // Place the pawns on the edges of the board
            pawns        = new int[2, 14];
            pawns[0, 0]  = 1;
            pawns[1, 0]  = 1;
            pawns[0, 13] = 1;
            pawns[1, 13] = 1;
        }