You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Sudo/main/sudo.py

193 lines
6.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 # 从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]
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, :]
# 获取格子所在的列的全部格子
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]
#
#
# # 打印数独
# 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
#