Пример #1
0
        private static void explore(int delay)
        {
            GemPuzzleForm oGemPuzzleForm = GemPuzzleForm.getInstance();
            PuzzleState   currentState;

            int[] tmpValues = new int[Constants.InvisibleValue];
            oGemPuzzleForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
            {
                for (int i = Constants.MinimumValue; i < Constants.InvisibleValue; i++)
                {
                    tmpValues[i] = oGemPuzzleForm.gemButtons[i].Value;
                }
            }));
            currentState = new PuzzleState(tmpValues);
            while (Solver.Position < (Solver.SolutionMoves.Length - 1))
            {
                currentState = new PuzzleState(currentState, Solver.SolutionMoves[++Solver.Position]);
                Solver.updateTiles(currentState);
                Thread.Sleep(delay);
            }
            oGemPuzzleForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
            {
                oGemPuzzleForm.ControlButtons = true;
            }));
        }
Пример #2
0
        /// <summary>
        /// Given a state, it calculates a new state randomly.
        /// </summary>
        /// <param name="state">The state containing the next possible and valid moves.</param>
        /// <returns>A state created randomly from a given state.</returns>
        public static PuzzleState SetNextStateRandomly(PuzzleState state)
        {
            PuzzleState tmpState;
            Random      nextMove = new Random(DateTime.Now.Millisecond);
            int         index    = nextMove.Next(0, state.ValidMoves.Length);

            tmpState = new PuzzleState(state.Values, state.ValidMoves[index]);
            return(tmpState);
        }
Пример #3
0
 private static void updateTiles(PuzzleState state)
 {
     GemPuzzleForm.getInstance().Invoke(new System.Windows.Forms.MethodInvoker(() =>
     {
         for (int j = Constants.MinimumValue; j < Constants.InvisibleValue; j++)
         {
             GemPuzzleForm.getInstance().gemButtons[j].Value = state.Values[j];
         }
     }));
 }
Пример #4
0
        private static void shuffleTiles()
        {
            GemPuzzleForm oGemPuzzleForm = GemPuzzleForm.getInstance();

            Solver.StartNode = Solver.getCurrentState();
            for (int i = 0; i < 50; i++)
            {
                Solver.StartNode = PuzzleState.SetNextStateRandomly(Solver.StartNode);
                Solver.updateTiles(Solver.StartNode);
                Thread.Sleep(100);
            }
        }
Пример #5
0
 /// <summary>
 /// This constructor is used when it is only necessary to create a copy ot the current state in the puzzle.
 /// </summary>
 public PuzzleState(PuzzleState state)
 {
     this.NonVisiblePosition = state.NonVisiblePosition;
     this.Values = new int[state.Values.Length];
     state.Values.CopyTo(this.Values, 0);
     this.LastMove = state.LastMove;
     this.Heuristic1 = state.Heuristic1;
     this.Heuristic2 = state.Heuristic2;
     this.Cost = state.Cost;
     this.PreviousMoves = new List<byte>(state.PreviousMoves);
     this.ValidMoves = new byte[state.ValidMoves.Length];
     state.ValidMoves.CopyTo(this.ValidMoves, 0);
 }
Пример #6
0
 /// <summary>
 /// This constructor is used when it is only necessary to create a copy ot the current state in the puzzle.
 /// </summary>
 public PuzzleState(PuzzleState state)
 {
     this.NonVisiblePosition = state.NonVisiblePosition;
     this.Values             = new int[state.Values.Length];
     state.Values.CopyTo(this.Values, 0);
     this.LastMove      = state.LastMove;
     this.Heuristic1    = state.Heuristic1;
     this.Heuristic2    = state.Heuristic2;
     this.Cost          = state.Cost;
     this.PreviousMoves = new List <byte>(state.PreviousMoves);
     this.ValidMoves    = new byte[state.ValidMoves.Length];
     state.ValidMoves.CopyTo(this.ValidMoves, 0);
 }
Пример #7
0
        private static int searchInList(List <PuzzleState> list, PuzzleState state)
        {
            int index = -1;

            for (int i = 0; (i < list.Count) && (index == -1); i++)
            {
                if (list[i].IsEqualTo(state))
                {
                    index = i;
                }
            }
            return(index);
        }
