예제 #1
0
 public Game(SpaceState state, SpaceState winstate, int w, int h)
 {
     this.w       = w;
     this.h       = h;
     currentState = state;
     winningState = winstate;
 }
예제 #2
0
 public SpaceState(string blocks, SpaceState parent, string moved, string direction)
 {
     this.blocks    = blocks;
     this.parent    = parent;
     this.moved     = moved;
     this.direction = direction;
 }
예제 #3
0
 public void Undo()
 {
     if (stateHistory.Count > 0)
     {
         currentState = stateHistory.Pop();
     }
 }
예제 #4
0
        private void solveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (game == null)
            {
                return;
            }

            moves.Clear();

            SolverWindow sw = new SolverWindow();
            SpaceState   sp = sw.SolveGame(game);

            if (sp != null)
            {
                while (sp.parent != null)
                {
                    moves.Add(new Tuple <string, int>(sp.moved, int.Parse(sp.direction)));
                    sp = sp.parent;
                }

                moves.Reverse();

                try { ml.Close(); }
                catch (Exception ex) { }

                ml = new MovesList();
                ml.ShowMoves(moves);
            }
        }
예제 #5
0
 public Game(SpaceState state, SpaceState stage, int w, int h, char goalBlock)
 {
     this.w         = w;
     this.h         = h;
     this.state     = state;
     this.stage     = stage;
     this.goalBlock = goalBlock;
 }
예제 #6
0
        private void SolveMethod()
        {
            isRunning   = true;
            returnState = ps.Solve();
            isRunning   = false;

            Thread.Sleep(150);

            message = "Solution found\nStates Checked: " + ps.count;
        }
