public bool Equals(ProfessorChecker other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return other._id.Equals(_id); }
private IEnumerable<ProfessorChecker> FindMatchingChecker(ProfessorChecker[] solution, int solutionIndex, ProfessorChecker[] checkers) { var unused = checkers.Except(solution).ToList(); var thisIndex = solutionIndex + 1; foreach (var unusedProfessorChecker in unused) { for (int i = 0; i < 4; i++) { if (thisIndex < 4) //first row { var leftChecker = solution[solutionIndex]; if (leftChecker.Right.Color == unusedProfessorChecker.Left.Color && leftChecker.Right.BodyPart != unusedProfessorChecker.Left.BodyPart) { yield return unusedProfessorChecker.Clone(); } } else if (thisIndex % 4 == 0) //first column, in any other row { var topChecker = solution[thisIndex - 4]; if (topChecker.Bottom.Color == unusedProfessorChecker.Top.Color && topChecker.Bottom.BodyPart != unusedProfessorChecker.Top.BodyPart) { yield return unusedProfessorChecker.Clone(); } } else //2nd-4th column in 2nd-4th row { var leftChecker = solution[thisIndex - 1]; var topChecker = solution[thisIndex - 4]; if (leftChecker.Right.Color == unusedProfessorChecker.Left.Color && leftChecker.Right.BodyPart != unusedProfessorChecker.Left.BodyPart && topChecker.Bottom.Color == unusedProfessorChecker.Top.Color && topChecker.Bottom.BodyPart != unusedProfessorChecker.Top.BodyPart) { yield return unusedProfessorChecker.Clone(); } } unusedProfessorChecker.TurnRight(); } } }
public IEnumerable<ProfessorChecker[]> Solve() { var bag = new ConcurrentBag<ProfessorChecker[]>(); _checkers.AsParallel().ForAll(checker => { var checkers = _checkers.Select(c => c.Clone()).ToArray(); for (int i = 0; i < 4; i++) { var board = new ProfessorChecker[16]; board[0] = checker; var solutions = BuildSolutionRecursively(board, 0, checkers).ToList(); foreach (var solution in solutions) { bag.Add(solution); } checker.TurnRight(); } }); return bag; }
private IEnumerable<ProfessorChecker[]> BuildSolutionRecursively(ProfessorChecker[] board, int solutionIndex, ProfessorChecker[] checkers) { var nextIndex = solutionIndex + 1; var matchingCheckers = FindMatchingChecker(board, solutionIndex, checkers).ToList(); foreach (var nextChecker in matchingCheckers) { board[nextIndex] = nextChecker; if (nextIndex == 15) { yield return board.Select(pc => pc.Clone()).ToArray(); } if (nextIndex < 15) { foreach (var solution in BuildSolutionRecursively(board, nextIndex, checkers)) { yield return solution; } } board[nextIndex] = null; } }
public ProfessorGameSolver(ProfessorChecker[] checkers) { if (checkers.Length != 16) throw new ArgumentOutOfRangeException("checkers"); _checkers = checkers; }