Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Rekomendowane odpowiedzi

Opublikowano

Co tu dużo opisywać - program do rozwiązywania sudoku. Na razie Beta 0.5, sprawdzałem na wielu i źle na pewno niczego nie wpisuje, ale nie zawsze zauważa wszystkie możliwe tricki.

W ciągu tygodnia dam update, który będzie nieco bardziej wysilał procesor i sprawdzał na kilka kroków w przód, a jak nie znajdzie rozwiązania to podstawiał liczby i sprawdzał kilka możliwości. Na razie takich bajerów nie ma.

Starałem się pisać przejrzyście, ale jak zwykle zapewne nikomu się nie bedzie chciało analizować, bo po swojemu wrzuciłem setki zmiennych ;)

Że nie skończyłem, a to dopiero beta, to trzeba kilka razy kliknąć "rozwiąż" zanim rzeczywiście rozwiąże, co mi bardzo pomagało w debugowaniu i sprawdzaniu poszczególnych funkcji, a z najtrudniejszymi poziomami sobie nie poradzi, ale jak pisałem wyżej w ciągu tygodnia to się zmieni. To wypisywanie pod spodem możliwych cyfr też usunę na koniec lub dam jako opcjonalne.

 

Wersja 0.5

 

 

#include <EditConstants.au3>
 
 
Global $Sudoku[10][10]
Global $XSudoku[10][10]
Global $Input[10][10]
Global $label[10][10] ;<----
Global $colors[2]=[0xbbffbb, 0xddffdd]
Global $aWrite
GUICreate("Wefhy's Sudoku Solver", 455, 705) ;705->505
GUISetState()
For $liczX=1 to 9
    For $liczY=1 to 9
        $Input[$liczX][$liczY]=GUICtrlCreateInput($Sudoku[$liczX][$liczY], 50*$liczX-45, 70*$liczY-45, 45, 45, BitOR($ES_CENTER, $ES_NUMBER)) ;70->50
        GUICtrlSetBkColor(-1, $colors[Mod(Int(($liczX-1)/3)+Int(($liczY-1)/3),2)])
        GUICtrlSetFont(-1, 25)
        GUICtrlSetLimit(-1, 1)
        $label[$liczX][$liczY]=GUICtrlCreateLabel("", 50*$liczX-45, 70*$liczY+5, 50, 20)  ;<----
        GUICtrlSetFont(-1, 7) ;<----
    Next
Next
$Start=GUICtrlCreateButton("Rozwiąż!", 5, 655, 95, 45) ;655->455
Do
    Sleep(10)
    $nMsg=GUIGetMsg()
    If $nMsg=$Start Then
        ;Do
            _ReadSudoku()
            If _CheckErrors() Then
                _Solve1()
                $until=_Solve2()
 
            Else
                MsgBox(0, "Error", "Sudoku zawiera błąd!")
            EndIf
        ;Until $until
        _ReadSudoku()
        _Solve1()
    EndIf
 
Until $nMsg=-3
 
Func _ReadSudoku()
    For $liczX=1 to 9
        For $liczY=1 to 9
            $Sudoku[$liczX][$liczY]=GUICtrlRead($Input[$liczX][$liczY])
            If $Sudoku[$liczX][$liczY]=0 Then $Sudoku[$liczX][$liczY]=""
        Next
    Next
EndFunc
 
Func _CheckErrors()
    For $liczX=1 to 9
        $line=""
        For $liczY=1 to 9
            If Not StringInStr($line, $Sudoku[$liczX][$liczY]) Then
                $line&=$Sudoku[$liczX][$liczY]
            Else
                Return 0
            EndIf
        Next
    Next
    For $liczY=1 to 9
        $line=""
        For $liczX=1 to 9
            If Not StringInStr($line, $Sudoku[$liczX][$liczY]) Then
                $line&=$Sudoku[$liczX][$liczY]
            Else
                Return 0
            EndIf
        Next
    Next
    For $KliczX=1 to 3
        For $KliczY=1 to 3
            $square=""
            For $liczX=1 to 3
                For $liczY=1 to 3
                    If Not StringInStr($square, $Sudoku[($KliczX-1)*3+$liczX][($KliczY-1)*3+$liczY]) Then
                        $square&=$Sudoku[($KliczX-1)*3+$liczX][($KliczY-1)*3+$liczY]
                    Else
                        Return 0
                    EndIf
                    ;GUICtrlSetBkColor($Input[$KliczX*3-3+$liczX][$KliczY*3-3+$liczY], "0xff0000")
                Next
            Next
            ;Sleep(1000)
        Next
    Next
    Return 1
EndFunc
Func _Solve1()
    $x=False
    $aWrite=""
    For $liczX=1 to 9
        For $liczY=1 to 9
            If $Sudoku[$liczX][$liczY] Then
                GUICtrlSetData($label[$liczX][$liczY], "") ;<----
                ContinueLoop
            EndIf
            Local $write[10]=[0,1,1,1,1,1,1,1,1,1]
            For $licz=1 to 9
                If $Sudoku[$liczX][$licz] Then $write[$Sudoku[$liczX][$licz]]=0
                If $Sudoku[$licz][$liczY] Then $write[$Sudoku[$licz][$liczY]]=0
            Next
            $KX=Int(($liczX-1)/3)
            $KY=Int(($liczY-1)/3)
            For $liczX2=1 to 3
                For $liczY2=1 to 3
                    If $Sudoku[$KX*3+$liczX2][$KY*3+$liczY2] Then $write[$Sudoku[$KX*3+$liczX2][$KY*3+$liczY2]]=0
                Next
            Next
            $swrite=""
            For $licz=1 to 9
                If $write[$licz] Then $swrite&=$licz
            Next
            $XSudoku[$liczX][$liczY]=$swrite
            GUICtrlSetData($label[$liczX][$liczY], $swrite) ;<----
            If StringLen($swrite)=1 Then
                $x=True
                $aWrite&=$liczX&"|"&$liczY&"."
            EndIf
        Next
    Next
    $aWrite=StringTrimRight($aWrite, 1)
    Return $x
EndFunc
 
Func _Solve2()
    $return=0
    If $aWrite Then
        $temp=StringSplit($aWrite, ".")
        For $licz=1 to $temp[0]
            $temp2=StringSplit($temp[$licz], "|")
            $return=GUICtrlSetData($Input[$temp2[1]][$temp2[2]], $XSudoku[$temp2[1]][$temp2[2]])
        Next
    EndIf
    For $liczX=1 to 9
        For $licz=1 to 9
            $temp=""
            For $liczY=1 to 9
                If StringInStr($XSudoku[$liczX][$liczY], $licz) Then $temp&=$liczY
            Next
            If StringLen($temp)=1 Then $return=GUICtrlSetData($Input[$liczX][$temp], $licz)
        Next
    Next
    For $liczY=1 to 9
        For $licz=1 to 9
            $temp=""
            For $liczX=1 to 9
                If StringInStr($XSudoku[$liczX][$liczY], $licz) Then $temp&=$liczX
            Next
            If StringLen($temp)=1 Then $return=GUICtrlSetData($Input[$temp][$liczY], $licz)
        Next
    Next
    For $KliczX=1 to 3
        For $KliczY=1 to 3
            For $licz=1 to 9
                $temp=""
                For $liczX=1 to 3
                    For $liczY=1 to 3
                        If Not $Sudoku[($KliczX-1)*3+$liczX][($KliczY-1)*3+$liczY] And StringInStr($XSudoku[($KliczX-1)*3+$liczX][($KliczY-1)*3+$liczY], $licz) Then $temp&=($liczX-1)*3+$liczY ;Dlaczego warunek czasmi warunek 2, ale nie warunek 1?
                    Next
                Next
                ConsoleWrite($KliczX&"/"&$KliczY&"|"&$temp&@CRLF)
                If StringLen($temp)=1 Then $return=GUICtrlSetData($Input[($KliczX-1)*3+Int(($temp-1)/3)+1][($KliczY-1)*3+Mod($temp-1, 3)+1], $licz)
            Next
        Next
    Next
    Return $return
 
EndFunc

Law of Revelation: The hidden flaw never remains hidden.

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...