Esempio n. 1
0
    def remove(check, sudoku):
        copy = Sudoku()
        copy.Copy(sudoku, True)

        for coord in check:
            box = copy.grid[coord[0] + coord[1] * 9]
            copy.SetDigit(box, 0, True)

        return copy
Esempio n. 2
0
    def step(sudoku):
        # Probeer zover te solven als we kunnen met naked singles
        try:
            solve.singles(sudoku)
        except Exception as e:
            print("Couldn't solve while creating pattern", e)
            # Sudoku is dus niet legaal
            return None

        # Selecteer vervolgens een box met zo min mogelijk legal opties, dit wordt onze pivot
        leg = 10
        pivot = None

        for box in sudoku.grid:
            if box.digit > 0:
                # Skip boxes die al een nummer hebben
                continue

            if len(box.legal) >= leg:
                # Skip boxes met meer legal opties dan die eerder gevonden
                continue

            leg = len(box.legal)
            pivot = box
            if leg == 2:
                break

        # Note, het kan zijn dat we geen Pivot hebben gevonden, in dit geval hadden alle boxes een getal
        # en kunnen we de huidige oplossing teruggeven
        if pivot is None:
            return sudoku

        # Het kan ook zijn dat we een pivot vinden met len(pivot.legal) = 0.
        # In dat geval is de huidige sudoku niet legaal en returnen we niks
        if len(pivot.legal) == 0:
            return None

        # Itereer door de verschillende opties willekeurig
        # (omdat we maar 1 patroon kiezen, willen we dat deze willekeurig is)
        shuf = random.sample(pivot.legal, len(pivot.legal))
        for num in shuf:
            # Maak eerst een kopie aan
            copy = Sudoku()
            copy.Copy(sudoku)
            copy.SetDigit(copy.grid[pivot.index], num, True)
            # Roep vervolgens step weer aan (recursief)
            copy = step(copy)

            # Nu is copy of empty (als er geen legal optie uit komt) en zoeken we verder
            if copy is None:
                continue
            # Of hij is solved (dan zijn we klaar)
            else:
                return copy
        # Als we de forloop uitkomen, dan is er nog geen copy gereturned.
        # Return daarom None, zodat verder gezocht kan worden
        return None
Esempio n. 3
0
def bruteforce(sudoku, max=81, f=fulltuples, depth=0):
    if debug:
        # visual(sudoku)
        print("bruteforce launch with", depth)
    # Deze functie lost de sudoku gegarandeert op, al dan niet met brute-force, en geeft alle oplossingen terug.
    brutesolved = []

    # Probeer zover te solven als we kunnen met de aangegeven techniek
    f(sudoku)

    # Selecteer vervolgens een box met zo min mogelijk legal opties, dit wordt onze pivot
    leg = 10
    pivot = None

    for box in sudoku.grid:
        if box.digit > 0:
            # Skip boxes die al een nummer hebben
            continue

        if len(box.legal) >= leg:
            # Skip boxes met meer legal opties dan die eerder gevonden
            continue

        leg = len(box.legal)
        pivot = box
        if leg == 2:
            break

    # Note, het kan zijn dat we geen Pivot hebben gevonden, in dit geval hadden alle boxes een getal
    # en kunnen we de huidige oplossing teruggeven
    if pivot is None:
        return [sudoku]

    # Het kan ook zijn dat we een pivot vinden met len(pivot.legal) = 0.
    # In dat geval is de huidige sudoku niet legaal en returnen we een lege array
    # Tevens geven we een lege array terug als de maximale diepte is bereikt
    if len(pivot.legal) == 0 or depth >= max:
        return []

    # Als we vervolgens een pivot hebben gevonden, maken we voor iedere optie een nieuwe sudoku aan
    brutesudokus = []
    for num in pivot.legal:
        copy = Sudoku()
        copy.Copy(sudoku)
        copy.SetDigit(copy.grid[pivot.index], num, True)
        brutesudokus.append(copy)

    # Vervolgens hebben we een array aan copies (die ieder een ander nummer voor de pivot hebben
    # Hier kunnen we bruteforce weer voor aanroepen (recursief dus)

    for sudo in brutesudokus:
        try:
            check = bruteforce(sudo, max, f, depth + 1)
            if check is False:
                return False
            brutesolved.extend(check)
        except Exception as e:
            continue

    # Check eerst hoeveel oplossingen er zijn:
    sol = len(brutesolved)
    if sol > 2:
        # Als we nu al meerdere oplossingen hebben gevonden dan is dit een probleem
        if debug:
            print("Sudoku has multiple solutions")
        return False
    if depth == 0:
        # Als de depth 0 is, dan is dit dus de bovenste laag.
        if sol == 1:
            # En als er dan een oplossing gevonden is, dan is dit een enkele
            if debug:
                print("Sudoku has a single solution")
            sudoku.Copy(brutesolved[0])
            return True
        if sol == 0:
            # Anders hebben we er geen gevonden!
            if debug:
                print("Sudoku has no solutions")
            return False

    return brutesolved
