Программа нахождения решения Судоку. Только начинающий. Жду конструктивной критики! - C#

Узнай цену своей работы

Формулировка задачи:

Пожалуйста, оцените, и укажите на ошибки: оформления программы, составления комментариев!
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Sudoku_Solver
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. int index = 0;
  10. int[] sudoku = new int[81] {0,1,0, 7,5,0, 0,6,0, // Вводим судоку
  11. 0,2,7, 0,4,3, 5,0,0, // ячейка - один символ
  12. 4,0,8, 6,0,0, 0,0,7, // строка - 9 символов по горизонтали
  13. // столбец - 9 символов по вертикали
  14. 0,8,0, 0,6,9, 0,0,0, // сегмент - группа из 9 символов
  15. 0,0,0, 8,0,0, 6,7,5,
  16. 2,0,0, 0,3,7, 0,4,0,
  17. 0,7,9, 0,8,0, 0,2,0,
  18. 8,0,0, 1,0,6, 0,0,3,
  19. 1,3,0, 0,0,5, 0,8,4};
  20. //Вывод судоку на экран
  21. Console.WriteLine("Судоку");
  22. Writeln(sudoku);
  23. if (CheckSudoku(sudoku)) //Условие проверяет в методе правильность судоку
  24. {
  25. //Если судоку правильное, то ищется решение
  26. if (Solver(index, ref sudoku)) //Условие проверяет есть ли решение,
  27. { //если есть, метод возвращает true и по ref ссылке первое найденное решение
  28. Console.WriteLine("Первое найденное решение Судоку");
  29. Writeln(sudoku);
  30. }
  31. else Console.WriteLine("Нет решений");
  32. }
  33. else Console.WriteLine("Судоку составлен с ошибками");
  34. Console.ReadKey();
  35. }
  36. //Метод проверки судоку на правильность составления
  37. static bool CheckSudoku(int[] sudoku) // метод возвращает true, если судоку составлен правильно
  38. {
  39. for (int index = 0; index < 81; index++)
  40. {
  41. if (9 < sudoku[index] || sudoku[index] < 0) //Проверка значений ячеек в диапазоне 1 до 9
  42. return false;
  43. if (sudoku[index] != 0) //Проверяем на совпадение только ненулевые ячейки
  44. {
  45. //проверяем ячейку на совпадение значения с другими ячейками в строке, столбце, сегменте
  46. if (CheckPossibleValue(sudoku[index], index, sudoku) == false)
  47. return false;
  48. }
  49. }
  50. return true;
  51. }
  52. //Метод поиска решения судоку
  53. static bool Solver(int index, ref int[] sudoku)
  54. {
  55. if ((index < 81) && (sudoku[index] == 0)) //Проверяем ячейки подряд, кроме заполненных и запрещаем выход за пределы массива судоку
  56. {
  57. Stack<int> stackPossibleValues = new Stack<int>(); //инициализируем стек для возможных значений ячейки
  58. for (int possibleValue = 1; possibleValue < 10; possibleValue++) //последовательно проверяем значение от 1 до 9 и записываем в стек
  59. {
  60. if (CheckPossibleValue(possibleValue, index, sudoku)) //если нет совпадений в столбце строке и сегменте
  61. stackPossibleValues.Push(possibleValue); //записываем значение в стек
  62. }
  63. while (stackPossibleValues.Count > 0) //проверяем значения из стека для ячейки, пока стек не опустеет
  64. {
  65. sudoku[index] = stackPossibleValues.Pop(); //присваеваем ячейке значение из стека
  66. if (Solver(index + 1, ref sudoku)) //Метод вызывает сам себя с увеличением индекса массива судоку
  67. return true; //Условие if вернет true, только если достигли конца судоку, т.е. все ячейки заполнены
  68. }
  69. sudoku[index] = 0; //если все значения стека проверены, и из вложенных методов возвращалось false,
  70. return false; //то обнуляем ячейку с номером index, возвращаем предыдущему методу false
  71. }
  72. else if (index < 81) //заполненные ячейки пропускаем.
  73. {
  74. if (Solver(index + 1, ref sudoku) == false)
  75. return false;
  76. }
  77. return true; //возврат true будет при index = 81, т.е. все ячейки заполнены,
  78. //произойдет последовательный выход из всех вложенных методов, т.к. все методы будут возвращать true
  79. }
  80. //Метод проверяее значение на совпадение с другими ячейками в строке, столбце, сегменте
  81. //в метод поступает: проверяемое значение, индекс ячейки, где проверяется это значение, и массив судоку
  82. static bool CheckPossibleValue(int value, int index, int[] sudoku)
  83. {
  84. //проверяем по строке и столбцу
  85. for (int j = 0; j < 9; j++)
  86. {
  87. if (value == sudoku[(index / 9) * 9 + j] //находим первый элемент строки (index / 9) * 9
  88. & index != (index / 9) * 9 + j) //условие чтобы ячейка не сравнивала себя с собой
  89. {
  90. return false; //возвращаем false, если было совпадение значения с ячейками в строке
  91. }
  92. if (value == sudoku[(index % 9) + 9 * j] //находим первый элемент столбца (index % 9) + 9
  93. & index != (index % 9) + 9 * j)
  94. {
  95. return false; //возвращаем false, если было совпадение значения с ячейками в столбце
  96. }
  97. }
  98. //проверяем по сегменту
  99. for (int j = 0; j < 3; j++)
  100. {
  101. for (int k = 0; k < 3; k++)
  102. { //находим первый элемент сегмента ((index / 27 * 27) + (index % 9) / 3 * 3)
  103. if (value == sudoku[(index / 27 * 27) + ((index % 9) / 3 * 3) + (9 * j) + k]
  104. & index != ((index / 27 * 27) + (index % 9) / 3 * 3 + (9 * j) + k))
  105. {
  106. return false; //возвращаем false, если было совпадение значения с ячейками в сегменте
  107. }
  108. }
  109. }
  110. return true; //возвращаем true, если совпадений не было
  111. }
  112. //Просто метод вывода на экран судоку в удобоваримом виде
  113. static void Writeln(int[] sudoku)
  114. {
  115. Console.WriteLine(new string('-', 21));
  116. for (int i = 0; i < 81; i++)
  117. {
  118. Console.Write("{0} ", sudoku[i]);
  119. if (((i + 1) % 3 == 0) & ((i + 1) % 9 != 0))
  120. Console.Write("| ");
  121. if ((i + 1) % 9 == 0)
  122. Console.WriteLine();
  123. if ((i + 1) % 27 == 0)
  124. Console.WriteLine(new string('-', 21));
  125. }
  126. }
  127. }
  128. }

