public Sudoku(int n) { this.n = n; this.n2 = n * n; Items = new SudokuItem[n2][]; for (int j = 0; j < Items.Length; j++) { Items[j] = new SudokuItem[n2]; for (int i = 0; i < Items[j].Length; i++) { Items[j][i] = new SudokuItem(this, n, i, j, 0); } } Blocks = new SudokuBlock[n][]; for (int j = 0; j < Blocks.Length; j++) { Blocks[j] = new SudokuBlock[n]; for (int i = 0; i < Blocks[j].Length; i++) { Blocks[j][i] = new SudokuBlock(this, n, i, j); } } for (int bj = 0; bj < Blocks.Length; bj++) { for (int bi = 0; bi < Blocks[bj].Length; bi++) { SudokuBlock block = Blocks[bj][bi]; for (int k = 0; k < block.Items.Length; k++) { int i = k % n; int j = k / n; block.Items[k] = Items[bj * n + j][bi * n + i]; } } } Rows = new SudokuRow[n2]; for (int j = 0; j < n2; j++) { Rows[j] = new SudokuRow(this, n, j); for (int i = 0; i < Rows[j].Items.Length; i++) { Rows[j].Items[i] = Items[j][i]; } } Columns = new SudokuColumn[n2]; for (int i = 0; i < n2; i++) { Columns[i] = new SudokuColumn(this, n, i); for (int j = 0; j < Columns[i].Items.Length; j++) { Columns[i].Items[j] = Items[j][i]; } } }
public void ClearRowColumnBlockCandidates(int v) { SudokuRow row = Sudoku.Rows[j]; row.ClearCandidate(v); SudokuColumn col = Sudoku.Columns[i]; col.ClearCandidate(v); SudokuBlock block = Sudoku.GetBlock(i, j); block.ClearCandidate(v); }
public bool TryTriples() { bool rtVal = false; Dictionary <int, List <SudokuItem> > candidates = new Dictionary <int, List <SudokuItem> >(); for (int k = 1; k <= n2; k++) { candidates[k] = new List <SudokuItem>(); } foreach (SudokuItem item in Items) { if (item.value > 0) { continue; } for (int k = 1; k < item.Candidates.Length; k++) { if (item.Candidates[k] && !candidates[k].Contains(item)) { candidates[k].Add(item); } } } int[] keys = candidates.Keys.ToArray(); for (int i = 0; i < keys.Length; i++) { int count = candidates[keys[i]].Count; if (count < 2 || count > 3) { candidates.Remove(keys[i]); } } List <int> lstKeys = candidates.Keys.ToList(); for (int k = 0; k < lstKeys.Count - 2; k++) { int c1 = lstKeys[k]; List <SudokuItem> l1 = candidates[c1]; for (int l = k + 1; l < lstKeys.Count - 1; l++) { int c2 = lstKeys[l]; List <SudokuItem> l2 = candidates[c2]; for (int m = l + 1; m < lstKeys.Count; m++) { int c3 = lstKeys[m]; List <SudokuItem> l3 = candidates[c3]; SudokuItem[] result = l1.Union(l2).Union(l3).ToArray(); if (result.Count() != 3) { continue; } int[] finalkeys = new int[] { c1, c2, c3 }; // 如果是HiddenTriples,先清除自己单元的其他候选项 foreach (var item in result) { if (item.GetCandidateNumbers().Length > 2) { rtVal |= item.ClearCandidatesExcept(finalkeys); } } // 清除其他单元的候选项 rtVal |= ClearCandidates(finalkeys, result); // 清除区块中其他单元的候选项 SudokuBlock block = Sudoku.GetBlock(result[0].i, result[0].j); SudokuBlock block2 = Sudoku.GetBlock(result[1].i, result[1].j); SudokuBlock block3 = Sudoku.GetBlock(result[2].i, result[2].j); if (block == block2 && block2 == block3) { rtVal |= block.ClearCandidates(finalkeys, result); } if (rtVal) { return(rtVal); } } } } return(rtVal); }