예제 #7
0
        public bool IsWin(SpaceState state)
        {
            for (int i = 0; i < game.stage.blocks.Count(); i++)
            {
                if ((game.stage.blocks[i] == '0' || game.stage.blocks[i] == '-') && state.blocks[i] == game.goalBlock)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #8
0
        public bool IsWin(SpaceState currentState)
        {
            for (int i = 0; i < winningState.blocks.Count(); i++)
            {
                if (winningState.blocks[i] != '0' && winningState.blocks[i] != currentState.blocks[i])
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #9
0
        // Overloaded constructor.
        public PuzzleSolver(Game game)
        {
            // Test if a game is playing.
            if (game == null)
            {
                return;
            }

            // Set width and height of the puzzle.
            w = game.w;
            h = game.h;

            // Set the starting state of the puzzle.
            startState   = game.currentState;
            winningState = game.winningState;

            // Analyze the blocks present in the puzzle.
            AnalyzeBlocks();
        }
예제 #10
0
        // Method for searching breadth fisrt for solution.
        public SpaceState Solve()
        {
            // Reset count.
            count = 0;

            // Add first state in open list.
            open.Add(game.state);

            // Adding fist state in lookup list.
            lookup.Add(Simplify(ref game.state.blocks));

            List <char> moveBlocks = new List <char>();

            moveBlocks.AddRange(game.state.blocks.Distinct());
            moveBlocks.Remove(' ');

            // While loop to search for solution.
            while (open.Count > 0)
            {
                // Test first element on open stack.
                SpaceState test = open.First();
                // Remove element from stack.
                open.RemoveAt(0);

                // Test for winning condition.
                if (IsWin(test))
                {
                    return(test);
                }

                // Increment count.
                count++;

                for (int i = 0; i < moveBlocks.Count; i++)
                {
                    List <int> oldIndexes = new List <int>();
                    for (int oi = 0; oi < test.blocks.Length; oi++)
                    {
                        if (test.blocks[oi] == moveBlocks[i])
                        {
                            oldIndexes.Add(oi);
                        }
                    }

                    int diff = 0;
                    for (int iteration = 0; iteration < 4; iteration++)
                    {
                        #region Move

                        // Set diff for movement.
                        if (iteration == 0)
                        {
                            diff = -game.w;
                        }
                        else if (iteration == 1)
                        {
                            diff = +game.w;
                        }
                        else if (iteration == 2)
                        {
                            diff = -1;
                        }
                        else if (iteration == 3)
                        {
                            diff = +1;
                        }

                        bool valid = true;

                        // Create new indexes.
                        List <int> newIndexes = new List <int>();
                        for (int oi = 0; oi < oldIndexes.Count; oi++)
                        {
                            newIndexes.Add(oldIndexes[oi] + diff);
                        }

                        // Test against stage.
                        for (int ni = 0; valid && ni < newIndexes.Count; ni++)
                        {
                            if (game.stage.blocks[newIndexes[ni]] == '#')
                            {
                                valid = false;
                            }
                            else if (game.stage.blocks[newIndexes[ni]] == '-' && moveBlocks[i] != game.goalBlock)
                            {
                                valid = false;
                            }
                        }

                        // Test new indexes.
                        for (int ni = 0; valid && ni < newIndexes.Count; ni++)
                        {
                            char mb = moveBlocks[i];
                            char tb = test.blocks[newIndexes[ni]];

                            if (!(test.blocks[newIndexes[ni]] == ' ' || test.blocks[newIndexes[ni]] == moveBlocks[i]))
                            {
                                valid = false;
                            }
                        }

                        // Apply move and add to list.
                        if (valid)
                        {
                            string newBlocks = String.Copy(test.blocks);
                            for (int oi = 0; oi < oldIndexes.Count; oi++)
                            {
                                newBlocks = newBlocks.Remove(oldIndexes[oi], 1);
                                newBlocks = newBlocks.Insert(oldIndexes[oi], " ");
                            }
                            for (int ni = 0; ni < newIndexes.Count; ni++)
                            {
                                newBlocks = newBlocks.Remove(newIndexes[ni], 1);
                                newBlocks = newBlocks.Insert(newIndexes[ni], moveBlocks[i].ToString());
                            }

                            SpaceState sp = new SpaceState(newBlocks, test, moveBlocks[i].ToString(), iteration.ToString());

                            if (!(lookup.Contains(Simplify(ref newBlocks))))
                            {
                                open.Add(sp);
                                lookup.Add(Simplify(ref newBlocks));
                            }
                        }

                        #endregion
                    }
                }
            }

            return(game.state);
        }
예제 #11
0
 public void NewState(SpaceState state)
 {
     stateHistory.Push(currentState);
     currentState = state;
 }
예제 #12
0
        private void MoveBlocks(int direction)
        {
            if (game == null)
            {
                return;
            }

            List <int> oldIndexes = new List <int>();

            for (int oi = 0; oi < game.currentState.blocks.Length; oi++)
            {
                if (game.currentState.blocks[oi] == game.selectedBlock)
                {
                    oldIndexes.Add(oi);
                }
            }

            bool valid = true;

            // Test old indexes.
            for (int oi = 0; oi < oldIndexes.Count; oi++)
            {
                if (direction == 0 && !(oldIndexes[oi] / game.w > 0))
                {
                    valid = false; break;
                }
                if (direction == 1 && !(oldIndexes[oi] / game.w < game.h - 1))
                {
                    valid = false; break;
                }
                if (direction == 2 && !(oldIndexes[oi] % game.w > 0))
                {
                    valid = false; break;
                }
                if (direction == 3 && !(oldIndexes[oi] % game.w < game.w - 1))
                {
                    valid = false; break;
                }
            }

            // Set diff for movement.
            int diff = 1;

            if (direction == 0)
            {
                diff = -game.w;
            }
            else if (direction == 1)
            {
                diff = +game.w;
            }
            else if (direction == 2)
            {
                diff = -1;
            }
            else if (direction == 3)
            {
                diff = +1;
            }

            // Create new indexes.
            List <int> newIndexes = new List <int>();

            for (int oi = 0; oi < oldIndexes.Count; oi++)
            {
                newIndexes.Add(oldIndexes[oi] + diff);
            }

            // Test new  indexes.
            for (int ni = 0; valid && ni < newIndexes.Count; ni++)
            {
                if (!(game.currentState.blocks[newIndexes[ni]] == '0' || game.currentState.blocks[newIndexes[ni]] == game.selectedBlock))
                {
                    valid = false;
                }
            }

            // Apply move and add to list.
            if (valid)
            {
                string newBlocks = String.Copy(game.currentState.blocks);
                for (int oi = 0; oi < oldIndexes.Count; oi++)
                {
                    newBlocks = newBlocks.Remove(oldIndexes[oi], 1);
                    newBlocks = newBlocks.Insert(oldIndexes[oi], "0");
                }
                for (int ni = 0; ni < newIndexes.Count; ni++)
                {
                    newBlocks = newBlocks.Remove(newIndexes[ni], 1);
                    newBlocks = newBlocks.Insert(newIndexes[ni], game.selectedBlock.ToString());
                }

                SpaceState sp = new SpaceState(newBlocks, null, "", "");
                game.NewState(sp);

                if (game.IsWin())
                {
                    MessageBox.Show("You have won the game. It took you " + game.stateHistory.Count + " moves.");
                }

                try { ml.MoveMade(new Tuple <string, int>(game.selectedBlock.ToString(), direction)); }
                catch (Exception e) { }
            }
        }
예제 #13
0
        // Method for searching breadth fisrt for solution.
        public SpaceState Solve()
        {
            // Reset count.
            count = 0;

            // Populate lookup lists.
            for (int i = 0; i < 1048575; i++)
            {
                lookup.Add(new List <string>());
            }

            // Add first state in open list.
            open.Add(startState);

            // Index of lookup list to store string.
            int aIndex = int.Parse(Simplify(ref startState.blocks).Substring(0, 5), System.Globalization.NumberStyles.HexNumber);

            // Adding fist state in lookup list.
            lookup[aIndex].Add(Simplify(ref startState.blocks).Substring(5));

            // While loop to search for solution.
            while (open.Count > 0)
            {
                // Test first element on open stack.
                SpaceState test = open.First();
                // Remove element from stack.
                open.RemoveAt(0);

                // Test for winning condition.
                if (IsWin(test))
                {
                    return(test);
                }

                // Increment count.
                count++;

                List <int>  zeroBlocks = new List <int>();
                List <char> moveBlocks = new List <char>();

                for (int i = 0; i < test.blocks.Length; i++)
                {
                    if (test.blocks[i] == '0')
                    {
                        zeroBlocks.Add(i);
                        if (i / w > 0 && !moveBlocks.Contains(test.blocks[i - w]))
                        {
                            moveBlocks.Add(test.blocks[i - w]);
                        }
                        if (i / w < h - 1 && !moveBlocks.Contains(test.blocks[i + w]))
                        {
                            moveBlocks.Add(test.blocks[i + w]);
                        }
                        if (i % w > 0 && !moveBlocks.Contains(test.blocks[i - 1]))
                        {
                            moveBlocks.Add(test.blocks[i - 1]);
                        }
                        if (i % w < w - 1 && !moveBlocks.Contains(test.blocks[i + 1]))
                        {
                            moveBlocks.Add(test.blocks[i + 1]);
                        }
                    }
                }

                moveBlocks.Remove('0');

                for (int i = 0; i < moveBlocks.Count; i++)
                {
                    List <int> oldIndexes = new List <int>();
                    for (int oi = 0; oi < test.blocks.Length; oi++)
                    {
                        if (test.blocks[oi] == moveBlocks[i])
                        {
                            oldIndexes.Add(oi);
                        }
                    }

                    int diff = 0;
                    for (int iteration = 0; iteration < 4; iteration++)
                    {
                        #region Move

                        bool valid = true;
                        // Test old indexes.
                        for (int oi = 0; oi < oldIndexes.Count; oi++)
                        {
                            if (iteration == 0 && !(oldIndexes[oi] / w > 0))
                            {
                                valid = false; break;
                            }
                            if (iteration == 1 && !(oldIndexes[oi] / w < h - 1))
                            {
                                valid = false; break;
                            }
                            if (iteration == 2 && !(oldIndexes[oi] % w > 0))
                            {
                                valid = false; break;
                            }
                            if (iteration == 3 && !(oldIndexes[oi] % w < w - 1))
                            {
                                valid = false; break;
                            }
                        }

                        // Set diff for movement.
                        if (iteration == 0)
                        {
                            diff = -w;
                        }
                        else if (iteration == 1)
                        {
                            diff = +w;
                        }
                        else if (iteration == 2)
                        {
                            diff = -1;
                        }
                        else if (iteration == 3)
                        {
                            diff = +1;
                        }

                        // Create new indexes.
                        List <int> newIndexes = new List <int>();
                        for (int oi = 0; oi < oldIndexes.Count; oi++)
                        {
                            newIndexes.Add(oldIndexes[oi] + diff);
                        }

                        // Test new  indexes.
                        for (int ni = 0; valid && ni < newIndexes.Count; ni++)
                        {
                            if (!(test.blocks[newIndexes[ni]] == '0' || test.blocks[newIndexes[ni]] == moveBlocks[i]))
                            {
                                valid = false;
                            }
                        }

                        // Apply move and add to list.
                        if (valid)
                        {
                            string newBlocks = String.Copy(test.blocks);
                            for (int oi = 0; oi < oldIndexes.Count; oi++)
                            {
                                newBlocks = newBlocks.Remove(oldIndexes[oi], 1);
                                newBlocks = newBlocks.Insert(oldIndexes[oi], "0");
                            }
                            for (int ni = 0; ni < newIndexes.Count; ni++)
                            {
                                newBlocks = newBlocks.Remove(newIndexes[ni], 1);
                                newBlocks = newBlocks.Insert(newIndexes[ni], moveBlocks[i].ToString());
                            }

                            int        cIndex2 = int.Parse(Simplify(ref newBlocks).Substring(0, 5), System.Globalization.NumberStyles.HexNumber);
                            SpaceState sp      = new SpaceState(newBlocks, test, moveBlocks[i].ToString(), iteration.ToString());

                            if (!(lookup[cIndex2].Contains(Simplify(ref newBlocks).Substring(5))))
                            {
                                open.Add(sp);
                                lookup[cIndex2].Add(Simplify(ref newBlocks).Substring(5));
                            }
                        }

                        #endregion
                    }
                }
            }

            return(startState);
        }
예제 #14
0
 public void NewState(SpaceState state)
 {
     stateHistory.Push(this.state);
     this.state = state;
 }