将数独方法封装成类

master-class
MrB 11 months ago
parent 8c433d88f4
commit 055a2c4521

@ -5,7 +5,6 @@
Description:None
"""
import random
from PySide6.QtCore import QTimer
@ -156,7 +155,6 @@ class Form(Form1):
except Exception:
print("Stack Empty")
def check_sudo(self):
global cnt, del_cnt, subject
f = 1
@ -253,27 +251,23 @@ class Form(Form1):
level = 2
if self.R_h.isChecked():
level = 3
max_clear_count = 64
min_clear_count = 14
each_level_count = (max_clear_count - min_clear_count) / 5
level_start = min_clear_count + (level - 1) * each_level_count
del_cnt = del_nums = random.randrange(level_start, level_start + each_level_count)
# 生成数独
sudo = sd.create_base_sudo()
sd.random_sudo(sudo, 50)
sudo = sd.Sudo()
subject = sudo.createSubjectByLevel(level)
# 打印参考答案
sd.print_sudo(sudo)
# 出题
subject = sd.get_sudo_subject(sudo, del_nums)
del_cnt = sudo.get_del_cnt()
sudo.print_sudo()
# 将np数组内容映射到按钮上
for row_index, row in enumerate(subject):
row_list = list(map(str, row.tolist()))
row_list = replace_element(row_list, '0', ' ')
for single_index, single in enumerate(row_list):
# 找到对象名为对应坐标的按钮
b = self.findChild(QPushButton, 'B' + str(row_index) + '_' + str(single_index))
# 将值映射到按钮上
b.setText(single)
# 禁用空值按钮
if single != ' ':
b.setDisabled(True)
else:

@ -2,37 +2,37 @@ import random
import numpy as np
# 获取格子所在的行的全部格子
def get_row(sudo, row):
return sudo[row, :]
# 获取格子所在的列的全部格子
def get_col(sudo, col):
return sudo[:, col]
# 获取格子所在的九宫格的全部格子
def get_block(sudo, row, col):
row_start = row // 3 * 3
col_start = col // 3 * 3
return sudo[row_start: row_start + 3, col_start: col_start + 3]
class Sudo:
def __init__(self):
self.sudo = np.zeros((9, 9), dtype=int)
self.base_sudo = np.zeros((9, 9), dtype=int)
self.base_sudo_list = []
self.base_sudo_list_index = 0
self.base_sudo_list_length = 0
self.base_sudo_list_index_list = []
self.base_sudo_list_index_list_length = 0
self.subject = None
self.del_cnt = 0
def get_del_cnt(self):
return self.del_cnt
def createSubjectByLevel(self, level):
max_clear_count = 64
min_clear_count = 14
each_level_count = (max_clear_count - min_clear_count) / 5
# 难度对应删除数
level_start = min_clear_count + (level - 1) * each_level_count
self.del_cnt = random.randrange(level_start, level_start + each_level_count)
# 打印数独
def print_sudo(sudo):
for row_index, row in enumerate(sudo):
if row_index % 3 == 0 and row_index != 0:
print('-' * (9 + 8 + 4))
row = list(map(str, row.tolist()))
row.insert(6, '|')
row.insert(3, '|')
row_str = ' '.join(row)
print(row_str.replace('0', ' '))
self.create_base_sudo()
self.random_sudo(50)
self.get_sudo_subject(self.del_cnt)
return self.subject
def create_base_sudo():
def create_base_sudo(self):
# 9*9的二维矩阵每个格子默认值为0
sudo = np.zeros((9, 9), dtype=int)
self.sudo = np.zeros((9, 9), dtype=int)
# 随机生成起始的基数(1 ~ 9)
num = random.randrange(9) + 1
@ -40,9 +40,9 @@ def create_base_sudo():
for row_index in range(9):
for col_index in range(9):
# 获取该格子对应的行、列、九宫格
sudo_row = get_row(sudo, row_index)
sudo_col = get_col(sudo, col_index)
sudo_block = get_block(sudo, row_index, col_index)
sudo_row = self.get_row(row_index)
sudo_col = self.get_col(col_index)
sudo_block = self.get_block(row_index, col_index)
# 如果该数字已经存在于对应的行、列、九宫格
# 则继续判断下一个候选数字,直到没有重复
@ -50,30 +50,50 @@ def create_base_sudo():
num = num % 9 + 1
# 赋值
sudo[row_index, col_index] = num
self.sudo[row_index, col_index] = num
num = num % 9 + 1
return sudo
return self.sudo
def random_sudo(sudo, times):
def get_row(self, row):
return self.sudo[row, :]
def get_col(self, col):
return self.sudo[:, col]
def get_block(self, row, col):
row_start = row // 3 * 3
col_start = col // 3 * 3
return self.sudo[row_start: row_start + 3, col_start: col_start + 3]
def print_sudo(self):
for row_index, row in enumerate(self.sudo):
if row_index % 3 == 0 and row_index != 0:
print('-' * (9 + 8 + 4))
row = list(map(str, row.tolist()))
row.insert(6, '|')
row.insert(3, '|')
row_str = ' '.join(row)
print(row_str.replace('0', ' '))
def random_sudo(self, times):
for _ in range(times):
# 随机交换两行
rand_row_base = random.randrange(3) * 3 # 从036 随机取一个
rand_rows = random.sample(range(3), 2) # 从 012中随机取两个数
row_1 = rand_row_base + rand_rows[0]
row_2 = rand_row_base + rand_rows[1]
sudo[[row_1, row_2], :] = sudo[[row_2, row_1], :]
self.sudo[[row_1, row_2], :] = self.sudo[[row_2, row_1], :]
# 随机交换两列
rand_col_base = random.randrange(3) * 3
rand_cols = random.sample(range(3), 2)
col_1 = rand_col_base + rand_cols[0]
col_2 = rand_col_base + rand_cols[1]
sudo[:, [col_1, col_2]] = sudo[:, [col_2, col_1]]
self.sudo[:, [col_1, col_2]] = self.sudo[:, [col_2, col_1]]
def get_sudo_subject(sudo, del_nums):
subject = sudo.copy()
def get_sudo_subject(self, del_nums):
self.subject = self.sudo.copy()
# 随机擦除从0到80随机取要删除的个数
clears = random.sample(range(81), del_nums)
@ -82,35 +102,91 @@ def get_sudo_subject(sudo, del_nums):
# 这样就不会重复删除同一个格子的数字
row_index = clear_index // 9
col_index = clear_index % 9
subject[row_index, col_index] = 0
return subject
self.subject[row_index, col_index] = 0
return self.subject
# 获取格子所在的行的全部格子
def get_row(sudo, row):
return sudo[row, :]
if __name__ == '__main__':
max_clear_count = 64 # 最多清除个数
min_clear_count = 14 # 最少清除个数
# 获取格子所在的列的全部格子
def get_col(sudo, col):
return sudo[:, col]
# 设置难度等级1~55个等级入门、初级、熟练、精通、大神
level = 3
# 每个等级的个数
each_level_count = (max_clear_count - min_clear_count) / 5
# 获取格子所在的九宫格的全部格子
def get_block(sudo, row, col):
row_start = row // 3 * 3
col_start = col // 3 * 3
return sudo[row_start: row_start + 3, col_start: col_start + 3]
#
#
# # 打印数独
# def print_sudo(sudo):
# for row_index, row in enumerate(sudo):
# if row_index % 3 == 0 and row_index != 0:
# print('-' * (9 + 8 + 4))
# row = list(map(str, row.tolist()))
# row.insert(6, '|')
# row.insert(3, '|')
# row_str = ' '.join(row)
# print(row_str.replace('0', ' '))
#
# def create_base_sudo():
# # 9*9的二维矩阵每个格子默认值为0
# sudo = np.zeros((9, 9), dtype=int)
# # 随机生成起始的基数(1 ~ 9)
# num = random.randrange(9) + 1
#
# # 遍历从左到右,从上到下逐个遍历
# for row_index in range(9):
# for col_index in range(9):
# # 获取该格子对应的行、列、九宫格
# sudo_row = get_row(sudo, row_index)
# sudo_col = get_col(sudo, col_index)
# sudo_block = get_block(sudo, row_index, col_index)
#
# # 如果该数字已经存在于对应的行、列、九宫格
# # 则继续判断下一个候选数字,直到没有重复
# while num in sudo_row or num in sudo_col or num in sudo_block:
# num = num % 9 + 1
#
# # 赋值
# sudo[row_index, col_index] = num
# num = num % 9 + 1
# return sudo
#
#
# def random_sudo(sudo, times):
# for _ in range(times):
# # 随机交换两行
# rand_row_base = random.randrange(3) * 3 # 从036 随机取一个
# rand_rows = random.sample(range(3), 2) # 从 012中随机取两个数
# row_1 = rand_row_base + rand_rows[0]
# row_2 = rand_row_base + rand_rows[1]
# sudo[[row_1, row_2], :] = sudo[[row_2, row_1], :]
#
# # 随机交换两列
# rand_col_base = random.randrange(3) * 3
# rand_cols = random.sample(range(3), 2)
# col_1 = rand_col_base + rand_cols[0]
# col_2 = rand_col_base + rand_cols[1]
# sudo[:, [col_1, col_2]] = sudo[:, [col_2, col_1]]
#
#
# def get_sudo_subject(sudo, del_nums):
# subject = sudo.copy()
#
# # 随机擦除从0到80随机取要删除的个数
# clears = random.sample(range(81), del_nums)
# for clear_index in clears:
# # 把0到80的坐标转化成行和列索引
# # 这样就不会重复删除同一个格子的数字
# row_index = clear_index // 9
# col_index = clear_index % 9
# subject[row_index, col_index] = 0
# return subject
#
# 该等级最小数
level_start = min_clear_count + (level - 1) * each_level_count
# 该等级范围内的随机数
del_nums = random.randrange(level_start, level_start + each_level_count)
# 生成基本盘
sudo = create_base_sudo()
# 生成终盘
random_sudo(sudo, 50)
# 获取数独题目
subject = get_sudo_subject(sudo, del_nums)
print('题目:')
print('=' * 26)
print_sudo(subject)
print('\n答案:')
print('=' * 26)
print_sudo(sudo)

Loading…
Cancel
Save