原理:重复随机生成一行值为1-9的序列,直到生成的九行序列满足数独规则。
代码:
import random
import time
import logging
logging.basicConfig(level = logging.INFO)
class ShuDu:
'数独生成器'
def __init__(self):
self.__map = [[0 for i in range(9)] for j in range(9)]
return
# 生成数独的一行,即9个值为1-9的数
def __randLine(self, x):
l = list(range(1, 10))
for i in range(len(x)):
x[i] = l[random.randint(0, len(l) - 1)]
l.remove(x[i])
return x
# 判断纵向是否冲突
def __zx_conflict(self, row):
for i in range(row):
for j in range(9):
if self.__map[row][j] == self.__map[i][j]:
return True
return False
# 判断九宫格是否冲突
def __jgg_conflict(self, row):
m = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
index = 0
for i in range(len(m)):
if row in m[i]:
index = i
comp = list()
for i in m:
comp.append([])
for j in m[index]:
comp[-1].append(self.__map[j][i[0]])
comp[-1].append(self.__map[j][i[1]])
comp[-1].append(self.__map[j][i[2]])
for i in range(3):
comp[i].remove(self.__map[row][0 + 3 * i])
comp[i].remove(self.__map[row][1 + 3 * i])
comp[i].remove(self.__map[row][2 + 3 * i])
for i in range(9):
if self.__map[row][i] in comp[i // 3]:
return True
return False
# 获取数独
def getMap(self):
def oneTry():
start = time.time()
self.__map = [[0 for i in range(9)] for j in range(9)]
self.__randLine(self.__map[0])
for i in range(1, 9):
it = 0
flag = 0
self.__randLine(self.__map[i])
while self.__zx_conflict(i) or self.__jgg_conflict(i):
self.__randLine(self.__map[i])
it += 1
if it > 200000: # 该值可反复调试,或许有最佳值
flag = 1
break
if flag == 1:
break
end = time.time()
if i == 8:
logging.info('map generate success,cost {:.3f}s'.format(end - start))
return True, end - start
else:
logging.info('map generate default,cost {:.3f}s'.format(end - start))
return False, end - start
cost = 0
while True:
logging.info('one try')
ot = oneTry()
cost += ot[1]
if ot[0]:
logging.info('total cost {:.3f}s'.format(cost))
return self.__map
return
# 打印数独
def printMap(self):
mmap = self.getMap()
print('the map is:')
for i in mmap:
for j in i:
print(j, end = ' ')
print()
if __name__ == '__main__':
# print(ShuDu.__doc__)
sd = ShuDu()
sd.printMap()
运行结果: