#include #include Opt("GuiOnEventMode", 1) Global $width = 800, $height = 600 Global $FieldSize = [5, 35, $width - 10, $height - 60] Global $Fields[9][9][3], $Space = 10, $FieldWidth = ($FieldSize[2] - ($Space * UBound($Fields) - 1)) / 9, $FieldHeight = ($FieldSize[3] - ($Space * UBound($Fields, 2) - 1)) / 9, $LabelsW[Int((UBound($Fields)) / 3)], $LabelsH[Int((UBound($Fields, 2)) / 3)] Global $Solved = False, $solving = False $Gui = GUICreate("SudokuSolver", $width, $height) GUICtrlCreateButton("New Sudoku", 5, 5, $width - 10, 25) GUICtrlSetOnEvent(-1, "_newSudoku") $SolveButton = GUICtrlCreateButton("Solve Sudoku", 5, $height - 30, $width - 10, 25) GUICtrlSetOnEvent(-1, "_buttonSolveSodoku") GUISetState(@SW_SHOW, $Gui) GUISetOnEvent($GUI_EVENT_CLOSE, "_close") GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND") $dummy = GUICtrlCreateDummy() Global $AccelKeys[1][2] = [["{TAB}", $dummy]] GUICtrlSetOnEvent($dummy, "_TabNext") GUISetAccelerators($AccelKeys, $Gui) _newSudoku() While Sleep(10) WEnd Func _newSudoku() $N=".61..7..3.92..3..............853..........5.45....8....4......1...16.8..6........" $N=StringSplit($N,"",2) $Solved=false For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 GUICtrlDelete($Fields[$i][$j][0]) Next Next For $i = 0 To UBound($LabelsW) - 1 Step 1 GUICtrlDelete($LabelsW[$i]) Next For $i = 0 To UBound($LabelsH) - 1 Step 1 GUICtrlDelete($LabelsH[$i]) Next $Nx=0 For $j = 0 To UBound($Fields, 2) - 1 Step 1 For $i = 0 To UBound($Fields) - 1 Step 1 $Fields[$i][$j][0] = GUICtrlCreateInput("", $FieldSize[0] + ($FieldWidth + $Space) * $i, $FieldSize[1] + ($FieldHeight + $Space) * $j, $FieldWidth, $FieldHeight) If Not ($N[$Nx]=".") Then GUICtrlSetData(-1,$N[$Nx]) GUICtrlSetFont(-1, $FieldHeight / 2) $Nx+=1 Next Next For $i = 3 To UBound($Fields) - 1 Step 3 $LabelsW[Int($i / 3) - 1] = GUICtrlCreateLabel("", $FieldSize[0] + $i * $FieldWidth + $i * $Space - $Space, $FieldSize[1], $Space, $FieldHeight * 9 + $Space * 8) GUICtrlSetBkColor(-1, 0x000000) Next For $i = 3 To UBound($Fields, 2) - 1 Step 3 $LabelsH[Int($i / 3) - 1] = GUICtrlCreateLabel("", $FieldSize[0], $FieldSize[1] + $i * $FieldHeight + $i * $Space - $Space, $FieldWidth * 9 + $Space * 8, $Space) GUICtrlSetBkColor(-1, 0x000000) Next EndFunc ;==>_newSudoku Func _buttonSolveSodoku() If $Solved Then For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 GUICtrlSetData($Fields[$i][$j][0], $Fields[$i][$j][2]) Next Next $Solved = False GUICtrlSetData($SolveButton, "Solve Sudoku") Else $solving = True For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 $Fields[$i][$j][1] = GUICtrlRead($Fields[$i][$j][0]) $Fields[$i][$j][2] = $Fields[$i][$j][1] GUICtrlSetState($Fields[$i][$j][0], $GUI_DISABLE) Next Next $maybePossible = True For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 If $Fields[$i][$j][1] <> "" Then $Fields[$i][$j][1] = "" If _check($i, $j, $Fields[$i][$j][2]) Then GUICtrlSetBkColor($Fields[$i][$j][0], 0xFF0000) MsgBox(16, "Error", "Das Sudoku ist nicht lösbar! Sudoku could not be solved!") $maybePossible = False ExitLoop 2 EndIf $Fields[$i][$j][1] = $Fields[$i][$j][2] EndIf Next Next If $maybePossible Then If Not _solveSudoku(0, 0) Then MsgBox(16, "Error", "Das Sudoku ist nicht lösbar! Sudoku could not be solved!") For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 $Fields[$i][$j][1] = 0 GUICtrlSetData($Fields[$i][$j][0], $Fields[$i][$j][2]) Next Next Else $Solved = True GUICtrlSetData($SolveButton, "Reset Field") EndIf EndIf For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 GUICtrlSetState($Fields[$i][$j][0], $GUI_ENABLE) Next Next $solving = False EndIf EndFunc ;==>_buttonSolveSodoku Func _solveSudoku($l, $r) If $l > UBound($Fields) - 1 Then Return True EndIf If $r > UBound($Fields, 2) - 1 Then Return _solveSudoku($l + 1, 0) EndIf If $Fields[$l][$r][1] > 0 Then Return _solveSudoku($l, $r + 1) EndIf For $i = 1 To UBound($Fields) Step 1 If Not _check($l, $r, $i) Then $Fields[$l][$r][1] = $i GUICtrlSetData($Fields[$l][$r][0], $i) If _solveSudoku($l, $r) Then Return True EndIf EndIf Next $Fields[$l][$r][1] = 0 GUICtrlSetData($Fields[$l][$r][0], 0) Return False EndFunc ;==>_solveSudoku Func _check($l, $r, $zahl) If _checkRow($l, $zahl) Then Return True ElseIf _checkCol($r, $zahl) Then Return True ElseIf _checkBox($l, $r, $zahl) Then Return True EndIf Return False EndFunc ;==>_check Func _checkRow($l, $zahl) For $i = 0 To UBound($Fields, 2) - 1 Step 1 If $Fields[$l][$i][1] = $zahl Then Return True EndIf Next Return False EndFunc ;==>_checkRow Func _checkCol($r, $zahl) For $i = 0 To UBound($Fields) - 1 Step 1 If $Fields[$i][$r][1] = $zahl Then Return True EndIf Next Return False EndFunc ;==>_checkCol Func _checkBox($l, $r, $zahl) $BoxL = Int($l / 3) * 3 $BoxR = Int($r / 3) * 3 For $i = $BoxL To $BoxL + 2 Step 1 For $j = $BoxR To $BoxR + 2 Step 1 If $Fields[$i][$j][1] = $zahl Then Return True EndIf Next Next Return False EndFunc ;==>_checkBox Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam) if NOT $solving then Local $nNotifyCode = BitShift($wParam, 16) Local $hCtrl = $lParam If $nNotifyCode = 1024 Or $nNotifyCode = 786 Then For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 If $hCtrl = GUICtrlGetHandle($Fields[$i][$j][0]) Then $data = GUICtrlRead($Fields[$i][$j][0]) If StringLen($data) > 1 Then $data = StringMid($data, StringLen($data)) EndIf If Not ($data = "1" Or $data = "2" Or $data = "3" Or $data = "4" Or $data = "5" Or $data = "6" Or $data = "7" Or $data = "8" Or $data = "9") Then $data = "" _selNext($i,$j) EndIf GUICtrlSetData($Fields[$i][$j][0], $data) If $data <> "" Then _selNext($i,$j) EndIf If $data <> "" Then GUICtrlSetBkColor($Fields[$i][$j][0], 0xFFFF00) Else GUICtrlSetBkColor($Fields[$i][$j][0], 0xFFFFFF) EndIf $Solved = False GUICtrlSetData($SolveButton, "Solve Sudoku") EndIf Next Next EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_COMMAND Func _selNext($i,$j) $x = $i $y = $j If $x + 1 > UBound($Fields) - 1 And $y + 1 > UBound($Fields, 2) - 1 Then $x = 0 $y = 0 ElseIf $y + 1 > UBound($Fields, 2) Then $x += 1 $y = 0 ElseIf $x + 1 > UBound($Fields) - 1 Then $x = 0 $y += 1 Else $x += 1 EndIf GUICtrlSetState($Fields[$x][$y][0], $GUI_FOCUS) EndFunc ;==>_selNext Func _TabNext() $a = ControlGetFocus("") $handle = ControlGetHandle ($Gui,"",$a) For $i = 0 To UBound($Fields) - 1 Step 1 For $j = 0 To UBound($Fields, 2) - 1 Step 1 if GUICtrlGetHandle($Fields[$i][$j][0])=$handle then _selNext($i,$j) ExitLoop 2 endif next next EndFunc Func _close() Exit EndFunc ;==>_close