Пример #8
0
 /// <summary>
 /// This constructor creates a new state, and updates cost, heuristic, none visible position, etc.
 /// </summary>
 /// <param name="state">This is the parent node</param>
 /// <param name="nextMovePosition">This is the position in the array that actually creates the new state.</param>
 public PuzzleState(PuzzleState state, byte nextMovePosition)
 {
     this.Values = new int[Constants.InvisibleValue];
     state.Values.CopyTo(this.Values, 0);
     this.LastMove = state.NonVisiblePosition;
     this.NonVisiblePosition = nextMovePosition;
     this.Values[this.LastMove] = this.Values[nextMovePosition];
     this.Values[nextMovePosition] = Constants.InvisibleValue;
     this.Heuristic1 = getHeuristic1();
     this.Heuristic2 = getHeuristic2();
     this.Cost = state.Cost + 1;
     this.PreviousMoves = new List<byte>(state.PreviousMoves);
     this.PreviousMoves.Add(nextMovePosition);
     this.setValidMovements();
 }
Пример #9
0
 /// <summary>
 /// This constructor creates a new state, and updates cost, heuristic, none visible position, etc.
 /// </summary>
 /// <param name="state">This is the parent node</param>
 /// <param name="nextMovePosition">This is the position in the array that actually creates the new state.</param>
 public PuzzleState(PuzzleState state, byte nextMovePosition)
 {
     this.Values = new int[Constants.InvisibleValue];
     state.Values.CopyTo(this.Values, 0);
     this.LastMove                 = state.NonVisiblePosition;
     this.NonVisiblePosition       = nextMovePosition;
     this.Values[this.LastMove]    = this.Values[nextMovePosition];
     this.Values[nextMovePosition] = Constants.InvisibleValue;
     this.Heuristic1               = getHeuristic1();
     this.Heuristic2               = getHeuristic2();
     this.Cost          = state.Cost + 1;
     this.PreviousMoves = new List <byte>(state.PreviousMoves);
     this.PreviousMoves.Add(nextMovePosition);
     this.setValidMovements();
 }
Пример #10
0
        /// <summary>
        /// Checks if two states have the same value arrangement (the tiles).
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        public bool IsEqualTo(PuzzleState state)
        {
            bool equals = false;

            if ((state.Heuristic2 == this.Heuristic2) && (state.Heuristic1 == this.Heuristic1))
            {
                equals = true;
                for (int i = Constants.MinimumValue; (i < Constants.InvisibleValue) && equals; i++)
                {
                    if (state.Values[i] != this.Values[i])
                    {
                        equals = false;
                    }
                }
            }
            return(equals);
        }
Пример #11
0
        private static PuzzleState getCurrentState()
        {
            GemPuzzleForm oGemPuzzleForm;
            PuzzleState   state;

            int[] currentArray = new int[Constants.InvisibleValue];
            oGemPuzzleForm = GemPuzzleForm.getInstance();
            oGemPuzzleForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
            {
                for (int i = Constants.MinimumValue; i < Constants.InvisibleValue; i++)
                {
                    currentArray[i] = oGemPuzzleForm.gemButtons[i].Value;
                }
            }));
            state = new PuzzleState(currentArray);
            return(state);
        }
Пример #12
0
        private static PuzzleState getBestNodeFromOpenList()
        {
            PuzzleState bestState;
            int         index = 0;

            if (Solver.OpenList.Count > 1)
            {
                for (int i = 1; i < Solver.OpenList.Count; i++)
                {
                    if ((Solver.OpenList[i].GetFofN()) < Solver.OpenList[index].GetFofN())
                    {
                        index = i;
                    }
                }
            }
            bestState = new PuzzleState(Solver.OpenList[index]);
            Solver.OpenList.RemoveAt(index);
            return(bestState);
        }
Пример #13
0
 private static void updateTiles(PuzzleState state)
 {
     GemPuzzleForm.getInstance().Invoke(new System.Windows.Forms.MethodInvoker(() =>
     {
         for (int j = Constants.MinimumValue; j < Constants.InvisibleValue; j++)
         {
             GemPuzzleForm.getInstance().gemButtons[j].Value = state.Values[j];
         }
     }));
 }
Пример #14
0
        private static void shuffleTiles()
        {
            GemPuzzleForm oGemPuzzleForm = GemPuzzleForm.getInstance();

            Solver.StartNode = Solver.getCurrentState();
            for (int i = 0; i < 50; i++)
            {
                Solver.StartNode = PuzzleState.SetNextStateRandomly(Solver.StartNode);
                Solver.updateTiles(Solver.StartNode);
                Thread.Sleep(100);
            }
        }
Пример #15
0
 private static int searchInList(List<PuzzleState> list, PuzzleState state)
 {
     int index = -1;
     for (int i = 0; (i < list.Count) && (index == -1); i++)
     {
         if (list[i].IsEqualTo(state))
         {
             index = i;
         }
     }
     return index;
 }
Пример #16
0
 private static void main()
 {
     while (true)
     {
         switch (Solver.Action)
         {
             case Actions.Shuffling:
                 Solver.shuffleTiles();
                 Solver.Action = Actions.None;
                 break;
             case Actions.Solving:
                 Solver.findSolution();
                 Solver.Action = Actions.Solved;
                 break;
             case Actions.Solved:
                 GemPuzzleForm.getInstance().Invoke(new System.Windows.Forms.MethodInvoker(() =>
                 {
                     GemPuzzleForm.getInstance().Moves.Text = "Total Moves: " + (Solver.GoalNode.PreviousMoves.Count - 1).ToString();
                 }));
                 Solver.SolutionMoves = new byte[Solver.GoalNode.PreviousMoves.Count];
                 Solver.GoalNode.PreviousMoves.CopyTo(Solver.SolutionMoves);
                 Solver.Position = 0;
                 Solver.Action = Actions.Explore;
                 break;
             case Actions.GoToStart:
                 PuzzleState state;
                 if (Solver.Position > 0)
                 {
                     state = Solver.getCurrentState();
                     while (Solver.Position > 0)
                     {
                         state = new PuzzleState(state, Solver.SolutionMoves[--Solver.Position]);
                         Solver.updateTiles(state);
                         Thread.Sleep(100);
                     }
                 }
                 Solver.Action = Actions.Waiting;
                 break;
             case Actions.GoBackward:
                 if (Solver.Position > 0)
                 {
                     state = Solver.getCurrentState();
                     state = new PuzzleState(state, Solver.SolutionMoves[--Solver.Position]);
                     Solver.updateTiles(state);
                 }
                 Solver.Action = Actions.Waiting;
                 break;
             case Actions.Explore:
                 Solver.explore(500);
                 Solver.Action = Actions.Waiting;
                 break;
             case Actions.GoForward:
                 if (Solver.Position < (Solver.SolutionMoves.Length - 1))
                 {
                     state = Solver.getCurrentState();
                     state = new PuzzleState(state, Solver.SolutionMoves[++Solver.Position]);
                     Solver.updateTiles(state);
                 }
                 Solver.Action = Actions.Waiting;
                 break;
             case Actions.GoToEnd:
                 Solver.explore(100);
                 Solver.Action = Actions.Waiting;
                 break;
             default:
                 // Do nothing.
                 break;
         }
     }
 }
Пример #17
0
 private static PuzzleState getCurrentState()
 {
     GemPuzzleForm oGemPuzzleForm;
     PuzzleState state;
     int[] currentArray = new int[Constants.InvisibleValue];
     oGemPuzzleForm = GemPuzzleForm.getInstance();
     oGemPuzzleForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
     {
         for (int i = Constants.MinimumValue; i < Constants.InvisibleValue; i++)
         {
             currentArray[i] = oGemPuzzleForm.gemButtons[i].Value;
         }
     }));
     state = new PuzzleState(currentArray);
     return state;
 }
Пример #18
0
 private static PuzzleState getBestNodeFromOpenList()
 {
     PuzzleState bestState;
     int index = 0;
     if (Solver.OpenList.Count > 1)
     {
         for (int i = 1; i < Solver.OpenList.Count; i++)
         {
             if ((Solver.OpenList[i].GetFofN()) < Solver.OpenList[index].GetFofN())
             {
                 index = i;
             }
         }
     }
     bestState = new PuzzleState(Solver.OpenList[index]);
     Solver.OpenList.RemoveAt(index);
     return bestState;
 }
Пример #19
0
        /// <summary>
        /// Algorithm A*
        /// f(n) = h(n) + g(n).
        /// Where:
        /// n: is the current state.
        /// f: is the function that decides which state is going to be explored.
        /// h: is the heuristic (the distance from the current state to the goal state.
        /// g: is the cost to get from the start state to the current state n.
        /// </summary>
        private static void findSolution()
        {
            List<PuzzleState> successorNodes;
            int index;
            bool notIgnore;
            int nodesVisited = 0;
            // 1. Create a node containing the goal state (Solver.GoalNode).
            // 2. Create a node containing the start state (Solver.StartNode)
            Solver.StartNode = Solver.getCurrentState();
            // 3. Put the start node on the OpenList.
            Solver.OpenList.Add(Solver.StartNode);
            // 4. While OpenList is not empty.
            while (Solver.OpenList.Count > 0)
            {
                // 5. Get the node off the open list with the lowest f and call it current node (Solver.CurrentNode).
                Solver.CurrentNode = Solver.getBestNodeFromOpenList();
                // 6. If Solver.CurrentNode is the same state as Solver.GoalState we have found the solution; break from the while loop
                if (Solver.GoalNode.IsEqualTo(Solver.CurrentNode))
                {
                    Solver.GoalNode = new PuzzleState(Solver.CurrentNode);
                    Solver.CurrentNode = null;
                    nodesVisited = Solver.ClosedList.Count + 1;
                    Solver.OpenList.Clear();
                    Solver.ClosedList.Clear();
                }
                else
                {
                    // 7. Generate each state that can come after CurrentNode.
                    successorNodes = new List<PuzzleState>(Solver.CurrentNode.ValidMoves.Length);
                    for (int i = 0; i < Solver.CurrentNode.ValidMoves.Length; i++)
                    {
                        successorNodes.Add(new PuzzleState(Solver.CurrentNode, Solver.CurrentNode.ValidMoves[i]));
                    }

                    foreach (PuzzleState state in successorNodes)
                    { // 8. For each successor node of current node:
                        // 9. If successor node is on the Open List but the existing one is a good or better, then disscard this successor and continue.
                        notIgnore = true;
                        index = Solver.searchInList(Solver.OpenList, state);
                        if (index > -1)
                        {
                            if (state.GetFofN() < Solver.OpenList[index].GetFofN())
                            {
                                // 9.1 Remove occurrances of successor node from Open List.
                                Solver.OpenList.RemoveAt(index);
                            }
                            else
                            {
                                notIgnore = false;
                            }
                        }
                        // 10. If successor node is on the Closed List but the existing one is a good or better, then disscard this successor and continue.
                        index = Solver.searchInList(Solver.ClosedList, state);
                        if (index > -1)
                        {
                            if (state.GetFofN() < Solver.ClosedList[index].GetFofN())
                            {
                                // 10.1 Remove occurrances of successor node from Closed List.
                                Solver.ClosedList.RemoveAt(index);
                            }
                            else
                            {
                                notIgnore = false;
                            }
                        }
                        // 11. Add successor node to the Open List.
                        if (notIgnore)
                        {
                            Solver.OpenList.Add(state);
                        }
                    }
                    // 14. Add CurrentNode to the Closed List.
                    Solver.ClosedList.Add(new PuzzleState(Solver.CurrentNode));
                    nodesVisited = Solver.ClosedList.Count;
                }
                GemPuzzleForm.getInstance().Invoke(new System.Windows.Forms.MethodInvoker(() =>
                {
                    GemPuzzleForm.getInstance().Nodes.Text = "Nodes Visited: " + nodesVisited.ToString();
                }));
            }
        }
