diff --git a/main/main.py b/main/main.py index 1dbc751..c4cc225 100644 --- a/main/main.py +++ b/main/main.py @@ -5,7 +5,6 @@ Description:None """ - import random from PySide6.QtCore import QTimer @@ -140,7 +139,7 @@ class Form(Form1): self.lcdNumber.display(time_str) def B_back(self): - global stack,cnt + global stack, cnt try: top = stack.pop() info = top.split(",", 1) @@ -156,7 +155,6 @@ class Form(Form1): except Exception: print("Stack Empty") - def check_sudo(self): global cnt, del_cnt, subject f = 1 @@ -186,11 +184,11 @@ class Form(Form1): if f == 1: print("yes") - QMessageBox.information(self, '提示','成功') + QMessageBox.information(self, '提示', '成功') self.timer.stop() else: print("no") - QMessageBox.information(self, '提示','失败') + QMessageBox.information(self, '提示', '失败') def put_num(self): global cnt, del_cnt, subject, stack @@ -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: diff --git a/main/sudo.py b/main/sudo.py index 4727875..8239888 100644 --- a/main/sudo.py +++ b/main/sudo.py @@ -2,6 +2,110 @@ import random import numpy as np +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) + + self.create_base_sudo() + self.random_sudo(50) + self.get_sudo_subject(self.del_cnt) + return self.subject + + def create_base_sudo(self): + # 9*9的二维矩阵,每个格子默认值为0 + self.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 = self.get_row(row_index) + sudo_col = self.get_col(col_index) + sudo_block = self.get_block(row_index, col_index) + + # 如果该数字已经存在于对应的行、列、九宫格 + # 则继续判断下一个候选数字,直到没有重复 + while num in sudo_row or num in sudo_col or num in sudo_block: + num = num % 9 + 1 + + # 赋值 + self.sudo[row_index, col_index] = num + num = num % 9 + 1 + return self.sudo + + + 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 # 从0,3,6 随机取一个 + rand_rows = random.sample(range(3), 2) # 从 0,1,2中随机取两个数 + row_1 = rand_row_base + rand_rows[0] + row_2 = rand_row_base + rand_rows[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] + self.sudo[:, [col_1, col_2]] = self.sudo[:, [col_2, col_1]] + + def get_sudo_subject(self, del_nums): + self.subject = self.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 + self.subject[row_index, col_index] = 0 + return self.subject + + # 获取格子所在的行的全部格子 def get_row(sudo, row): return sudo[row, :] @@ -17,100 +121,72 @@ 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 # 从0,3,6 随机取一个 +# rand_rows = random.sample(range(3), 2) # 从 0,1,2中随机取两个数 +# 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 +# - -# 打印数独 -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 # 从0,3,6 随机取一个 - rand_rows = random.sample(range(3), 2) # 从 0,1,2中随机取两个数 - 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 - - -if __name__ == '__main__': - max_clear_count = 64 # 最多清除个数 - min_clear_count = 14 # 最少清除个数 - - # 设置难度等级,1~5,5个等级:入门、初级、熟练、精通、大神 - level = 3 - - # 每个等级的个数 - each_level_count = (max_clear_count - min_clear_count) / 5 - - # 该等级最小数 - 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)