public override Move Execute() { var possiblesRemoved = new List <Move>(); var possibles = _engine.possibles; var values = _engine.values; while (true) { for (int i = 0; i < 9; i++) { var dict = new Dictionary <int, int>(); var indexes = new Dictionary <int, List <int> >(); for (int j = 0; j < 9; j++) { if (values[i, j] > 0) { continue; } foreach (int number in possibles[i, j]) { if (!dict.ContainsKey(number)) { dict[number] = 1; } else { dict[number]++; } if (!indexes.ContainsKey(number)) { indexes[number] = new List <int> { j } } ; else { indexes[number].Add(j); } } } var numbers = dict.Keys.Where(k => dict[k] == 2).ToList(); if (numbers.Count < 2) { continue; } for (int k = 0; k < numbers.Count; k++) { var first = numbers[k]; for (int j = k + 1; j < numbers.Count; j++) { var second = numbers[j]; var firstIndex = indexes[first]; firstIndex.Sort(); var secondIndex = indexes[second]; secondIndex.Sort(); if (BclEx.AreEqualSequences(firstIndex, secondIndex)) { int indexX = i; int indexY = firstIndex[0]; var p = possibles[indexX, indexY]; var possiblesToRemove = new List <int>(); foreach (int number in p) { if (number != first && number != second) { possiblesToRemove.Add(number); possiblesRemoved.Add(new Move { Row = indexX, Column = indexY, Value = number }); _engine.WriteLog(string.Format("performing hidden pairs in row removal of value {0} at {1}", number, _engine.CellFormat(indexX, indexY))); } } foreach (var n in possiblesToRemove) { p.Remove(n); } indexX = i; indexY = firstIndex[1]; p = possibles[indexX, indexY]; foreach (int number in p) { if (number != first && number != second) { possiblesToRemove.Add(number); possiblesRemoved.Add(new Move { Row = indexX, Column = indexY, Value = number }); _engine.WriteLog(string.Format("performing hidden pairs in row removal of value {0} at {1}", number, _engine.CellFormat(indexX, indexY))); } } foreach (var n in possiblesToRemove) { p.Remove(n); } goto beforeend; } } } } beforeend: { if (possiblesRemoved.Any()) { return new ReducePossibilitiesMove { Reduced = possiblesRemoved } } ; else { return(null); } } } }
public override Move Execute() { var possiblesRemoved = new List <Move>(); var possibles = _engine.possibles; var values = _engine.values; while (true) { for (int squareIndex = 0; squareIndex < 9; squareIndex++) { int minX = (squareIndex / 3) * 3; int maxX = minX + 3; int minY = (squareIndex % 3) * 3; int maxY = minY + 3; var dict = new Dictionary <int, int>(); var indexes = new Dictionary <int, List <int> >(); for (int i = minX; i < maxX; i++) { for (int j = minY; j < maxY; j++) { if (values[i, j] > 0) { continue; } foreach (int number in possibles[i, j]) { if (!dict.ContainsKey(number)) { dict[number] = 1; } else { dict[number]++; } int index = (i * 10 + j); if (!indexes.ContainsKey(number)) { indexes[number] = new List <int> { index } } ; else { indexes[number].Add(index); } } } } var numbers = dict.Keys.Where(k => dict[k] == 2).ToList(); if (numbers.Count < 2) { continue; } for (int i = 0; i < numbers.Count; i++) { var first = numbers[i]; for (int j = i + 1; j < numbers.Count; j++) { var second = numbers[j]; var firstIndex = indexes[first]; firstIndex.Sort(); var secondIndex = indexes[second]; secondIndex.Sort(); if (BclEx.AreEqualSequences(firstIndex, secondIndex)) { int firstNumberX = firstIndex[0] / 10; int firstNumberY = firstIndex[0] % 10; int secondNumberX = firstIndex[1] / 10; int secondNumberY = firstIndex[1] % 10; var p = possibles[firstNumberX, firstNumberY]; var possiblesToRemove = new List <int>(); foreach (int number in p) { if (number != first && number != second) { possiblesToRemove.Add(number); possiblesRemoved.Add(new Move { Row = firstNumberX, Column = firstNumberY, Value = number }); _engine.WriteLog(string.Format("performing naked pairs square removal of value {0} at {1}", number, _engine.CellFormat(firstNumberX, firstNumberY))); } } foreach (var n in possiblesToRemove) { p.Remove(n); } p = possibles[secondNumberX, secondNumberY]; possiblesToRemove = new List <int>(); foreach (int number in p) { if (number != first && number != second) { possiblesToRemove.Add(number); possiblesRemoved.Add(new Move { Row = secondNumberX, Column = secondNumberY, Value = number }); _engine.WriteLog(string.Format("performing naked pairs square removal of value {0} at {1}", number, _engine.CellFormat(secondNumberX, secondNumberY))); } } foreach (var n in possiblesToRemove) { p.Remove(n); } goto beforeend; } } } } beforeend: { if (possiblesRemoved.Any()) { return new ReducePossibilitiesMove { Reduced = possiblesRemoved } } ; else { return(null); } } } }