Пример #20
0
 private static void explore(int delay)
 {
     GemPuzzleForm oGemPuzzleForm = GemPuzzleForm.getInstance();
     PuzzleState currentState;
     int[] tmpValues = new int[Constants.InvisibleValue];
     oGemPuzzleForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
     {
         for (int i = Constants.MinimumValue; i < Constants.InvisibleValue; i++)
         {
             tmpValues[i] = oGemPuzzleForm.gemButtons[i].Value;
         }
     }));
     currentState = new PuzzleState(tmpValues);
     while (Solver.Position < (Solver.SolutionMoves.Length - 1))
     {
         currentState = new PuzzleState(currentState, Solver.SolutionMoves[++Solver.Position]);
         Solver.updateTiles(currentState);
         Thread.Sleep(delay);
     }
     oGemPuzzleForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
     {
         oGemPuzzleForm.ControlButtons = true;
     }));
 }
Пример #21
0
        private static void main()
        {
            while (true)
            {
                switch (Solver.Action)
                {
                case Actions.Shuffling:
                    Solver.shuffleTiles();
                    Solver.Action = Actions.None;
                    break;

                case Actions.Solving:
                    Solver.findSolution();
                    Solver.Action = Actions.Solved;
                    break;

                case Actions.Solved:
                    GemPuzzleForm.getInstance().Invoke(new System.Windows.Forms.MethodInvoker(() =>
                    {
                        GemPuzzleForm.getInstance().Moves.Text = "Total Moves: " + (Solver.GoalNode.PreviousMoves.Count - 1).ToString();
                    }));
                    Solver.SolutionMoves = new byte[Solver.GoalNode.PreviousMoves.Count];
                    Solver.GoalNode.PreviousMoves.CopyTo(Solver.SolutionMoves);
                    Solver.Position = 0;
                    Solver.Action   = Actions.Explore;
                    break;

                case Actions.GoToStart:
                    PuzzleState state;
                    if (Solver.Position > 0)
                    {
                        state = Solver.getCurrentState();
                        while (Solver.Position > 0)
                        {
                            state = new PuzzleState(state, Solver.SolutionMoves[--Solver.Position]);
                            Solver.updateTiles(state);
                            Thread.Sleep(100);
                        }
                    }
                    Solver.Action = Actions.Waiting;
                    break;

                case Actions.GoBackward:
                    if (Solver.Position > 0)
                    {
                        state = Solver.getCurrentState();
                        state = new PuzzleState(state, Solver.SolutionMoves[--Solver.Position]);
                        Solver.updateTiles(state);
                    }
                    Solver.Action = Actions.Waiting;
                    break;

                case Actions.Explore:
                    Solver.explore(500);
                    Solver.Action = Actions.Waiting;
                    break;

                case Actions.GoForward:
                    if (Solver.Position < (Solver.SolutionMoves.Length - 1))
                    {
                        state = Solver.getCurrentState();
                        state = new PuzzleState(state, Solver.SolutionMoves[++Solver.Position]);
                        Solver.updateTiles(state);
                    }
                    Solver.Action = Actions.Waiting;
                    break;

                case Actions.GoToEnd:
                    Solver.explore(100);
                    Solver.Action = Actions.Waiting;
                    break;

                default:
                    // Do nothing.
                    break;
                }
            }
        }
Пример #22
0
 /// <summary>
 /// Given a state, it calculates a new state randomly.
 /// </summary>
 /// <param name="state">The state containing the next possible and valid moves.</param>
 /// <returns>A state created randomly from a given state.</returns>
 public static PuzzleState SetNextStateRandomly(PuzzleState state)
 {
     PuzzleState tmpState;
     Random nextMove = new Random(DateTime.Now.Millisecond);
     int index = nextMove.Next(0, state.ValidMoves.Length);
     tmpState = new PuzzleState(state.Values, state.ValidMoves[index]);
     return tmpState;
 }
Пример #23
0
 /// <summary>
 /// Checks if two states have the same value arrangement (the tiles).
 /// </summary>
 /// <param name="state"></param>
 /// <returns></returns>
 public bool IsEqualTo(PuzzleState state)
 {
     bool equals = false;
     if ((state.Heuristic2 == this.Heuristic2) && (state.Heuristic1 == this.Heuristic1))
     {
         equals = true;
         for (int i = Constants.MinimumValue; (i < Constants.InvisibleValue) && equals; i++)
         {
             if (state.Values[i] != this.Values[i])
             {
                 equals = false;
             }
         }
     }
     return equals;
 }