public Path ToPath() { Path res = new Path(startPosition); foreach (char c in steps) { switch(Char.ToLower(c)) { case ('u'): res.Add(Direction.Up); break; case ('d'): res.Add(Direction.Down); break; case ('l'): res.Add(Direction.Left); break; case ('r'): res.Add(Direction.Right); break; } } return res; }
/// <summary> /// Generate the solution from the solver tree /// </summary> /// <returns></returns> private List<Solution> BuildSolutionPath() { List<INode<SolverNode>> solutions = evaluator.Solutions; if (solutions == null || solutions.Count == 0) { solutions = reverseEvaluator.Solutions; } if (solutions == null || solutions.Count == 0) { // No solution forward or reverse throw new Exception("A solution was expected, but not found"); } List<Solution> results = new List<Solution>(); foreach (INode<SolverNode> node in solutions) { if (node.Data.Status == SolverNodeStates.Solution) { if (node.Data.IsForward) { Solution simpleForward = new Solution(PuzzleMap, Map.Player); simpleForward.Set(strategy.BuildPath(node.Data)); simpleForward.Details = new GenericDescription(); simpleForward.Details.Name = "SokoSolve Solution"; simpleForward.Details.Author = new GenericDescriptionAuthor(); simpleForward.Details.Date = DateTime.Now; simpleForward.Details.DateSpecified = true; // Build a description SolverLabelList labels = Stats.GetDisplayData(); labels.Add("Machine", string.Format("{0} Running {1}.", DebugHelper.GetCPUDescription(), Environment.OSVersion)); simpleForward.Details.Description = labels.ToString(); results.Add(simpleForward); } else { Solution simpleForward = new Solution(PuzzleMap, Map.Player); simpleForward.Set(reverseStrategy.BuildPath(node.Data)); simpleForward.Details = new GenericDescription(); simpleForward.Details.Name = "SokoSolve Solution"; simpleForward.Details.Author = new GenericDescriptionAuthor(); simpleForward.Details.Date = DateTime.Now; simpleForward.Details.DateSpecified = true; // Build a description SolverLabelList labels = Stats.GetDisplayData(); labels.Add("Machine", string.Format("{0} Running {1}.", DebugHelper.GetCPUDescription(), Environment.OSVersion)); simpleForward.Details.Description = labels.ToString(); results.Add(simpleForward); } } if (node.Data.Status == SolverNodeStates.SolutionChain) { if (node.Data.ChainSolutionLink == null) throw new InvalidDataException("ChainSolutionLink must be set"); SolverNode forward = null; SolverNode reverse = null; if (node.Data.IsForward) { forward = node.Data; reverse = node.Data.ChainSolutionLink; } else { forward = node.Data.ChainSolutionLink; reverse = node.Data; } // Build the paths Path forwardPortion = strategy.BuildPath(forward); Path reversePortion = this.reverseStrategy.BuildPath(reverse); debugReport.AppendLabel("Forward Chain", "[{0}->{1}] links to {2}", forward.PlayerPositionBeforeMove,forward.PlayerPosition, forward.ChainSolutionLink.PlayerPosition); debugReport.AppendLabel("Reverse Chain", "[{0}->{1}] links to {2}", reverse.PlayerPositionBeforeMove, reverse.PlayerPosition, reverse.ChainSolutionLink.PlayerPosition); debugReport.AppendLabel("Forward", string.Format("[{0}] {1}", forwardPortion.Count, StringHelper.Join(forwardPortion.MovesAsPosition, null, ", "))); debugReport.AppendLabel("Reverse", string.Format("[{0}] {1}", reversePortion.Count, StringHelper.Join(reversePortion.MovesAsPosition, null, ", "))); Path fullPath = new Path(Map.Player); fullPath.Add(forwardPortion); fullPath.Add(reversePortion); // Join them Solution solution = new Solution(PuzzleMap, Map.Player); solution.Set(fullPath); solution.Details = new GenericDescription(); solution.Details.Name = "SokoSolve Solution"; solution.Details.Author = new GenericDescriptionAuthor(); solution.Details.Date = DateTime.Now; solution.Details.DateSpecified = true; // Build a description SolverLabelList labels = Stats.GetDisplayData(); labels.Add("Machine", string.Format("{0} Running {1}.", DebugHelper.GetCPUDescription(), Environment.OSVersion)); solution.Details.Description = labels.ToString(); results.Add(solution); } } // Sanity check string firsterror; foreach (Solution solution in results) { if (!solution.Test(map, out firsterror)) throw new Exception("Sanity Check Failed. Solution is not valid: "+firsterror); } return results; }