public Game(SpaceState state, SpaceState winstate, int w, int h) { this.w = w; this.h = h; currentState = state; winningState = winstate; }
public SpaceState(string blocks, SpaceState parent, string moved, string direction) { this.blocks = blocks; this.parent = parent; this.moved = moved; this.direction = direction; }
public void Undo() { if (stateHistory.Count > 0) { currentState = stateHistory.Pop(); } }
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); } }
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; }
private void SolveMethod() { isRunning = true; returnState = ps.Solve(); isRunning = false; Thread.Sleep(150); message = "Solution found\nStates Checked: " + ps.count; }
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); }
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); }
// 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(); }
// 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); }
public void NewState(SpaceState state) { stateHistory.Push(currentState); currentState = state; }
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) { } } }
// 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); }
public void NewState(SpaceState state) { stateHistory.Push(this.state); this.state = state; }