private BoardState puzzleDiver(BoardState b, int maxThreshhold) { // Gone as far as possible in this dive if (b.moves.Count + b.distance >= maxThreshhold || IsSolved(b.positions)) { return b; } List<int> moves = GetMoves(b.positions, b.moveTo); foreach (int m in moves) { if (buttonTimer.Enabled) { List<int> newMoves = AddMove(b.moves, m); int[] newPositions = ApplyMove(b.positions, m); int moveTo = GetMoveTo(b.positions); BoardState result = puzzleDiver(new BoardState(newMoves, newPositions, moveTo, GetDistance(newPositions)), maxThreshhold); if (IsSolved(result.positions)) { return result; } } } return b; }
private void solvePuzzle() { List<int> moves = new List<int>(); bool done = false; int[] positions = GetPositions(); int maxThreshold = GetDistance(positions); BoardState currentState = new BoardState(moves, positions, -1, GetDistance(positions)); while (buttonTimer.Enabled) { BoardState completedState = puzzleDiver(currentState, maxThreshold); if (IsSolved(completedState.positions)) { foreach (int m in completedState.moves) { for (int i = 0; i < pieces; i++) { Tile t = tiles[i]; if (t.Row * cols + t.Col == m) { t.Invoke(new MethodInvoker(delegate { MovePiece(t); })); Thread.Sleep(100); break; } } } string message = "Puzzle optimally solved in " + completedState.moves.Count + " moves."; MessageBox.Show(message, "Done"); buttonTimer.Stop(); solveButton.Text = "Solve"; done = true; break; } maxThreshold++; } if (!done) { string message = "I can not solve this puzzle in less than " + timeLimit + " seconds."; MessageBox.Show(message, "Failed"); } }