Esempio n. 4
0
def program(mode, sudoku):

    while mode in menumodes:
        # Menu control sectie
        command = interface.interface(mode)
        if command == "quit":
            mode = "exit"
            break
        if command == "select":
            mode = "difficulty"
        if command == "insert":
            mode = "create"
            break
        if command == "menu":
            mode = "menu"
        if command in diffs:
            mode = "play"
            diff = command
            print("Loading ...")
            if diff == "platinum blonde":
                # Lees de platinum blonde uit
                array = read.readsudoku(platinumBlonde)
                sudoku = Sudoku()

                for i in range(0, 9):
                    if array is 0:
                        x = shuffle.randarray()
                    else:
                        x = array[i]
                    for j in range(0, 9):
                        box = sudoku.rows[i][j]
                        sudoku.SetDigit(box, x[j], True)
            else:
                pattern = create.pattern()
                sudoku = create.puzzle(pattern, diff)
            break
        if command == "break":
            break
    while mode == "play":
        # Play control sectie
        solving = True
        message = ""
        sel = (0, 0)
        while solving:
            command = interface.play(sudoku, headers[1], message, sel)

            if len(command) == 2:
                sel = command[1]
                box = sudoku.grid[sel[0] + sel[1] * 9]

                if box.clue:
                    message = messges[0]
                elif command[0] == 0:
                    sudoku.SetDigit(box, 0)
                    message = messges[1]
                elif sudoku.CheckLegal(box, command[0]):
                    message = ""
                    sudoku.SetDigit(box, command[0])
                else:
                    message = " ||               !!  " + str(command[0]) + "mag daar niet  !!                 || "
                continue
            message = ""
            if command == "break":
                mode = "menu"
                solving = False
            if command == "solve":
                # Solve de sudoku en print deze
                print("Solving")
                solve.bruteforce(sudoku)
                continue
            if command == "check":
                # Check of je op de goede weg bent
                print("Checking")
                copy = Sudoku()
                copy.Copy(sudoku)
                good = solve.bruteforce(copy)
                if good:
                    message = messges[2]
                else:
                    message = messges[3]

    while mode == "create":

        creating = True
        sudoku = Sudoku()
        message = ""
        sel = (0, 0)
        while creating:
            command = interface.play(sudoku, headers[2], message, sel)
            if len(command) == 2:
                sel = command[1]
                box = sudoku.grid[sel[0] + sel[1] * 9]

                if box.clue:
                    message = messges[0]
                elif command[0] == 0:
                    sudoku.SetDigit(box, 0)
                    message = messges[1]
                elif sudoku.CheckLegal(box, command[0]):
                    message = ""
                    sudoku.SetDigit(box, command[0])
                else:
                    message = " ||               !!  " + str(command[0]) + "mag daar niet  !!                 || "
                continue
            message = ""
            if command == "break":
                mode = "menu"
                creating = False
            if command == "solve":
                # Kopiëer deze sudoku en probeer hem zelf op te lossen
                copy = Sudoku()
                copy.Copy(sudoku)
                mode = program("play", copy)
                return mode
            if command == "check":
                # Controleer of de sudoku legaal is
                print("checking")
                copy = Sudoku()
                copy.Copy(sudoku)
                good = solve.bruteforce(copy)
                if good:
                    message = messges[2]
                else:
                    message = messges[3]
                continue
    return mode