Решение задачи: «Программа нахождения решения Судоку. Только начинающий. Жду конструктивной критики!»

textual
Листинг программы
  1.         //Метод проверяее значение на совпадение с другими ячейками в строке, столбце, сегменте
  2.         //в метод поступает: проверяемое значение, индекс ячейки, где проверяется это значение, и массив судоку
  3.         static bool CheckPossibleValue(int value, int index, int[] sudoku)
  4.         {
  5.             const int lineSize = 9;             // кол-во ячеек в строке
  6.             const int blockSize = 27;           // кол-во ячеек в блоке - три сегмента по горизонтали(три строки)
  7.             const int lineSegmentSize = 3;      // кол-во строк в сегменте
  8.             const int colomnSegmentSize =3;     // кол-во столбцов в сегменте
  9.  
  10.             //проверяем по строке и столбцу    
  11.             for (int j = 0; j < lineSize; j++)
  12.             {
  13.                 if (value == sudoku[(index / lineSize) * lineSize + j]    //находим первый элемент строки (index / 9) * 9
  14.                     && index != (index / lineSize) * lineSize + j)         //условие чтобы ячейка не сравнивала себя с собой
  15.                 {
  16.                     return false;                           //возвращаем false, если было совпадение значения с ячейками в строке
  17.                 }
  18.  
  19.                 if (value == sudoku[(index % lineSize) + lineSize * j]    //находим первый элемент столбца (index % 9) + 9
  20.                     && index != (index % lineSize) + lineSize * j)
  21.                 {
  22.                     return false;                           //возвращаем false, если было совпадение значения с ячейками в столбце
  23.                 }
  24.             }
  25.             //проверяем по сегменту
  26.             for (int j = 0; j < lineSegmentSize; j++)
  27.             {
  28.                 for (int k = 0; k < colomnSegmentSize; k++)
  29.                 {                                           //находим первый элемент сегмента ((index / 27 * 27) + (index % 9) / 3 * 3)
  30.                     if (value == sudoku[(index / blockSize * blockSize)
  31.                         + ((index % lineSize) / lineSegmentSize * lineSegmentSize) + (lineSize * j) + k]
  32.                         && index != ((index / blockSize * blockSize)
  33.                         + (index % lineSize) / lineSegmentSize * lineSegmentSize + (lineSize * j) + k))
  34.                     {
  35.                         return false;                       //возвращаем false, если было совпадение значения с ячейками в сегменте
  36.                     }
  37.                 }
  38.             }
  39.             return true;                                    //возвращаем true, если совпадений не было
  40.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 3.8 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы