我如何确保数独板只生成一个唯一的解决方案?它已经做到了吗?

2024-04-25 19:53:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试用Tim的数独解算器修改TechManager。我得到了它,所以它会生成一个随机板,但我不确定如何确保只有一个唯一的解决方案。关于如何实现这一点,有什么想法吗

import random


n = 3
m = n**2


def make_board(bo):
    possible_answers = [_ for _ in range(1, m+1)]
    # print(possible_answers)
    find = find_empty(bo)
    if not find:
        return True
    else:
        row, col = find

    random.shuffle(possible_answers)

    for i in possible_answers:
        #  i = random.randint(1, 9)
        if valid(bo, i, (row, col)):
            bo[row][col] = i

            if make_board(bo):
                return True

            bo[row][col] = 0

    return False


counter = 1


def solve(bo):
    global counter
    find = find_empty(bo)
    if not find:
        counter += 1
        return True
    else:
        row, col = find

    for i in range(1, m+1):
        if valid(bo, i, (row, col)):
            bo[row][col] = i

            if solve(bo):
                return True

            bo[row][col] = 0

    return False


def valid(bo, num, pos):
    # Check row
    for i in range(len(bo[0])):
        if bo[pos[0]][i] == num and pos[1] != i:
            return False

    # Check column
    for i in range(len(bo)):
        if bo[i][pos[1]] == num and pos[0] != i:
            return False

    # Checks square
    box_x = pos[1] // n
    box_y = pos[0] // n

    for i in range(box_y * n, box_y * n + n):
        for j in range(box_x * n, box_x * n + n):
            if bo[i][j] == num and (i, j) != pos:
                return False

    return True


def print_board(bo):
    for i in range(len(bo)):
        if i % n == 0 and i != 0:
            print("- - - - - - - - - - - - - ")

        for j in range(len(bo[0])):
            if j % n == 0 and j != 0:
                print(" | ", end="")

            if j == m-1:
                print(bo[i][j])
            else:
                print(str(bo[i][j]) + " ", end="")


def find_empty(bo):
    for i in range(len(bo)):
        for j in range(len(bo[0])):
            if bo[i][j] == 0:
                return i, j  # return row, column

    return None


def count_squares(bo):
    count = 0
    for box in bo:
        for num in box:
            if num != 0:
                count += 1

    return count

此函数与make_board()和solve()一起用于生成电路板

def generate_board(diff):
    """generates a board based on difficulty specified"""
    empty_board = [[0 for _ in range(m)] for _ in range(m)]
    global counter

    difficulty_levels = {"Easy": 30, "Medium": 25, "Hard": 20}
    difficulty = difficulty_levels[diff]

    make_board(empty_board)
    counter = 1
    while count_squares(empty_board) > difficulty:
        x = random.randint(0, m-1)
        y = random.randint(0, m-1)
        if valid(empty_board, empty_board[x][y], (x, y)):
            empty_board[x][y] = 0

    return empty_board


board = generate_board("Hard")

print_board(board)
print("\n\n")
solve(board)
print_board(board)

Tags: inposboardboxforreturnifdef