/// <summary> /// 填充单元格 /// </summary> /// <param name="table">表</param> /// <param name="index">索引</param> /// <returns>返回结果</returns> public bool FillCell(Cell[,] table, int index) { RelativeCellMethod removeCandidateMethod = new RelativeCellMethod(RemoveCellCandidate); RelativeCellMethod recoverCandidateMethod = new RelativeCellMethod(RecoverCellCandidate); if (index >= 81) {//如果索引超出范围,则表示数独已成功生成,直接返回 return(true); } if (table[index / 9, index % 9].answer != 0) {//如果索引的单元格已赋值,则直接跳到下一个索引赋值 return(FillCell(table, index + 1)); } bool flag = true; List <int> nextCandidates = new List <int>(); //预先保存好改单元格的候选数序列,如果所有候选数都不成功,则把候选数全部还原之后再返回 nextCandidates.AddRange(table[index / 9, index % 9].candidate); while (table[index / 9, index % 9].candidate.Count > 0 && flag) { //如果单元格候选数个数大于0,且标记为真,则循环试探候选数 SetValue(table[index / 9, index % 9]); //为单元格赋值 flag &= DealRelativeCell(removeCandidateMethod, table, index); //移除相关单元格的对应这个值的候选数 if (!flag) { //如果移除候选数失败,则恢复候选数,并继续下个循环 DealRelativeCell(recoverCandidateMethod, table, index); } else {//如果移除候选数成功,则继续试探填充下一个单元格 flag &= FillCell(table, index + 1); if (!flag) {//如果填充下一个单元格失败,则恢复候选数,并继续下个循环 DealRelativeCell(recoverCandidateMethod, table, index); } else {//如果填充下一个单元格成功,则直接返回(运行到这里肯定表示整个数独已成功生成!) return(true); } } flag = !flag;//把标志取反,继续下个循环 } if (table[index / 9, index % 9].candidate.Count == 0) {//如果所有候选数都是过了且全部失败,恢复此单元格的候选数,并返回false table[index / 9, index % 9].candidate.AddRange(nextCandidates); return(false); } return(flag); }
/// <summary> /// 处理相关单元格 /// 包括行,列和宫 /// </summary> /// <param name="cellMethod">调用方法</param> /// <param name="table">表</param> /// <param name="index">索引</param> /// <returns>返回结果</returns> private bool DealRelativeCell(RelativeCellMethod cellMethod, Cell[,] table, int index) { bool flag = true; Cell cell = table[index / 9, index % 9]; for (int i = 0; i < 9; i++) { //同列单元格 if (i != index / 9) { //不能等于本单元格 flag &= cellMethod(table, i, index % 9, index); } //同行单元格 if (i != index % 9) { //不能等于本单元格 flag &= cellMethod(table, index / 9, i, index); } } //宫内的其它四个单元格 for (int i = nineCells[index / 9]; i < nineCells[index / 9] + 3; i++) { for (int j = nineCells[index % 9]; j < nineCells[index % 9] + 3; j++) { if (i != index / 9 && j != index % 9) { flag &= cellMethod(table, i, j, index); } } } if (cellMethod == RecoverCellCandidate) { cell.answer = 0; } return(flag); }