internal SudokuSolutionNode Step(SudokuSolutionNode a_node, SudokuSolutionType a_type) { if (a_node.Board.IsEmpty) { return(new SudokuSolutionNode(a_node.Board, SudokuSolutionNodeState.Unsolvable)); } if (a_node.StepMode != SudokuSolutionNodeStepMode.StepAllAlgorithms) { Debug.Assert(!a_node.Nodes.Any()); a_node.StepMode = SudokuSolutionNodeStepMode.StepSelectedAlgorithm; List <SudokuSolution> solution_nodes = SudokuSolutionTypeToSolvingFunction(a_type)(a_node.NextBoard, true); solution_nodes = SudokuSolutionNode.Consolidate(solution_nodes.Distinct().ToList()); foreach (SudokuSolution solution in solution_nodes) { if (!a_node.Nodes.Any(n => n.Solution.Equals(solution))) { a_node.AddNode(a_node.NextBoard, SudokuSolutionNodeState.Solution, solution); } } } return(a_node.Nodes.FirstOrDefault(node => node.Solution.Type == a_type)); }
public bool Test(bool a_all) { if (m_after == null) { return(false); } if (m_solution == null) { return(false); } SudokuSolutionNode node = SudokuSolutionNode.CreateRoot(m_before); if (a_all) { node.StepAll(); } else { node.Step(m_solution.Type); } SudokuSolutionNode solved_node = node.Nodes.FirstOrDefault(n => n.Solution.Equals(m_solution)); if (solved_node == null) { return(false); } return(m_after.Equals(solved_node.NextBoard)); }
public static SudokuSolutionNode CreateTree(SudokuSolutionNode a_root) { SudokuSolutionNode root = CreateRoot(a_root.Board); root.RecreateTree(a_root); return(root); }
private static void LoadNodesFromXML(XElement a_element, SudokuSolutionNode a_parent) { a_element.Element("solution_nodes").Elements().ForEach(child_element => { SudokuBoard board = SudokuBoard.LoadFromXML(child_element.Element("board")); SudokuSolutionNode child_node = a_parent.AddNode( board, (SudokuSolutionNodeState)Enum.Parse(typeof(SudokuSolutionNodeState), child_element.Attribute("state").Value), SudokuSolution.LoadFromXML(child_element.Element("solution"), board) ); LoadNodesFromXML(child_element, child_node); }); }
private void UpdateState(SudokuSolutionNode a_node, bool a_bEnd) { if (!a_node.Board.IsSolvable) { a_node.State = SudokuSolutionNodeState.Unsolvable; } else if (a_node.Board.IsSolved) { a_node.State = SudokuSolutionNodeState.Solved; } else if (a_bEnd) { a_node.State = SudokuSolutionNodeState.Unsolved; } }
private void RecreateTree(SudokuSolutionNode a_node) { if (a_node.State == SudokuSolutionNodeState.Solution) { Step(); if (a_node.Nodes.Any()) { Nodes.First().RecreateTree(a_node.Nodes.First()); } } else if ((a_node.State == SudokuSolutionNodeState.Solved) || (a_node.State == SudokuSolutionNodeState.Unsolvable) || (a_node.State == SudokuSolutionNodeState.Unsolved)) { } else if (a_node.State == SudokuSolutionNodeState.State) { if (a_node.StepMode == SudokuSolutionNodeStepMode.StepAllAlgorithms) { StepAll(); } else if (a_node.StepMode == SudokuSolutionNodeStepMode.StepFirstSolution) { Step(); } else if (a_node.StepMode == SudokuSolutionNodeStepMode.StepSelectedAlgorithm) { Step(a_node.Nodes.First().Solution.Type); } else if (a_node.StepMode == SudokuSolutionNodeStepMode.StepNone) { return; } SudokuSolutionNode sol1 = a_node.Nodes.FirstOrDefault(n => n.Nodes.Any()); SudokuSolutionNode sol2 = null; if (sol1 != null) { sol2 = Nodes.FirstOrDefault(n => n.Solution.Equals(sol1.Solution)); } if ((sol1 != null) && (sol2 != null)) { sol2.RecreateTree(sol1); } } }
public void RemoveNodes(SudokuSolutionNode a_except) { if (!m_nodes.Contains(a_except)) { a_except = null; } m_nodes.Clear(); if (a_except != null) { m_nodes.Add(a_except); } m_step_mode = SudokuSolutionNodeStepMode.StepSelectedAlgorithm; }
private static SudokuSolutionNode LoadFromXML(XElement a_element) { try { SudokuSolutionNode node = SudokuSolutionNode.CreateRoot(SudokuBoard.LoadFromXML(a_element.Element("board"))); Debug.Assert(a_element.Element("solution").IsEmpty); LoadNodesFromXML(a_element, node); return(node); } catch { return(null); } }
public override bool Equals(object a_obj) { if (a_obj == null) { return(false); } if (ReferenceEquals(this, a_obj)) { return(true); } SudokuSolutionNode node = a_obj as SudokuSolutionNode; if (node == null) { return(false); } if (m_state != node.m_state) { return(false); } if (!m_board.Equals(node.m_board)) { return(false); } if ((m_solution == null) && (node.m_solution == null)) { return(true); } if ((m_solution == null) ^ (node.m_solution == null)) { return(false); } if (m_solution.Equals(node.m_solution)) { return(true); } return(false); }
internal SudokuSolutionNode Solve(SudokuSolutionNode a_node) { if (a_node.Board.IsEmpty) { return(new SudokuSolutionNode(a_node.Board, SudokuSolutionNodeState.Unsolvable)); } for (;;) { if ((a_node.State == SudokuSolutionNodeState.Solved) || (a_node.State == SudokuSolutionNodeState.Unsolvable) || (a_node.State == SudokuSolutionNodeState.Unsolved)) { return(a_node); } a_node = Step(a_node); } }
public static SudokuSolutionNode LoadFromFile(string a_fileName) { try { using (FileStream file_stream = new FileStream(a_fileName, FileMode.Open, FileAccess.Read)) { using (GZipStream gzip_stream = new GZipStream(file_stream, CompressionMode.Decompress)) { using (StreamReader stream_reader = new StreamReader(gzip_stream, Encoding.ASCII)) { return(SudokuSolutionNode.LoadFromXML(XElement.Load(stream_reader))); } } } } catch { return(null); } }
internal SudokuSolutionNode Step(SudokuSolutionNode a_node) { if (a_node.Board.IsEmpty) { return(new SudokuSolutionNode(a_node.Board, SudokuSolutionNodeState.Unsolvable)); } if ((a_node.StepMode != SudokuSolutionNodeStepMode.StepFirstSolution) && (a_node.StepMode != SudokuSolutionNodeStepMode.StepAllAlgorithms)) { a_node.StepMode = SudokuSolutionNodeStepMode.StepFirstSolution; if (a_node.State == SudokuSolutionNodeState.State) { List <SudokuSolution> solutions = null; if (a_node.NextBoard.IsSolvable) { // PLINQ solutions = (from func in m_simple_funcs.Concat(m_complex_funcs) select func(a_node.NextBoard, false)).FirstOrDefault(sols => sols.Count > 0); } if (solutions != null) { solutions = SudokuSolutionNode.Consolidate(RemoveOverlapped(solutions.Distinct().ToList())); if (solutions.Count == 0) { solutions = null; } } if (solutions != null) { foreach (SudokuSolution solution in solutions) { SudokuSolutionNode node = a_node.AddNode(a_node.NextBoard, SudokuSolutionNodeState.Solution, solution); node = node.AddNode(node.NextBoard, SudokuSolutionNodeState.State); UpdateState(node, false); } a_node = a_node.Nodes.First().Nodes.First(); } else { UpdateState(a_node, true); } } else { a_node = a_node.AddNode(a_node.NextBoard, SudokuSolutionNodeState.State); UpdateState(a_node, false); } } else { if (a_node.Nodes.Any()) { a_node = a_node.Nodes.First(); } else { UpdateState(a_node, true); } } return(a_node); }
internal void StepAll(SudokuSolutionNode a_node) { if (a_node.StepMode == SudokuSolutionNodeStepMode.StepAllAlgorithms) { return; } a_node.StepMode = SudokuSolutionNodeStepMode.StepAllAlgorithms; if ((a_node.State == SudokuSolutionNodeState.Solved) || (a_node.State == SudokuSolutionNodeState.Unsolvable) || (a_node.State == SudokuSolutionNodeState.Unsolved)) { return; } if (a_node.Board.IsEmpty) { return; } if (a_node.State == SudokuSolutionNodeState.Solution) { if (!a_node.Nodes.Any()) { a_node = a_node.AddNode(a_node.NextBoard, SudokuSolutionNodeState.State); UpdateState(a_node, false); } } else { ConcurrentBag <SudokuSolution> solution_nodes = new ConcurrentBag <SudokuSolution>(); Parallel.ForEach(m_simple_funcs, func => { List <SudokuSolution> list = func(a_node.NextBoard, true); foreach (var sol in list) { solution_nodes.Add(sol); } }); if (solution_nodes.Count == 0) { Parallel.ForEach(m_complex_funcs, func => { List <SudokuSolution> list = func(a_node.NextBoard, true); foreach (var sol in list) { solution_nodes.Add(sol); } }); } List <SudokuSolution> solution_nodes_1 = SudokuSolutionNode.Consolidate(solution_nodes.Distinct().ToList()); foreach (SudokuSolution solution in solution_nodes_1) { if (!a_node.Nodes.Any(n => n.Solution.Equals(solution))) { a_node.AddNode(a_node.NextBoard, SudokuSolutionNodeState.Solution, solution); } } } }
internal SudokuSolutionNode AddNode(SudokuSolutionNode a_node) { a_node.m_parent = this; m_nodes.Add(a_node); return(a_node); }