Advertisement
Guest User

iichan sudoku generator

a guest
Jan 29th, 2012
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.54 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. #iichan sudoku generator
  4. #v 1.0.0
  5.  
  6. import random
  7.  
  8. class Matrix(object): #класс матрицы
  9.     def __init__(self, cols, rows):
  10.         self.cols = cols
  11.         self.rows = rows
  12.         self.matrix = []
  13.         for i in range(rows):
  14.             ea_row = []
  15.             for j in range(cols):
  16.                 ea_row.append("")
  17.             self.matrix.append(ea_row)
  18.  
  19.     def setitem(self, col, row, v):
  20.         self.matrix[col-1][row-1] = v
  21.  
  22.     def getitem(self, col, row):
  23.         return self.matrix[col-1][row-1]
  24.  
  25.     def __repr__(self): # ,
  26.         outStr = ""
  27.         for i in range(self.rows):
  28.             outStr += 'Row %s = %s\n' % (i+1, str(self.matrix[i]))
  29.         return outStr
  30.  
  31. def Number(i, j):
  32.     Number = (i-1)*9 + j #это порядковый номер текущего элемента в матрице
  33.     NumberTransp = (j-1)*9 + i #порядковый номер в транспорированной матрице
  34.     a = (Number -1)/27 #27- число элементов в трёх строках, т.е. в трёх блоках
  35.     b = (NumberTransp -1)/27
  36.     NumberBlock = a*3 + (b+1) #формула получена эмпирическим путём :3
  37.     return NumberBlock
  38.  
  39. Sudoku = Matrix(9, 9)    #создаём матрицу 9х9
  40. #и словари из пустых списков для всех вертикалей, горизонталей
  41. #и блоков- областей 3х3 в которых не должны повторятся числа
  42. ListHor = {}
  43. ListVer = {}
  44. ListBlock = {}
  45. for i in range(1, 10):
  46.     ListHor[i] = []
  47.     ListVer[i] = []
  48.     ListBlock[i] = []
  49.  
  50. #лист в котором будут хранится числа из которых можно случайно выбрать одно для
  51. #каждой конкретной ячейки, т.е. уже возможные (не повторяющиеся по соответствующим
  52. #вертикалям, горизонталям и блокам) числа
  53. List = []
  54. List = list(range(1, 10))
  55.  
  56. #итератор для верхнего цикла while (перебор строк матрицы)
  57. i = 1
  58. flag = False
  59.  
  60. while i < 10: #перебор строк
  61.     j = 1 #итератор для вложенного цикла while
  62.     while j < 10:
  63.     #если в текущей горизонтали уже есть какие то числа, то
  64.     #вычитаем их из List (в котором просто числа 1..9)
  65.         if len(ListHor[i]) > 0:
  66.             for n in range(0, len(ListHor[i])):
  67.                 if List.count(ListHor[i][n]) > 0:
  68.                     List.remove(ListHor[i][n])
  69.  
  70.         #аналогично для текущей вертикали
  71.         if len(ListVer[j]) > 0:
  72.             for n in range(0, len(ListVer[j])):
  73.                 if List.count(ListVer[j][n]) > 0:
  74.                     List.remove(ListVer[j][n])
  75.  
  76.         #для того, чтобы сделать ту же операцию для текущего блока,
  77.         #необходимо вычислить его номер (блоки пронумерованы начиная
  78.         #с верхнего левого слева направо)
  79.         NumberBlock = Number(i, j) #формула получена эмпирическим путём :3
  80.         #зная номер текущего блока, можем провести известную операцию
  81.         if len(ListBlock[NumberBlock]) > 0:
  82.             for n in range(0, len(ListBlock[NumberBlock])):
  83.                 if List.count(ListBlock[NumberBlock][n]) > 0:
  84.                     List.remove(ListBlock[NumberBlock][n])
  85.  
  86.         #если List пуст (т.е. текущая строка заполнена неверно)
  87.         #возвращаемся на первый элемент строки, стираем элементы из списка
  88.         #текущей горизонтали, последние элементы соответсвующих девяти вертикалей
  89.         #и некоторые элементы из трех соответствующих блоков. Затем проходим строку заново
  90.         #и надеемся что на этот раз заполнится как следует
  91.         if List == []:
  92.             List = list(range(1, 10))
  93.             Choice = random.choice(List)
  94.             for k in range(1, j):
  95.                 ListVer[k].pop()
  96.                 ListHor[i].pop()
  97.                 NumBl = Number(i, k)
  98.                 ListBlock[NumBl].remove(Sudoku.getitem(i, k))
  99.             i = i - 1
  100.             break #прерывание цикла- всё что дальше, уже не исполняется!
  101.  
  102.         Choice = random.choice(List) #выбираем один из элементов List рандомом
  103.         #если в List только один элемент, его и выбираем
  104.         if len(List) == 1:
  105.             Choice = List[0]
  106.  
  107.         #добавляем в соответствующие списки выбранное число
  108.         ListHor[i].append(Choice)
  109.         ListVer[j].append(Choice)
  110.         ListBlock[NumberBlock].append(Choice)
  111.         #наконец то вносим выбранное число в матрицу
  112.         Sudoku.setitem(i, j, Choice)
  113.         #обновляем List
  114.         List = list(range(1, 10))
  115.         #...и итераторы
  116.         j += 1
  117.     i += 1
  118.  
  119. #выводим результат
  120. print Sudoku
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement