#noenv #persistent #singleinstance force settitlematchmode 3 ;-------------------------------------------------------------------------- MyFolder = %A_MyDocuments% StringRight, x, MyFolder, 1 if x <> \ MyFolder = %MyFolder%\ ;-------------------------------------------------------------------------- row1 = field11|field21|field31|field41|field51|field61|field71|field81|field91 row2 = field12|field22|field32|field42|field52|field62|field72|field82|field92 row3 = field13|field23|field33|field43|field53|field63|field73|field83|field93 row4 = field14|field24|field34|field44|field54|field64|field74|field84|field94 row5 = field15|field25|field35|field45|field55|field65|field75|field85|field95 row6 = field16|field26|field36|field46|field56|field66|field76|field86|field96 row7 = field17|field27|field37|field47|field57|field67|field77|field87|field97 row8 = field18|field28|field38|field48|field58|field68|field78|field88|field98 row9 = field19|field29|field39|field49|field59|field69|field79|field89|field99 ;-------------------------------------------------------------------------- column1 = field11|field12|field13|field14|field15|field16|field17|field18|field19 column2 = field21|field22|field23|field24|field25|field26|field27|field28|field29 column3 = field31|field32|field33|field34|field35|field36|field37|field38|field39 column4 = field41|field42|field43|field44|field45|field46|field47|field48|field49 column5 = field51|field52|field53|field54|field55|field56|field57|field58|field59 column6 = field61|field62|field63|field64|field65|field66|field67|field68|field69 column7 = field71|field72|field73|field74|field75|field76|field77|field78|field79 column8 = field81|field82|field83|field84|field85|field86|field87|field88|field89 column9 = field91|field92|field93|field94|field95|field96|field97|field98|field99 ;-------------------------------------------------------------------------- block1 = field11|field21|field31|field12|field22|field32|field13|field23|field33 block2 = field41|field51|field61|field42|field52|field62|field43|field53|field63 block3 = field71|field81|field91|field72|field82|field92|field73|field83|field93 block4 = field14|field24|field34|field15|field25|field35|field16|field26|field36 block5 = field44|field54|field64|field45|field55|field65|field46|field56|field66 block6 = field74|field84|field94|field75|field85|field95|field76|field86|field96 block7 = field17|field27|field37|field18|field28|field38|field19|field29|field39 block8 = field47|field57|field67|field48|field58|field68|field49|field59|field69 block9 = field77|field87|field97|field78|field88|field98|field79|field89|field99 ;-------------------------------------------------------------------------- loop, 9 { ColumnIndex = %a_index% loop, 9 { RowIndex = %a_index% field%ColumnIndex%%RowIndex% = 0 } } ;-------------------------------------------------------------------------- Gui, Font, s9 loop, 3 { a := (a_index - 1) loop, 3 { b := (a_index - 1) x := (11 + a * 107) y := (5 + b * 107) Gui, Add, GroupBox, w101 h107 x%x% y%y% } } Gui, Font, s14 cb0b0a0, webdings ShowWhat = colors loop, 9 { RowIndex = %a_index% loop, 9 { ColumnIndex = %a_index% x := (ColumnIndex * 31) y := (RowIndex * 31) if ColumnIndex <= 3 x -= 10 else if ColumnIndex <= 6 x += 4 else x += 18 if RowIndex <= 3 y -= 13 else if RowIndex <= 6 y += 1 else y += 15 gui, add, text, x%x% y%y%, n ; field%ColumnIndex%%RowIndex% } } Gui, Font, s14 cblack, wingdings gui, add, text, x+34 y20 w20, à ; à in wingdings = "->" PointAtButton = 1 PointAtColor = 1 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 gui, add, text, yp+31 w20 Gui, Font, s14, webdings gui, add, text, x+6 y18 cwhite, n gui, add, text, yp+31 cyellow, n gui, add, text, yp+31 cFF7700, n gui, add, text, yp+31 cred, n gui, add, text, yp+31 cpurple, n gui, add, text, yp+31 cblue, n gui, add, text, yp+31 caqua, n gui, add, text, yp+31 cgreen, n gui, add, text, yp+31 cblack, n gui, add, text, yp+31 cb0b0a0, n Gui, Font, s18 cblack, arial gui, add, text, x+9 y18, = 1 gui, add, text, yp+31, = 2 gui, add, text, yp+31, = 3 gui, add, text, yp+31, = 4 gui, add, text, yp+31, = 5 gui, add, text, yp+31, = 6 gui, add, text, yp+31, = 7 gui, add, text, yp+31, = 8 gui, add, text, yp+31, = 9 gui, add, text, yp+31, = empty Gui, Font, s12 cblack, wingdings gui, add, button, x11 y+27 gback vback, ß ; ß in wingdings = "<-" gui, add, button, x+12 gforward vforward, à ; à in wingdings = "->" Gui, Font, s12 cblack, arial gui, add, button, x+12 gFindOne vFindOne, find one gui, add, button, x+12 gFindAll vFindAll, find all gui, add, button, x+12 gRemoveAll vRemoveAll, remove all gui, add, button, x+12 gNewSudoku vNewSudoku, new sudoku gui, add, button, x11 y+12 gmemorize vmemorize, memorize gui, add, button, x+12 grestore vrestore, restore gui, add, button, x+12 gTestMain vtest, test gui, add, button, x+12 ghelp vhelp, ? gui, color, e0e0d0 gui, show, h438, color-sudoku ;-------------------------------------------------------------------------- today = %A_MM%%A_DD% if (today = 1224 or today = 1225 or today = 1226 or today = 1227 or today = 1228 or today = 1229 or today = 1230 or today = 1231 or today = 0101 or today = 0102 or today = 0103 or today = 0104 or today = 0105 or today = 0106) { gosub DisableButtons settimer, ChristmasTree, 50 ChristmasTree1 = 000050067800020000500806000000504000004030100008900300080070210039185740000090000 ChristmasTree2 = 000050067800030000500806000000502000002040100008900400080070310049185720000090000 loop { ColorsToFields(ChristmasTree1) gosub FieldsToStatics if StopBlinking = 1 { MemoryBack = %ChristmasTree1% settimer, ChristmasTree, off gosub EnableButtons break } sleep 500 ColorsToFields(ChristmasTree2) gosub FieldsToStatics if StopBlinking = 1 { MemoryBack = %ChristmasTree2% settimer, ChristmasTree, off gosub EnableButtons break } sleep 500 } } ;-------------------------------------------------------------------------- settimer, ReactToClicksOnFieldsOrColors, 100 return ; end of the auto-execute section ;__________________________________________________________________________ ;__________________________________________________________________________ ChristmasTree: GetKeyState, state, LButton if state = D StopBlinking = 1 return ;__________________________________________________________________________ guiclose: exitapp ;__________________________________________________________________________ #IfWinActive color-sudoku ahk_class AutoHotkeyGUI 1::MemoryNumbers = %MemoryNumbers%1 2::MemoryNumbers = %MemoryNumbers%2 3::MemoryNumbers = %MemoryNumbers%3 4::MemoryNumbers = %MemoryNumbers%4 5::MemoryNumbers = %MemoryNumbers%5 6::MemoryNumbers = %MemoryNumbers%6 7::MemoryNumbers = %MemoryNumbers%7 8::MemoryNumbers = %MemoryNumbers%8 9::MemoryNumbers = %MemoryNumbers%9 0::MemoryNumbers = %MemoryNumbers%0 Numpad1::MemoryNumbers = %MemoryNumbers%1 Numpad2::MemoryNumbers = %MemoryNumbers%2 Numpad3::MemoryNumbers = %MemoryNumbers%3 Numpad4::MemoryNumbers = %MemoryNumbers%4 Numpad5::MemoryNumbers = %MemoryNumbers%5 Numpad6::MemoryNumbers = %MemoryNumbers%6 Numpad7::MemoryNumbers = %MemoryNumbers%7 Numpad8::MemoryNumbers = %MemoryNumbers%8 Numpad9::MemoryNumbers = %MemoryNumbers%9 Numpad0::MemoryNumbers = %MemoryNumbers%0 left::gosub back right::gosub forward WheelDown::PointAt(PointAtButton + 1) WheelUp::PointAt(PointAtButton - 1) ;-------------------------------------------------------------------------- enter:: NumpadEnter:: stringlen, m, MemoryNumbers if m < 3 return stringright, MemoryNumbers, MemoryNumbers, 3 stringleft, row, MemoryNumbers, 1 if row = 0 return stringmid, column, MemoryNumbers, 2, 1 if column = 0 return stringright, color, MemoryNumbers, 1 block := ceil(column/3) + 3 * ceil(row/3) - 3 if (field%column%%row% = 0 and HowOften(row%row%, color) = 0 and HowOften(column%column%, color) = 0 and HowOften(block%block%, color) = 0 or color = 0) { field%column%%row% = %color% NewSituation := FieldsToColors() MemoryBack = %MemoryBack%%NewSituation% MemoryForward = gosub FieldsToStatics } MemoryNumbers = return ;__________________________________________________________________________ ReactToClicksOnFieldsOrColors: IfWinNotActive, color-sudoku ahk_class AutoHotkeyGUI return GetKeyState, state, LButton if state <> D return WinGet, IdThisScript, ID, A MouseGetPos,,, IdWindow, control if (IdWindow <> IdThisScript) return loop, 111 if control = Static%a_index% { if (a_index <= 81) { ColumnIndex := mod(a_index, 9) if ColumnIndex = 0 ColumnIndex = 9 RowIndex := ceil(a_index/9) BlockIndex := ceil(ColumnIndex/3) + 3 * ceil(RowIndex/3) - 3 if (field%ColumnIndex%%RowIndex% = 0 and HowOften(row%RowIndex%, PointAtColor) = 0 and HowOften(column%ColumnIndex%, PointAtColor) = 0 and HowOften(block%BlockIndex%, PointAtColor) = 0 or field%ColumnIndex%%RowIndex% <> 0 and PointAtColor = 0) { field%ColumnIndex%%RowIndex% = %PointAtColor% NewSituation := FieldsToColors() MemoryBack = %MemoryBack%%NewSituation% MemoryForward = gosub FieldsToStatics } break } else if (92 <= a_index and a_index <= 101) { PointAt(a_index - 91) ShowWhat = colors gosub FieldsToStatics break } else if (102 <= a_index and a_index <= 111) { PointAt(a_index - 101) ShowWhat = numbers gosub FieldsToStatics break } } return ;__________________________________________________________________________ back: stringlen, MemLen, MemoryBack if MemLen > 81 { stringright, SituationNow, MemoryBack, 81 MemoryForward = %MemoryForward%%SituationNow% stringtrimright, MemoryBack, MemoryBack, 81 stringright, SituationBefore, MemoryBack, 81 ColorsToFields(SituationBefore) gosub FieldsToStatics } return ;__________________________________________________________________________ forward: stringlen, MemLen, MemoryForward if MemLen > 0 { stringright, NextSituation, MemoryForward, 81 ColorsToFields(NextSituation) gosub FieldsToStatics MemoryBack = %MemoryBack%%NextSituation% stringtrimright, MemoryForward, MemoryForward, 81 } return ;__________________________________________________________________________ FindOne: settimer, ReactToClicksOnFieldsOrColors, off gosub DisableButtons StartSituation := FieldsToColors() try = 0 TryIndex = 0 NoTryUntilNow = 1 loop, 999 { missing = 0 found = 0 loop, 9 { BlockIndex = %a_index% loop, 9 { ColorIndex = %a_index% if HowOften(block%BlockIndex%, ColorIndex) = 0 { missing += 1 HowManyPossibleFields = 0 PossibleField1 = PossibleField2 = loop, parse, block%BlockIndex%, | if %a_loopfield% = 0 ; if field is empty { StringMid, ColumnIndex, a_loopfield, 6, 1 StringRight, RowIndex, a_loopfield, 1 ; For example, if a_loopfield = field34, then ColumnIndex = 3 and RowIndex = 4. if HowOften(row%RowIndex%, ColorIndex) = 0 if HowOften(column%ColumnIndex%, ColorIndex) = 0 { HowManyPossibleFields += 1 PossibleField2 = %PossibleField1% PossibleField1 = %a_loopfield% } } if HowManyPossibleFields = 1 { %PossibleField1% = %ColorIndex% NewSituation := FieldsToColors() found = 1 if NoTryUntilNow = 1 { MemoryBack = %MemoryBack%%NewSituation% MemoryForward = gosub FieldsToStatics gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } else ifnotinstring, NewSituation, 0 ; there is no empty field { if %FindField1% = %FindColor% { ColorsToFields(StartSituation) %FindField1% = %FindColor% } else if %FindField2% = %FindColor% { ColorsToFields(StartSituation) %FindField2% = %FindColor% } NewSituation := FieldsToColors() MemoryBack = %MemoryBack%%NewSituation% MemoryForward = gosub FieldsToStatics gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } else if (HowManyPossibleFields = 2 and try = 1) { found = 1 try = 0 TryIndex += 1 if NoTryUntilNow = 1 { FindField1 = %PossibleField1% FindField2 = %PossibleField2% FindColor = %ColorIndex% } NoTryUntilNow = 0 %PossibleField1% = %ColorIndex% TrySituation%TryIndex% := FieldsToColors() %PossibleField1% = 0 %PossibleField2% = %ColorIndex% } else if (HowManyPossibleFields = 0 and TryIndex > 0) { found = 1 try = 0 ColorsToFields(TrySituation%TryIndex%) TryIndex -= 1 } else if HowManyPossibleFields = 0 { if NoTryUntilNow = 1 msgbox There is no solution, because color %ColorIndex% can not be set in block %BlockIndex%! else msgbox There is no solution! ColorsToFields(StartSituation) gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } } } if missing = 0 { gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } if found = 0 { if try = 0 try = 1 else if try = 1 { msgbox Too many possibilities! ColorsToFields(StartSituation) gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } } msgbox I don't understand! ColorsToFields(StartSituation) gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return ;__________________________________________________________________________ FindAll: settimer, ReactToClicksOnFieldsOrColors, off gosub DisableButtons StartSituation := FieldsToColors() try = 0 TryIndex = 0 loop, 999 { missing = 0 found = 0 loop, 9 { BlockIndex = %a_index% loop, 9 { ColorIndex = %a_index% if HowOften(block%BlockIndex%, ColorIndex) = 0 { missing += 1 HowManyPossibleFields = 0 PossibleField1 = PossibleField2 = loop, parse, block%BlockIndex%, | if %a_loopfield% = 0 ; if field is empty { StringMid, ColumnIndex, a_loopfield, 6, 1 StringRight, RowIndex, a_loopfield, 1 ; For example, if a_loopfield = field34, then ColumnIndex = 3 and RowIndex = 4. if HowOften(row%RowIndex%, ColorIndex) = 0 if HowOften(column%ColumnIndex%, ColorIndex) = 0 { HowManyPossibleFields += 1 PossibleField2 = %PossibleField1% PossibleField1 = %a_loopfield% } } if HowManyPossibleFields = 1 { %PossibleField1% = %ColorIndex% found = 1 gosub FieldsToStatics NewSituation := FieldsToColors() ifnotinstring, NewSituation, 0 ; there is no empty field { MemoryBack = %MemoryBack%%NewSituation% MemoryForward = gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } sleep 300 } else if (HowManyPossibleFields = 2 and try = 1) { found = 1 try = 0 TryIndex += 1 %PossibleField1% = %ColorIndex% TrySituation%TryIndex% := FieldsToColors() %PossibleField1% = 0 %PossibleField2% = %ColorIndex% gosub FieldsToStatics sleep 300 } else if (HowManyPossibleFields = 0 and TryIndex > 0) { found = 1 try = 0 ColorsToFields(TrySituation%TryIndex%) TryIndex -= 1 gosub FieldsToStatics sleep 300 } else if HowManyPossibleFields = 0 { msgbox There is no solution, because color %ColorIndex% can not be set in block %BlockIndex%! ColorsToFields(StartSituation) gosub FieldsToStatics gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } } } if missing = 0 { gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } if found = 0 { if try = 0 try = 1 else if try = 1 { msgbox Too many possibilities! ColorsToFields(StartSituation) gosub FieldsToStatics gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } } msgbox I don't understand! ColorsToFields(StartSituation) gosub FieldsToStatics gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return ;__________________________________________________________________________ RemoveAll: empty = loop, 81 empty = %empty%0 ColorsToFields(empty) gosub FieldsToStatics return ;__________________________________________________________________________ NewSudoku: ;-------------------------------------------------------------------------- ; select a sudoku NewSudokus = ( 000000007602054000000020806001700009000000060200030004709000001000140080000000400 050400370400005000020000000000090053500000018000020000008304000600900700001006090 002500380016000007800000000020000901005002000900005800107600000060420008090001000 004008500690200000000000802002000010700000000000000056400700030001602090060100705 100090002407000030805000010000650007002007600060030000003000904000001050000020078 908000000000028005000300000030000180100007000070090060000050270002009003000710090 036000001020000390400000000705604100000001005003075029100000040800000503060000700 000000000000034500000200060001002007509010308608000409200765003030000090006923700 003429001000080020000700000006004009040050080200600700007006000080040030900300500 020000006135000000040009050000095000000003400070160000013500080000000975200000060 100000000000456000003028700029000380008030090070000510006907200000043000000000000 000050067800020000500806000000504000004030100008900300080070210039185740000090000 740061000015870000000000000000000004123456009060010005070020543080030602090040701 000030008000274000001000500009800150000000040040510000030600070020000000005402090 ) fileread, OwnNewSudokus, %MyFolder%new sudokus.txt if OwnNewSudokus <> NewSudokus = %NewSudokus%%OwnNewSudokus% StringReplace, MemoryForward, NewSudokus, `n,, A StringReplace, MemoryForward, MemoryForward, `r,, A Sort, NewSudokus, Random stringleft, NewSudoku, NewSudokus, 81 MemoryBack = %MemoryBack%%NewSudoku% ;-------------------------------------------------------------------------- ; vary the sudoku NewSudoku := permuteColors(NewSudoku) MemoryBack = %MemoryBack%%NewSudoku% NewSudoku := sortThirds(sortThirds(part(NewSudoku,0,27)) sortThirds(part(NewSudoku,27,27)) sortThirds(part(NewSudoku,54,27))) MemoryBack = %MemoryBack%%NewSudoku% NewSudoku := rotate90(NewSudoku) MemoryBack = %MemoryBack%%NewSudoku% NewSudoku := sortThirds(sortThirds(part(NewSudoku,0,27)) sortThirds(part(NewSudoku,27,27)) sortThirds(part(NewSudoku,54,27))) MemoryBack = %MemoryBack%%NewSudoku% Random, r01, 0, 1 if (r01 == 0) { NewSudoku := rotate90(NewSudoku) MemoryBack = %MemoryBack%%NewSudoku% } ColorsToFields(NewSudoku) gosub FieldsToStatics return ;-------------------------------------------------------------------------- permuteColors(sud) { non := "a,b,c,d,e,f,g,h,i" sort, non, random, d, loop, 9 { repl := part(non, 2 * (a_index - 1), 1) StringReplace, sud, sud, %A_Index%, %repl%, All } loop, 9 { repl := part("abcdefghi", a_index - 1, 1) StringReplace, sud, sud, %repl%, %a_index%, All } return sud } ;-------------------------------------------------------------------------- ; Splits a string in 3 part-strings of equal length, ; sorts the part-strings by random and rejoins them: sortThirds(aString) { ter := "0,1,2" sort, ter, random, d, len := strlen(aString) / 3 return part(aString, part(ter,0,1) * len, len) part(aString, part(ter,2,1) * len, len) part(aString, part(ter,4,1) * len, len) } ;-------------------------------------------------------------------------- rotate90(sud) { newSud := "" Loop, 9 { outerIndex := A_Index Loop, 9 { newSud := newSud part(sud, 9 - outerIndex + (A_Index - 1) * 9, 1) } } return newSud } ;-------------------------------------------------------------------------- part(aString, from, count) { StringMid, result, aString, from + 1, count return result } ;__________________________________________________________________________ memorize: LastSudoku := FieldsToColors() filedelete, %MyFolder%last sudoku.txt fileappend, %LastSudoku%, %MyFolder%last sudoku.txt return ;__________________________________________________________________________ restore: fileread, LastSudoku, %MyFolder%last sudoku.txt if errorlevel = 0 { MemoryBack = %MemoryBack%%LastSudoku% MemoryForward = ColorsToFields(LastSudoku) gosub FieldsToStatics } return ;__________________________________________________________________________ TestMain: settimer, ReactToClicksOnFieldsOrColors, off gosub DisableButtons StartSituation := FieldsToColors() MemFieldsColors = try = 0 TryIndexMain = 0 BlockIndexes = 1/2/3/4/5/6/7/8/9 Sort, BlockIndexes, D/ Random loop, 999 { missing = 0 found = 0 loop, parse, BlockIndexes, / { BlockIndex = %a_loopfield% loop, 9 { ColorIndex = %a_index% if HowOften(block%BlockIndex%, ColorIndex) = 0 { missing += 1 HowManyPossibleFields = 0 PossibleField1 = PossibleField2 = loop, parse, block%BlockIndex%, | if %a_loopfield% = 0 ; if field is empty { StringMid, ColumnIndex, a_loopfield, 6, 1 StringRight, RowIndex, a_loopfield, 1 ; For example, if a_loopfield = field34, then ColumnIndex = 3 and RowIndex = 4. if HowOften(row%RowIndex%, ColorIndex) = 0 if HowOften(column%ColumnIndex%, ColorIndex) = 0 { HowManyPossibleFields += 1 PossibleField2 = %PossibleField1% PossibleField1 = %a_loopfield% } } if HowManyPossibleFields = 1 { %PossibleField1% = %ColorIndex% found = 1 NewSituation := FieldsToColors() ifnotinstring, NewSituation, 0 ; there is no empty field { gosub FieldsToStatics sleep 300 loop, %TryIndexMain% ; search for other solutions { ColorsToFields(TrySituationMain%a_index%) ThereIsASolution = 0 gosub TestSub if ThereIsASolution = 1 { MemFieldsColorsAIndex := MemFieldsColors%a_index% MemFieldsColors = %MemFieldsColors%%MemFieldsColorsAIndex% } } if MemFieldsColors <> { msgbox There are several solutions.`n`nYou can browse some possible next steps with the right-arrow-button. MemoryForward = Loop, Parse, MemFieldsColors, / if A_LoopField <> { StringRight, MemColor, A_LoopField, 1 StringTrimRight, MemField, A_LoopField, 1 ColorsToFields(StartSituation) %MemField% = %MemColor% MemSituation := FieldsToColors() MemoryForward = %MemoryForward%%MemSituation% } } else { msgbox, 260,, There is only one solution!`n`nDo you want to add this sudoku to %MyFolder%new sudokus.txt? ifmsgbox yes { fileappend, `n%StartSituation%, %MyFolder%new sudokus.txt if errorlevel = 0 msgbox This sudoku was added to %MyFolder%new sudokus.txt. } } ColorsToFields(StartSituation) gosub FieldsToStatics gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } else if (HowManyPossibleFields = 2 and try = 1) { found = 1 try = 0 TryIndexMain += 1 MemFieldsColors%TryIndexMain% = %PossibleField1%%ColorIndex%/%PossibleField2%%ColorIndex%/ %PossibleField1% = %ColorIndex% TrySituationMain%TryIndexMain% := FieldsToColors() %PossibleField1% = 0 %PossibleField2% = %ColorIndex% } else if (HowManyPossibleFields = 0 and TryIndexMain > 0) { found = 1 try = 0 ColorsToFields(TrySituationMain%TryIndexMain%) TryIndexMain -= 1 } else if HowManyPossibleFields = 0 { msgbox There is no solution, because color %ColorIndex% can not be set in block %BlockIndex%! ColorsToFields(StartSituation) gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } } } if missing = 0 { gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } if found = 0 { if try = 0 try = 1 else if try = 1 { ColorsToFields(StartSituation) msgbox, 260,, Too many possibilities!`n`nSet random %ShowWhat%? ifmsgbox yes { loop, 40 { random, row, 1, 9 random, column, 1, 9 random, color, 1, 9 block := ceil(column/3) + 3 * ceil(row/3) - 3 if (field%column%%row% = 0 and HowOften(row%row%, color) = 0 and HowOften(column%column%, color) = 0 and HowOften(block%block%, color) = 0) { field%column%%row% = %color% NewSituation := FieldsToColors() MemoryBack = %MemoryBack%%NewSituation% gosub FieldsToStatics } } } gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return } } } msgbox I don't understand! ColorsToFields(StartSituation) gosub EnableButtons settimer, ReactToClicksOnFieldsOrColors, on return ;__________________________________________________________________________ TestSub: try = 0 TryIndexSub = 0 loop, 999 { found = 0 loop, 9 { BlockIndex = %a_index% loop, 9 { ColorIndex = %a_index% if HowOften(block%BlockIndex%, ColorIndex) = 0 { HowManyPossibleFields = 0 PossibleField1 = PossibleField2 = loop, parse, block%BlockIndex%, | if %a_loopfield% = 0 ; if field is empty { StringMid, ColumnIndex, a_loopfield, 6, 1 StringRight, RowIndex, a_loopfield, 1 ; For example, if a_loopfield = field34, then ColumnIndex = 3 and RowIndex = 4. if HowOften(row%RowIndex%, ColorIndex) = 0 if HowOften(column%ColumnIndex%, ColorIndex) = 0 { HowManyPossibleFields += 1 PossibleField2 = %PossibleField1% PossibleField1 = %a_loopfield% } } if HowManyPossibleFields = 1 { %PossibleField1% = %ColorIndex% found = 1 NewSituation := FieldsToColors() ifnotinstring, NewSituation, 0 ; there is no empty field { gosub FieldsToStatics sleep 300 ThereIsASolution = 1 return } } else if (HowManyPossibleFields = 2 and try = 1) { found = 1 try = 0 TryIndexSub += 1 %PossibleField1% = %ColorIndex% TrySituationSub%TryIndexSub% := FieldsToColors() %PossibleField1% = 0 %PossibleField2% = %ColorIndex% } else if (HowManyPossibleFields = 0 and TryIndexSub > 0) { found = 1 try = 0 ColorsToFields(TrySituationSub%TryIndexSub%) TryIndexSub -= 1 } else if HowManyPossibleFields = 0 return } } } if found = 0 { if try = 0 try = 1 else if try = 1 return } } return ;__________________________________________________________________________ help: msgbox, ( Using the mouse: Choose %ShowWhat% by clicking on the %ShowWhat% or turning the mouse-wheel, set %ShowWhat% by clicking on the fields. To switch from colors to numbers/from numbers to colors, click on a number/a color. Using the keyboard: To set %ShowWhat%, press row-number, column-number, color-number, enter. The left-arrow-key and the right-arrow-key do the same as the left-arrow-button and the right-arrow-button. "new sudoku" contains 14 sudokus, made and tested using "test". You can make, test and add more sudokus using "test". "new sudoku" sets up a varied sudoku, the left-arrow-button displays the variations, the right-arrow-button displays the original sudokus. "memorize" stores the current situation in %MyFolder%last sudoku.txt. ) return ;__________________________________________________________________________ PointAt(number) { global WinGet, IdThisScript, ID, A MouseGetPos,,, IdWindow if (IdWindow <> IdThisScript) return if (number < 1 or number > 10) return PointAtButton = %number% PointAtColor = %number% if PointAtColor = 10 PointAtColor = 0 StaticIndex = 81 loop, 10 { StaticIndex += 1 GuiControl,, Static%StaticIndex% ; don't point at } StaticIndex := (81 + PointAtButton) GuiControl,, Static%StaticIndex%, à ; point at } ;__________________________________________________________________________ HowOften(RowOrColumnOrBlock, Color) { global count = 0 loop, parse, RowOrColumnOrBlock, | if %a_loopfield% = %Color% count += 1 return count } ;__________________________________________________________________________ FieldsToColors() { global Colors = loop, 9 { RowIndex = %a_index% loop, 9 { ColumnIndex = %a_index% Color := field%ColumnIndex%%RowIndex% Colors = %Colors%%Color% } } return Colors } ;__________________________________________________________________________ ColorsToFields(Colors) { global i = 0 loop, 9 { RowIndex = %a_index% loop, 9 { ColumnIndex = %a_index% i += 1 stringmid, Color, Colors, %i%, 1 field%ColumnIndex%%RowIndex% = %Color% } } } ;__________________________________________________________________________ FieldsToStatics: if ShowWhat = colors { i = 0 loop, 9 { RowIndex = %a_index% loop, 9 { ColumnIndex = %a_index% if field%ColumnIndex%%RowIndex% = 1 Gui, Font, s14 cwhite, webdings else if field%ColumnIndex%%RowIndex% = 2 Gui, Font, s14 cyellow, webdings else if field%ColumnIndex%%RowIndex% = 3 Gui, Font, s14 cFF7700, webdings else if field%ColumnIndex%%RowIndex% = 4 Gui, Font, s14 cred, webdings else if field%ColumnIndex%%RowIndex% = 5 Gui, Font, s14 cpurple, webdings else if field%ColumnIndex%%RowIndex% = 6 Gui, Font, s14 cblue, webdings else if field%ColumnIndex%%RowIndex% = 7 Gui, Font, s14 caqua, webdings else if field%ColumnIndex%%RowIndex% = 8 Gui, Font, s14 cgreen, webdings else if field%ColumnIndex%%RowIndex% = 9 Gui, Font, s14 cblack, webdings else if field%ColumnIndex%%RowIndex% = 0 Gui, Font, s14 cb0b0a0, webdings i += 1 GuiControl, Font, Static%i% GuiControl,, Static%i%, n } } } else if ShowWhat = numbers { Gui, Font, s18 c000000, arial i = 0 loop, 9 { RowIndex = %a_index% loop, 9 { ColumnIndex = %a_index% i += 1 GuiControl, Font, Static%i% if field%ColumnIndex%%RowIndex% = 1 GuiControl,, Static%i%, 1 else if field%ColumnIndex%%RowIndex% = 2 GuiControl,, Static%i%, 2 else if field%ColumnIndex%%RowIndex% = 3 GuiControl,, Static%i%, 3 else if field%ColumnIndex%%RowIndex% = 4 GuiControl,, Static%i%, 4 else if field%ColumnIndex%%RowIndex% = 5 GuiControl,, Static%i%, 5 else if field%ColumnIndex%%RowIndex% = 6 GuiControl,, Static%i%, 6 else if field%ColumnIndex%%RowIndex% = 7 GuiControl,, Static%i%, 7 else if field%ColumnIndex%%RowIndex% = 8 GuiControl,, Static%i%, 8 else if field%ColumnIndex%%RowIndex% = 9 GuiControl,, Static%i%, 9 else if field%ColumnIndex%%RowIndex% = 0 GuiControl,, Static%i%, } } } return ;__________________________________________________________________________ DisableButtons: guicontrol, disable, back guicontrol, disable, forward guicontrol, disable, FindOne guicontrol, disable, FindAll guicontrol, disable, RemoveAll guicontrol, disable, NewSudoku guicontrol, disable, memorize guicontrol, disable, restore guicontrol, disable, test guicontrol, disable, help return ;__________________________________________________________________________ EnableButtons: guicontrol, enable, back guicontrol, enable, forward guicontrol, enable, FindOne guicontrol, enable, FindAll guicontrol, enable, RemoveAll guicontrol, enable, NewSudoku guicontrol, enable, memorize guicontrol, enable, restore guicontrol, enable, test guicontrol, enable, help return