Decipher Posted November 13, 2012 Share Posted November 13, 2012 (edited) I've been working on this fun project for a few hours as it turns out its not so fun anymore. LOL but I'm determined. Does anyone got ideas why this isn't working? I know that there is a rule missing, I didn't get that far. Thanks for your help expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> #include <Array.au3> Opt("GUIOnEventMode", 1) ; My idea is that of a graph with x,y cordinates. One array points to the edit control handles the other their values while they wait to put inside the GUI. Dim $aSudoku[9][9], $aSudoku_Value[9][9][2] ; The reason this array was created is for two very goods reason, one to prevent unnecessary processing and two I need a fool proof way to distinguish between fixed values. Dim $iDemension = 0, $iIndex = 0 ;;;The first index numbers for the control array. ;$Sudoku_Solved = False ; $iDemension is just a variable name. The $aSudoku array is only 2D name value pairs AdlibRegister("_Populate_Sudoku", 250) ; This function reads numbers from the $aSudoku_Value 3D array and puts them inside the edit controls #region ### START Koda GUI section ### Form= $Sudoku = GUICreate("Sudoku Solution Calculator", 335, 340) ; Create Sudoku GUI Dim $iLeft = 10, $iTop = 10 ; Intial cordinates for the first edit control - box. For $i = 1 To 81 Step 1 ; The games calls for a graph that consists of 81 squares = 9x9 $aSudoku[$iDemension][$iIndex] = GUICtrlCreateEdit("", $iLeft, $iTop, 35, 35, BitOR("", $ES_CENTER)) GUICtrlSetState(-1, @SW_LOCK) GUICtrlSetFont(-1, 16, 700, "Arial Black") GUICtrlSetBkColor(-1, 0xFFFFFF) GUICtrlSetColor(-1, 000000) $iLeft += 35 ; for each iteration step or move the new box 35 px to the right. $iIndex += 1 ; $iIndex is only from 0 to 8 until $i reaches a multiple of 9 For $iAdjust = 1 To 9 Step 1 If $iAdjust * 9 = $i Then $iIndex = 0 ; reset the index to 0 for enumerating another row through columns I think...lmao, it works $iDemension += 1 ; changes to the next row $iLeft = 10 ; reset the pos for another row. $iTop += 35 ; bring the position on the new row down a notch as necessary. EndIf Next Next _Create_Fixed_Value(0, 2, 4) ; Param1 = x cord, Param2 = y cord, Param3 = fixed number who's value should not change during execution. _Create_Fixed_Value(0, 3, 2) _Create_Fixed_Value(0, 4, 6) _Create_Fixed_Value(0, 6, 1) _Create_Fixed_Value(1, 6, 2) _Create_Fixed_Value(1, 7, 6) _Create_Fixed_Value(2, 0, 5) _Create_Fixed_Value(2, 3, 1) _Create_Fixed_Value(2, 5, 3) _Create_Fixed_Value(2, 6, 8) _Create_Fixed_Value(2, 8, 9) _Create_Fixed_Value(3, 1, 5) _Create_Fixed_Value(3, 2, 6) _Create_Fixed_Value(3, 3, 8) _Create_Fixed_Value(3, 7, 2) _Create_Fixed_Value(3, 8, 7) _Create_Fixed_Value(4, 3, 7) _Create_Fixed_Value(4, 5, 5) _Create_Fixed_Value(5, 0, 9) _Create_Fixed_Value(5, 1, 7) _Create_Fixed_Value(5, 5, 4) _Create_Fixed_Value(5, 6, 5) _Create_Fixed_Value(5, 7, 3) _Create_Fixed_Value(6, 0, 6) _Create_Fixed_Value(6, 2, 5) _Create_Fixed_Value(6, 3, 9) _Create_Fixed_Value(6, 5, 2) _Create_Fixed_Value(6, 8, 8) _Create_Fixed_Value(7, 1, 2) _Create_Fixed_Value(7, 2, 7) _Create_Fixed_Value(8, 2, 1) _Create_Fixed_Value(8, 4, 5) _Create_Fixed_Value(8, 5, 6) _Create_Fixed_Value(8, 6, 7) GUISetState(@SW_SHOW) ; show the GUI #endregion ### END Koda GUI section ### GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_Sudoku") ; register the exit function While 1 If Not IsComplete() Then _Random_Evalulation() ; randomly populate squares with numbers that do not conflict. Sleep(50) WEnd Func _Exit_Sudoku() Exit EndFunc ;==>_Exit_Sudoku ; obviously there is a problem with randomizing instead of a programmatic educated quess. Func _TryDigit($aSquare, $iDigit) ; Generate random digit and check for duplication - as to follow the instructions on solving the puzzle. If $aSudoku_Value[$aSquare[0]][$aSquare[1]][1] = False Then ; this line checks to see if the index contains a fixed number if not than set the value to the random digit. $aSudoku_Value[$aSquare[0]][$aSquare[1]][0] = $iDigit EndIf Local $iHorizontal = _Horizontal_Valid($aSquare, $iDigit) ; this function will return the one of the indexes to the array contain a handle to a duplicate upon failure. Local $iVertical = _Vertical_Valid($aSquare, $iDigit) If $iHorizontal = "" And $iVertical = "" Then Return True ElseIf $iHorizontal <> "" Then $aSquare[1] = $iHorizontal For $iDigit = 1 To 9 If _Horizontal_Valid($aSquare, $iDigit) = "" Then ExitLoop If $iDigit = 9 Then $aSudoku_Value[$aSquare[0]][$aSquare[1]][0] = "" Next ElseIf $iVertical <> "" Then $aSquare[0] = $iVertical For $iDigit = 1 To 9 If _Vertical_Valid($aSquare, $iDigit) = "" Then ExitLoop If $iDigit = 9 Then $aSudoku_Value[$aSquare[0]][$aSquare[1]][0] = "" Next EndIf EndFunc ;==>_TryDigit Func _Empty_Sudoku() ; empty the contents of the value array except for the fixed numbers. For $iCtrl = 0 To 8 Step 1 For $iCtrl_Index = 0 To 8 Step 1 If $aSudoku_Value[$iCtrl][$iCtrl_Index][1] = False Then $aSudoku_Value[$iCtrl][$iCtrl_Index][0] = "" EndIf Next Next EndFunc ;==>_Empty_Sudoku Func IsComplete() Local $aSquare[2] For $aSquare[0] = 0 To 8 Step 1 For $aSquare[1] = 0 To 8 Step 1 If $aSudoku_Value[$aSquare[0]][$aSquare[1]][1] = False Then If _Horizontal_Valid($aSquare, $aSudoku_Value[$aSquare[0]][$aSquare[1]][0]) <> "" Or _Vertical_Valid($aSquare, $aSudoku_Value[$aSquare[0]][$aSquare[1]][0]) <> "" Then Return False EndIf Next Next EndFunc ;==>IsComplete Func _Horizontal_Valid($aSquare, $iDigit) For $iSquare = 0 To 8 If $aSquare[1] <> $iSquare Then If $aSudoku_Value[$aSquare[0]][$iSquare][0] = $iDigit Then If $aSudoku_Value[$aSquare[0]][$iSquare][1] = False Then Return $iSquare Return $aSquare[1] EndIf EndIf Next Return "" EndFunc ;==>_Horizontal_Valid Func _Vertical_Valid($aSquare, $iDigit) For $iSquare = 0 To 8 If $aSquare[0] <> $iSquare Then If $aSudoku_Value[$iSquare][$aSquare[1]][0] = $iDigit Then If $aSudoku_Value[$iSquare][$aSquare[1]][1] = False Then Return $iSquare Return $aSquare[0] EndIf EndIf Next Return "" EndFunc ;==>_Vertical_Valid Func _Random_Evalulation() _Empty_Sudoku() For $i = 1 To 100 Step 1 While 1 $aSquare = _Random_Square() If Not IsPopulated($aSquare) Then ExitLoop WEnd For $iDigit = 1 To 9 If _TryDigit($aSquare, $iDigit) Then ExitLoop If $iDigit = 9 Then $aSudoku_Value[$aSquare[0]][$aSquare[1]][0] = "" Next Next EndFunc ;==>_Random_Evalulation Func _Random_Square() ; take note of what this function is doing and is pretty straight forward as to whats being done. Local $aCord[2] = [Int(Random(0, 9)), Int(Random(0, 9))] Return $aCord EndFunc ;==>_Random_Square Func _Populate_Sudoku() For $iCtrl = 0 To 8 Step 1 For $iCtrl_Index = 0 To 8 Step 1 If $aSudoku_Value[$iCtrl][$iCtrl_Index][0] <> "" And $aSudoku_Value[$iCtrl][$iCtrl_Index][1] = False Then If $aSudoku_Value[$iCtrl][$iCtrl_Index][0] <> GUICtrlRead($aSudoku[$iCtrl][$iCtrl_Index]) Then GUICtrlSetData($aSudoku[$iCtrl][$iCtrl_Index], $aSudoku_Value[$iCtrl][$iCtrl_Index][0]) EndIf EndIf Next Next EndFunc ;==>_Populate_Sudoku Func _Create_Fixed_Value($X, $Y, $iValue) $aSudoku_Value[$X][$Y][0] = $iValue ; the 0 index contains the number values $aSudoku_Value[$X][$Y][1] = True ; is this last index is set to true then its a fixed value otherwise the value is automatically false. GUICtrlSetData($aSudoku[$X][$Y], $aSudoku_Value[$X][$Y][0]) GUICtrlSetColor($aSudoku[$X][$Y], 0xFF0000) ; paint them red. ;$sFixed_Values += "{" & $X & "," & $Y & "}" ; this line is redundant; I should have removed this when I converted to a 3d array for distinguishing between them. EndFunc ;==>_Create_Fixed_Value Func IsPopulated($aSquare) ; I don't think this works but run this thing and see what happens. I have successfully generated a correct answering following the row and column rules only once but the harder I try the worst it runs. ;I think I need to change tactics. Thanks for reading and suggestion. If $aSudoku_Value[$aSquare[0]][$aSquare[1]][0] <> "" Then Return True EndFunc ;==>IsPopulated Sorry, I couldn't get the tidied code inserted properly. But uh this isn't that complicated... Edited November 13, 2012 by Decipher Spoiler Link to comment Share on other sites More sharing options...
MvGulik Posted November 13, 2012 Share Posted November 13, 2012 why this isn't working?General suggestion: Be a bit more specific in what it is doing wrong, and what it is your expecting it to do instead. "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
Decipher Posted November 13, 2012 Author Share Posted November 13, 2012 Sudoku rules- Sudoku is played over a 9x9 grid, divided to 3x3 sub grids called "regions":- Sudoku begins with some of the grid cells already filled with numbers:- The object of Sudoku is to fill the other empty cells with numbers between 1 and 9 (1 number only in each cell) according the following guidelines:1. Number can appear only once on each row2. Number can appear only once on each column: Allowed Not allowed 3. Number can appear only once on each region: Allowed Not allowed - A summary of these guidelines would be, that a number should appear only once on each row, column and a region.I can edit the initial post with code comments if necessary.I have attempted to populate a box with fixed numbers that followed the rules with exception to the 3x3 region rule.It does not work. I question my methods. I'm hoping that someone can offer some helpful advice.Thanks Spoiler Link to comment Share on other sites More sharing options...
JohnOne Posted November 13, 2012 Share Posted November 13, 2012 First there is syntax error, second change GUICtrlSetOnEvent($GUI_EVENT_CLOSE, "_Exit_Sudoku") ; register the exit function To GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_Sudoku") ; register the exit function AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Decipher Posted November 13, 2012 Author Share Posted November 13, 2012 (edited) Thanks, I was wondering why I couldn't hit the "X". Lol I should've caught that. The problem is that my script is not coming close to solving the puzzle with just the first two rules in places. Edited November 13, 2012 by Decipher Spoiler Link to comment Share on other sites More sharing options...
JohnOne Posted November 14, 2012 Share Posted November 14, 2012 If you leave it running for 1 billion years or 3 it might solve, because it is entirely random. It's like the monkies writing a shakespear novel cliche. For a starting point, look at what numbers are being tried in 1 row and colum for example row 1 colum 1, do you see a number being tried that is already a fixed number in both the row and the colum? because I do. You might want to check for that. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
czardas Posted November 14, 2012 Share Posted November 14, 2012 (edited) I'll tell you what is wrong - your AI is totally random (that's the problem - which John identified as I was writing this). Start by identifying candidate values for each available square. Perhaps you could start with a 9x9x7 cube and fill the third dimension with candidate values, then take it from there. Edited November 14, 2012 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
JohnOne Posted November 14, 2012 Share Posted November 14, 2012 (edited) Also, you might want to think about whether your fixed numbers are actually solvable. For an exercise, first try to create a filled valid sudoku grid from scratch which is started with a random seed in one square. EDIT: which I think is what czardas just said. Edited November 14, 2012 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
MvGulik Posted November 14, 2012 Share Posted November 14, 2012 http://en.wikipedia.org/wiki/Sudoku_algorithms "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
JohnOne Posted November 14, 2012 Share Posted November 14, 2012 I was going to post a link but suspect this is an exercise in logic. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
BrewManNH Posted November 14, 2012 Share Posted November 14, 2012 You might get a few ideas from that Mat posted a few years ago for a Sudoku solver script. Or even this batch file that supposedly solves the puzzles. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
czardas Posted November 14, 2012 Share Posted November 14, 2012 (edited) My idea may not be the best approach but it's interesting to consider. I now see that my 9x9x7 cube (based on the above puzzle) would have to be 9x9x10 (after looking at the variety of examples). The first grid would hold the puzzle and the remaining 9 grids would hold all possible missing values. Any field intersected by a completely empty row and (empty) column would have 9 possible candidate values (with entries through grids 1 to 9). Next I would look for an empty field with the least number of candidate solutions and start to build a tree of possible solutions. The branches that lead nowhere may need to be cleared from memory as you go. It could take a long time. Edited November 14, 2012 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Decipher Posted November 14, 2012 Author Share Posted November 14, 2012 Thanks for all the useful information m8s. This is absolutely an exercise in logic. While working an 12 hour grave-yard shift I've decided on a new system for generating the solutions. The code above is illogical as it is generates and attempts to validate digits at random this only adds to the number of possibilities and as JohnOne Stated it could take a tremendous amount of time and never once come close to solving the puzzle. I'm now going to use a Fixed System: Requiring two more 2D arrays - one horizontal and the other vertical where the structure is outlined below: Global $Fixed_Horizontal[9][4] Horizontal 9x4 should contain each rows information or if you will its probabillity - this is what the count is for. ----------------------------------------------------------------------- |Rows 0 to 8|Fixed Digits|Possible Digits|Available Count| ----------------------------------------------------------------------- For ex. lets say row 5 which would be in my array system index 4 because of the zero based arrays, contains the fixed digits "456987" then the Possible digits in Global $Fixed_Horizontal[4][2] would contain "123" and the available count is 3. Knowing the available count is in my logic is the same as the knowing probability of finding what I call a Fixed number. Using min/max functions I can determine the row or column to be analyzed firstly. Then the digit to be checked against the other digits must be an available digit. I would then iterate through all of the available sectors counting the conflicts storing the last non conflict coordinate in a variable. If the (duplicate)conflict counter is one less than the available count then I know the number is a valid addiction to the Fixed number set and should be treated as such making is value permanent. Removing the digit from the Possible and Available indexes and adding it to the Digits in a Row. If the difference is not valid meaning more than one then it will not be placed and It will then continue to check the next available digit in the available set otherwise the probability check will run again selecting a new row or column to analyze, more likely it will be the same row or column selected because there is once less possibility and therefore greater chance of determining a Fixed number. What should be done when a row or column that is select for analyzes based on probability does not have a valid addition to make to the Fixed Number set? Suggestions? Then that would be the completion of the first check the second which will be executed when there are no possible valid additions to be made and should make educated guesses on probability. I have ideas for this but offer your own if you wish. Concerning the first two rules I think this system will in most cases succeed if there are enough starting fixed numbers. The third rule would work in the same way with a third array. I will post code when its written. I note that Mat has allegedly already succeeded in making a similar script. This is for fun so I will not be viewing or asking anyone for code but suggestions and other helpful information is greatly appreciated. Thanks Spoiler Link to comment Share on other sites More sharing options...
MvGulik Posted November 14, 2012 Share Posted November 14, 2012 (edited) Mmm, looked around for some Sudoku strings (as solver input cases). But they seem not that common (probably using wrong search parameters).Anyway, did found this one: http://forum.enjoysudoku.com/patterns-game-results-t6291.htmlMight be of some use. (don't forget to browse that forum, as its a Sudoku forum ... like anyone might miss that. ) Edited November 14, 2012 by MvGulik "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
jdelaney Posted November 15, 2012 Share Posted November 15, 2012 (edited) I created this, it can solve the easy puzzles...i'll add additional functions within the loop to recursivly guess (when out of known answers)...the file that is created on the fly includes an easy puzzle, that will be solved UPDATE:: added logic to attempt guesses, but only one at a time, so if the guess (all possible single attempt guesses) fails, then script fails...real fun to watch it try though ...(will add logic for a second guess later...need to make that dynamic to allow infinite, valid guesses) The gauntlet was thrown, beat in fewer lines if you can expandcollapse popup#include <Array.au3> #include <File.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Global $sDifficulty_Easy = "Easy" Global $sDifficulty_Med = "Med" Global $sDifficulty_Hard = "Hard" Global $sDifficulty_Default = $sDifficulty_Hard Global $gsFILE_Puzzle = @ScriptDir & "Puzzle_" & $sDifficulty_Default & ".txt" Global Enum $giPuzzle_Y1D_0 = 0, _ $giPuzzle_Y1D_1, _ $giPuzzle_Y1D_2, _ $giPuzzle_Y1D_3, _ $giPuzzle_Y1D_4, _ $giPuzzle_Y1D_5, _ $giPuzzle_Y1D_6, _ $giPuzzle_Y1D_7, _ $giPuzzle_Y1D_8, _ $giPuzzle_Y1D_UBound Global Enum $giPuzzle_X2D_0 = 0, _ $giPuzzle_X2D_1, _ $giPuzzle_X2D_2, _ $giPuzzle_X2D_3, _ $giPuzzle_X2D_4, _ $giPuzzle_X2D_5, _ $giPuzzle_X2D_6, _ $giPuzzle_X2D_7, _ $giPuzzle_X2D_8, _ $giPuzzle_X2D_UBound Global Enum $giPuzzle_3D_Known = 0, _ $giPuzzle_3D_aPossible, _ $giPuzzle_3D_KnownGuess, _ $giPuzzle_3D_aGuessPossible, _ $giPuzzle_3D_Control, _ $giPuzzle_3D_UBound Global $gaPuzzle[$giPuzzle_Y1D_UBound][$giPuzzle_X2D_UBound][$giPuzzle_3D_UBound] Global $gaPossible[9]=[1,2,3,4,5,6,7,8,9] ; Add possible to all cells For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] = $gaPossible Next Next $bExists = FileExists ($gsFILE_Puzzle) If $bExists Then $gaPuzzle = GenerateFILEPuzzle($gaPuzzle) Else $gaPuzzle = GenerateRandomPuzzle($gaPuzzle) ; Currently, creating a fixed puzzle EndIf If GuiCreateCurrent() Then MsgBox (1,1,"SOVLED!") Else MsgBox (1,1,"Failed!") EndIf While True $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Exit WEnd Func GenerateRandomPuzzle($aCallersArray) _FileCreate ( $gsFILE_Puzzle ) $hFile = FileOpen ( $gsFILE_Puzzle, 2 ) Switch $sDifficulty_Default Case $sDifficulty_Easy, $sDifficulty_Med FileWrite ( $hFile, "2,9,,,,,8,," & @CRLF & _ "8,5,,4,,1,3,7," & @CRLF & _ ",,,,3,,,," & @CRLF & _ ",3,,,,2,,5,6" & @CRLF & _ ",4,,3,9,7,,1," & @CRLF & _ "1,2,,5,,,,3," & @CRLF & _ ",,,,1,,,," & @CRLF & _ ",6,4,9,,8,,2,3" & @CRLF & _ ",,7,,,,,8,5" ) Case $sDifficulty_Hard FileWrite ( $hFile, ",6,,,9,8,,1," & @CRLF & _ "2,,,1,,,,5," & @CRLF & _ ",,,,4,,,," & @CRLF & _ "6,,,,,5,,9," & @CRLF & _ ",,3,8,,9,7,," & @CRLF & _ ",1,,2,,,,,8" & @CRLF & _ ",,,,,4,,," & @CRLF & _ ",2,,,,3,,,9" & @CRLF & _ ",3,,9,2,,,6," ) EndSwitch FileClose ( $hFile ) Local $aTemp[1] _FileReadToArray ( $gsFILE_Puzzle, $aTemp ) _ArrayDelete ( $aTemp, 0 ) For $y1D = 0 To UBound ( $aTemp ) - 1 $aTemp2 = StringSplit ( $aTemp[$y1D], "," ) _ArrayDelete ( $aTemp2, 0 ) For $x2D = 0 To UBound ( $aTemp2 ) - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] = $aTemp2[$x2D] Next Next ; Clear out possible array For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2d = 0 To $giPuzzle_X2D_UBound - 1 If $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] > 0 Then $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] = "" Next Next Return $gaPuzzle EndFunc Func GenerateFILEPuzzle($aCallersArray) Local $aTemp[1] _FileReadToArray ( $gsFILE_Puzzle, $aTemp ) _ArrayDelete ( $aTemp, 0 ) For $y1D = 0 To UBound ( $aTemp ) - 1 $aTemp2 = StringSplit ( $aTemp[$y1D], "," ) _ArrayDelete ( $aTemp2, 0 ) For $x2D = 0 To UBound ( $aTemp2 ) - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] = $aTemp2[$x2D] Next Next ; Clear out possible array For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2d = 0 To $giPuzzle_X2D_UBound - 1 If $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] > 0 Then $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] = "" Next Next Return $gaPuzzle EndFunc Func GuiCreateCurrent () $iControlHeight = 15 $iControlWidth = 15 $iControlBuffer = 10 $iGuiWidth = $iControlBuffer+(($iControlWidth+$iControlBuffer)*$giPuzzle_X2D_UBound) $iGuiHeight = $iControlBuffer+(($iControlWidth+$iControlBuffer)*$giPuzzle_Y1D_UBound) Global $hGui = GUICreate ( @ScriptName, $iGuiWidth, $iGuiHeight ) For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2d = 0 To $giPuzzle_X2D_UBound - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Control] = GUICtrlCreateLabel ( $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known], $iControlBuffer+(($x2D)*($iControlWidth+$iControlBuffer)), $iControlBuffer+(($y1D)*($iControlWidth+$iControlBuffer)), $iControlWidth, $iControlHeight, BitOR($SS_SUNKEN,$SS_CENTER) ) Switch $y1D Case 0 To 2, 6 To 8 If $x2D < 3 Or $x2D > 5 Then GUICtrlSetBkColor ( -1, 0x00ff00 ) Case 3 To 5 If $x2D > 2 And $x2D < 6 Then GUICtrlSetBkColor ( -1, 0x00ff00 ) EndSwitch Next Next GUISetState(@SW_SHOW) $bReturn_GuiCreateCurrent = False MsgBox ( 1,1,"Solve on close of this msgbox") Global $iGuessCounter = 0 While True $msg = GUIGetMsg() While FillInEasyAndRemoveKnown() WEnd ; Check if number is only available in a section once...that is by default, correct If FillInWhenOnlyOneCellInSectionHasPossibleNumber() Then ContinueLoop If FillInWhenOnlyOneCellInColHasPossibleNumberX() Then ContinueLoop If FillInWhenOnlyOneCellInRowHasPossibleNumberY() Then ContinueLoop ; Last resort...guess, and attempt to fill all in based on the guess ; Guess fills in known values to KnownGuess, and checks if all are filled to return true While Not Guess() $iGuessCounter += 1 Wend If CheckIfWon() Then $bReturn_GuiCreateCurrent = True ExitLoop EndIf If $msg = $GUI_EVENT_CLOSE Then Exit WEnd Return $bReturn_GuiCreateCurrent EndFunc Func FillInEasyAndRemoveKnown ($bGuess=False) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf $bReturn_FillInEasyAndRemoveKnown = False ; Clear out possible array of row and column For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known]) > 0 Then RemoveYRowPossibility($y1D, $gaPuzzle[$y1D][$x2D][$iKnown],$bGuess) RemoveXColPossibility($x2D, $gaPuzzle[$y1D][$x2D][$iKnown],$bGuess) EndIf Next Next ; Clear out possiblity of section For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 ; Only enter if known $iTempKnown = $gaPuzzle[$y1D][$x2D][$iKnown] If StringLen ($iTempKnown) = 0 Then ContinueLoop Switch $y1D Case 0 To 2 $yStart = 0 Case 3 To 5 $yStart = 3 Case 6 To 8 $yStart = 6 EndSwitch Switch $x2D Case 0 To 2 $xStart = 0 Case 3 To 5 $xStart = 3 Case 6 To 8 $xStart = 6 EndSwitch For $y = $yStart To $yStart+2 For $x = $xStart To $xStart+2 ; Skip current case If $y = $y1D And $x = $x2D Then ContinueLoop RemoveCellPossibility($y,$x,$iTempKnown,$bGuess) Next Next Next Next ; Loop through all, and find where possible ubound = 1...that is now known...if found, return true...if none found, return false For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iKnown])=0 Then $aTemp = $gaPuzzle[$y1D][$x2D][$iaPossible] If UBound ( $aTemp ) = 1 Then UpdateGuiWithKnownValue($y1D,$x2D,$aTemp[0],$bGuess) Return True EndIf EndIf Next Next Return $bReturn_FillInEasyAndRemoveKnown EndFunc Func RemoveYRowPossibility ($iCallersYValue, $iCallersKnownValue, $bGuess=False) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf For $i = 0 To $giPuzzle_X2D_UBound - 1 $aTemp = $gaPuzzle[$iCallersYValue][$i][$iaPossible] $iDeleteValue = _ArraySearch ( $aTemp, $iCallersKnownValue ) If $iDeleteValue >= 0 Then _ArrayDelete ( $aTemp, $iDeleteValue ) $gaPuzzle[$iCallersYValue][$i][$iaPossible] = $aTemp Next EndFunc Func RemoveXColPossibility ($iCallersXValue, $iCallersKnownValue, $bGuess = False) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf For $i = 0 To $giPuzzle_Y1D_UBound - 1 $aTemp = $gaPuzzle[$i][$iCallersXValue][$iaPossible] $iDeleteValue = _ArraySearch ( $aTemp, $iCallersKnownValue ) If $iDeleteValue >= 0 Then _ArrayDelete ( $aTemp, $iDeleteValue ) $gaPuzzle[$i][$iCallersXValue][$iaPossible] = $aTemp Next EndFunc Func RemoveCellPossibility ($iCallersYValue, $iCallersXValue, $iCallersKnownValue, $bGuess = False ) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf $aTemp = $gaPuzzle[$iCallersYValue][$iCallersXValue][$iaPossible] $iDeleteValue = _ArraySearch ( $aTemp, $iCallersKnownValue ) If $iDeleteValue >= 0 Then _ArrayDelete ( $aTemp, $iDeleteValue ) $gaPuzzle[$iCallersYValue][$iCallersXValue][$iaPossible] = $aTemp EndFunc Func UpdateGuiWithKnownValue ($iCallersYValue, $iCallersXValue, $iCallersKnownValue, $bGuess = False) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf $gaPuzzle[$iCallersYValue][$iCallersXValue][$iKnown] = $iCallersKnownValue $gaPuzzle[$iCallersYValue][$iCallersXValue][$iaPossible] = "" GUICtrlSetData ( $gaPuzzle[$iCallersYValue][$iCallersXValue][$giPuzzle_3D_Control], $gaPuzzle[$iCallersYValue][$iCallersXValue][$iKnown] ) EndFunc Func FillInWhenOnlyOneCellInSectionHasPossibleNumber ($bGuess=False) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf $bReturn_FillInWhenOnlyOneCellInSectionHasPossibleNumber = False ; loop through number until a section returns only 1 possibility for that number...return true after setting For $iNumber = 1 To 9 ; Reset counter ; Loops to allow increasing conditional bounds $iYMin = 0 $iYMax = 2 For $y = 0 To 2 $iXMin = 0 $iXMax = 2 For $x = 0 To 2 $iTempSectionCounter = 9 ; decided to go section by section...too tird to logically do in one loop $bContinueLoop = True For $y1D = $iYMin To $iYMax For $x2D = $iXMin To $iXMax If $gaPuzzle[$y1D][$x2D][$iKnown]=$iNumber Then $bContinueLoop = False $iTempSectionCounter = 0 Else If StringLen ($gaPuzzle[$y1D][$x2D][$iKnown]) > 0 Or _ArraySearch ( $gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber ) < 0 Then $iTempSectionCounter-=1 EndIf EndIf If Not $bContinueLoop Then ExitLoop Next If Not $bContinueLoop Then ExitLoop Next If $iTempSectionCounter = 1 Then For $y1D = $iYMin To $iYMax For $x2D = $iXMin To $iXMax If _ArraySearch ( $gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber ) >= 0 Then UpdateGuiWithKnownValue($y1D,$x2D,$iNumber,$bGuess) Return True EndIf Next Next EndIf ; Current section didn't include any $iXMin += 3 $iXMax += 3 Next $iYMin += 3 $iYMax += 3 Next Next Return $bReturn_FillInWhenOnlyOneCellInSectionHasPossibleNumber EndFunc Func FillInWhenOnlyOneCellInColHasPossibleNumberX ($bGuess=False) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf $bReturn_FillInWhenOnlyOneCellInColHasPossibleNumberX = False For $iNumber = 1 To 9 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 $bContinueLoop = True $iTempColumnCounter = 9 For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 If StringLen ($gaPuzzle[$y1D][$x2D][$iKnown]) > 0 Or _ArraySearch ( $gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber ) < 0 Then $iTempColumnCounter-=1 EndIf Next If $iTempColumnCounter = 1 Then ExitLoop Next If $iTempColumnCounter = 1 Then For $x2D = $x2D To $x2D For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 If _ArraySearch ( $gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber ) >= 0 Then UpdateGuiWithKnownValue($y1D,$x2D,$iNumber,$bGuess) Return True EndIf Next Next EndIf Next Return $bReturn_FillInWhenOnlyOneCellInColHasPossibleNumberX EndFunc Func FillInWhenOnlyOneCellInRowHasPossibleNumberY ($bGuess=False) If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible Else $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible EndIf $bReturn_FillInWhenOnlyOneCellInRowHasPossibleNumberY = False For $iNumber = 1 To 9 For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 $bContinueLoop = True $iTempRowCounter = 9 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen ($gaPuzzle[$y1D][$x2D][$iKnown]) > 0 Or _ArraySearch ( $gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber ) < 0 Then $iTempRowCounter-=1 EndIf Next If $iTempRowCounter = 1 Then ExitLoop Next If $iTempRowCounter = 1 Then For $y1D = $y1D To $y1D For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If _ArraySearch ( $gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber ) >= 0 Then UpdateGuiWithKnownValue($y1D,$x2D,$iNumber,$bGuess) Return True EndIf Next Next EndIf Next Return $bReturn_FillInWhenOnlyOneCellInRowHasPossibleNumberY EndFunc Func Guess() ; Blindly use the first avail array possibility that matches $iGuessCounter...attempt to solve...if not, false (outside function the guess counter increments, and attempts again) Local $iTempGuessCounter = $iGuessCounter If CheckIfWon (False) Then Return True ConsoleWrite ( "GuessCounter=[" & $iGuessCounter & "]" ) ; Clear out all known guesses, and reset availguess array to possible array For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$giPuzzle_3D_KnownGuess])>0 And StringLen($gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known])=0 Then GUICtrlSetData ( $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Control], "" ) EndIf $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_KnownGuess] = $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aGuessPossible] = $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] Next Next ; Check if already won If CheckIfWon (True) Then Return True ; Loop Through until an element is found matching the current $iGuessCounter $bGuessFound = False For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 $aTemp = $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] If UBound ($aTemp) - 1 < $iTempGuessCounter Then If IsArray ( $aTemp ) Then $iTempGuessCounter -= (UBound ($aTemp) - 1) EndIf Else $iGuessNumber = $aTemp[$iTempGuessCounter] $bGuessFound = True UpdateGuiWithKnownValue ($y1D,$x2D,$iGuessNumber,True) ConsoleWrite ( "; Start with Number=[" & $iGuessNumber & "] x|y=[" & $x2D & "|" & $y1D & "]" & @CRLF ) ; Need to remove the guess number from guess possible array Switch $y1D Case 0 To 2 $iYStart = 0 Case 3 To 5 $iYStart = 3 Case 6 To 8 $iYStart = 6 EndSwitch Switch $x2D Case 0 To 2 $iXStart = 0 Case 3 To 5 $iXStart = 3 Case 6 To 8 $iXStart = 6 EndSwitch For $iY = $iYStart To $iYStart+2 For $iX = $iXStart To $iXStart+2 $aTemp2 = $gaPuzzle[$iY][$iX][$giPuzzle_3D_aGuessPossible] $iDeleteValue = _ArraySearch ( $aTemp2, $iGuessNumber ) If $iDeleteValue >= 0 Then _ArrayDelete ( $aTemp2, $iDeleteValue ) $gaPuzzle[$iY][$iX][$giPuzzle_3D_aGuessPossible] = $aTemp2 Next Next EndIf If $bGuessFound Then ExitLoop Next If $bGuessFound Then ExitLoop Next If Not $bGuessFound Then MsgBox (1,1,"All Single attempt guesses tried, and failed") Exit EndIf ; Perform same loops to check for guess fits While True $msg = GUIGetMsg() While FillInEasyAndRemoveKnown(True) WEnd ; Check if number is only available in a section once...that is by default, correct If FillInWhenOnlyOneCellInSectionHasPossibleNumber(True) Then ContinueLoop If FillInWhenOnlyOneCellInColHasPossibleNumberX(True) Then ContinueLoop If FillInWhenOnlyOneCellInRowHasPossibleNumberY(True) Then ContinueLoop ;~ ; Currently only doing one guess at a time, or resetting ;~ ; Last resort...guess, and attempt to fill all in based on the guess ;~ ; Guess fills in known values to KnownGuess, and checks if all are filled to return true ;~ While Not Guess() ;~ $iGuessCounter += 1 ;~ Wend If CheckIfWon(True) Then Return True Else Return False EndIf If $msg = $GUI_EVENT_CLOSE Then Exit WEnd EndFunc Func CheckIfWon ($bGuess=False) $bReturn_CheckIfWon = True If $bGuess Then $iKnown = $giPuzzle_3D_KnownGuess Else $iKnown = $giPuzzle_3D_Known EndIf For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2d = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iKnown])=0 Then $bReturn_CheckIfWon = False Return $bReturn_CheckIfWon EndIf Next Next Return $bReturn_CheckIfWon EndFunc Edited November 15, 2012 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
Mat Posted November 15, 2012 Share Posted November 15, 2012 No idea how good it is, that was over 3 years ago. AutoIt Project Listing Link to comment Share on other sites More sharing options...
MvGulik Posted November 15, 2012 Share Posted November 15, 2012 BrewManNH beat you to it. "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
Decipher Posted November 15, 2012 Author Share Posted November 15, 2012 I created this, it can solve the easy puzzles...i'll add additional functions within the loop to recursivly guess (when out of known answers)...the file that is created on the fly includes an easy puzzle, that will be solvedUPDATE:: added logic to attempt guesses, but only one at a time, so if the guess (all possible single attempt guesses) fails, then script fails...real fun to watch it try though ...(will add logic for a second guess later...need to make that dynamic to allow infinite, valid guesses)The gauntlet was thrown, beat in fewer lines if you can As if I didn't have enough competition.. lol Spoiler Link to comment Share on other sites More sharing options...
jdelaney Posted November 16, 2012 Share Posted November 16, 2012 All done...this should solve any solveable puzzle: expandcollapse popup#include <Array.au3> #include <File.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Global $sDifficulty_Easy = "Easy" Global $sDifficulty_Med = "Med" Global $sDifficulty_Hard = "Hard" Global $sDifficulty_Default = $sDifficulty_Hard Global $gsFILE_Puzzle = @ScriptDir & "Puzzle_" & $sDifficulty_Default & ".txt" $iMaxRecurssionCounter = 2 Global Enum $giPuzzle_Y1D_0 = 0, _ $giPuzzle_Y1D_1, _ $giPuzzle_Y1D_2, _ $giPuzzle_Y1D_3, _ $giPuzzle_Y1D_4, _ $giPuzzle_Y1D_5, _ $giPuzzle_Y1D_6, _ $giPuzzle_Y1D_7, _ $giPuzzle_Y1D_8, _ $giPuzzle_Y1D_UBound Global Enum $giPuzzle_X2D_0 = 0, _ $giPuzzle_X2D_1, _ $giPuzzle_X2D_2, _ $giPuzzle_X2D_3, _ $giPuzzle_X2D_4, _ $giPuzzle_X2D_5, _ $giPuzzle_X2D_6, _ $giPuzzle_X2D_7, _ $giPuzzle_X2D_8, _ $giPuzzle_X2D_UBound Global Enum $giPuzzle_3D_Control = 0, _ $giPuzzle_3D_Known, _ $giPuzzle_3D_aPossible, _ $giPuzzle_3D_KnownGuess, _ $giPuzzle_3D_aGuessPossible, _ $giPuzzle_3D_KnownGuess2, _ $giPuzzle_3D_aGuessPossible2, _ $giPuzzle_3D_KnownGuess3, _ $giPuzzle_3D_aGuessPossible3, _ $giPuzzle_3D_KnownGuess4, _ $giPuzzle_3D_aGuessPossible4, _ $giPuzzle_3D_KnownGuess5, _ $giPuzzle_3D_aGuessPossible5, _ $giPuzzle_3D_KnownGuess6, _ $giPuzzle_3D_aGuessPossible6, _ $giPuzzle_3D_KnownGuess7, _ $giPuzzle_3D_aGuessPossible7, _ $giPuzzle_3D_KnownGuess8, _ $giPuzzle_3D_aGuessPossible8, _ $giPuzzle_3D_KnownGuess9, _ $giPuzzle_3D_aGuessPossible9, _ $giPuzzle_3D_KnownGuess10, _ $giPuzzle_3D_aGuessPossible10, _ $giPuzzle_3D_UBound Global $gaPuzzle[$giPuzzle_Y1D_UBound][$giPuzzle_X2D_UBound][$giPuzzle_3D_UBound] Global $gaPossible[9] = [1, 2, 3, 4, 5, 6, 7, 8, 9] ; Add possible to all cells For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] = $gaPossible Next Next $bExists = FileExists($gsFILE_Puzzle) If $bExists Then $gaPuzzle = GenerateFILEPuzzle($gaPuzzle) Else $gaPuzzle = GenerateRandomPuzzle($gaPuzzle) ; Currently, creating a fixed puzzle EndIf If GuiCreateCurrent() Then MsgBox(1, 1, "SOVLED!") Else MsgBox(1, 1, "Failed!") EndIf While True $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Exit WEnd Func GenerateRandomPuzzle($aCallersArray) _FileCreate($gsFILE_Puzzle) $hFile = FileOpen($gsFILE_Puzzle, 2) Switch $sDifficulty_Default Case $sDifficulty_Easy, $sDifficulty_Med FileWrite($hFile, "2,9,,,,,8,," & @CRLF & _ "8,5,,4,,1,3,7," & @CRLF & _ ",,,,3,,,," & @CRLF & _ ",3,,,,2,,5,6" & @CRLF & _ ",4,,3,9,7,,1," & @CRLF & _ "1,2,,5,,,,3," & @CRLF & _ ",,,,1,,,," & @CRLF & _ ",6,4,9,,8,,2,3" & @CRLF & _ ",,7,,,,,8,5") Case $sDifficulty_Hard FileWrite($hFile,",,,,,,,8,4" & @CRLF & _ ",9,,,5,,,,7" & @CRLF & _ ",,,,,9,1,," & @CRLF & _ ",,9,5,,,,7," & @CRLF & _ ",7,,3,,2,,6," & @CRLF & _ ",6,,,,1,8,," & @CRLF & _ ",,6,7,,,,," & @CRLF & _ "1,,,,3,,,4," & @CRLF & _ "3,2,,,,,,,") EndSwitch FileClose($hFile) Local $aTemp[1] _FileReadToArray($gsFILE_Puzzle, $aTemp) _ArrayDelete($aTemp, 0) For $y1D = 0 To UBound($aTemp) - 1 $aTemp2 = StringSplit($aTemp[$y1D], ",") _ArrayDelete($aTemp2, 0) For $x2D = 0 To UBound($aTemp2) - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] = $aTemp2[$x2D] Next Next ; Clear out possible array For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] > 0 Then $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] = "" Next Next Return $gaPuzzle EndFunc ;==>GenerateRandomPuzzle Func GenerateFILEPuzzle($aCallersArray) Local $aTemp[1] _FileReadToArray($gsFILE_Puzzle, $aTemp) _ArrayDelete($aTemp, 0) For $y1D = 0 To UBound($aTemp) - 1 $aTemp2 = StringSplit($aTemp[$y1D], ",") _ArrayDelete($aTemp2, 0) For $x2D = 0 To UBound($aTemp2) - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] = $aTemp2[$x2D] Next Next ; Clear out possible array For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known] > 0 Then $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_aPossible] = "" Next Next Return $gaPuzzle EndFunc ;==>GenerateFILEPuzzle Func GuiCreateCurrent() $iControlHeight = 15 $iControlWidth = 15 $iControlBuffer = 10 $iGuiWidth = $iControlBuffer + (($iControlWidth + $iControlBuffer) * $giPuzzle_X2D_UBound) $iGuiHeight = $iControlBuffer + (($iControlWidth + $iControlBuffer) * $giPuzzle_Y1D_UBound) Global $hGui = GUICreate(@ScriptName, $iGuiWidth, $iGuiHeight) For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 $gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Control] = GUICtrlCreateLabel($gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Known], $iControlBuffer + (($x2D) * ($iControlWidth + $iControlBuffer)), $iControlBuffer + (($y1D) * ($iControlWidth + $iControlBuffer)), $iControlWidth, $iControlHeight, BitOR($SS_SUNKEN, $SS_CENTER)) Switch $y1D Case 0 To 2, 6 To 8 If $x2D < 3 Or $x2D > 5 Then GUICtrlSetBkColor(-1, 0x00ff00) Case 3 To 5 If $x2D > 2 And $x2D < 6 Then GUICtrlSetBkColor(-1, 0x00ff00) EndSwitch Next Next GUISetState(@SW_SHOW) $bReturn_GuiCreateCurrent = False MsgBox(1, 1, "Solve on close of this msgbox") Local $iGuessCounter = 0 Local $iRecurssionCounter = 0 While True $msg = GUIGetMsg() While FillInEasyAndRemoveKnown() ;MsgBox (1,1,"FillInEasyAndRemoveKnown") WEnd ; Check if number is only available in a section once...that is by default, correct If FillInWhenOnlyOneCellInSectionHasPossibleNumber() Then ;MsgBox (1,1,"FillInWhenOnlyOneCellInSectionHasPossibleNumber") ContinueLoop EndIf If FillInWhenOnlyOneCellInColHasPossibleNumberX() Then ;MsgBox (1,1,"FillInWhenOnlyOneCellInColHasPossibleNumberX") ContinueLoop EndIf If FillInWhenOnlyOneCellInRowHasPossibleNumberY() Then ;MsgBox (1,1,"FillInWhenOnlyOneCellInRowHasPossibleNumberY") ContinueLoop EndIf ; Last resort...guess, and attempt to fill all in based on the guess ; Guess fills in known values to KnownGuess, and checks if all are filled to return true ;MsgBox (1,1,"done") While True Switch Guess($iGuessCounter, 0) Case 0 $iGuessCounter2 = 0 While True Switch Guess($iGuessCounter2, 1) Case 0 $iGuessCounter3 = 0 While True Switch Guess($iGuessCounter3, 2) Case 0 $iGuessCounter4 = 0 While True Switch Guess($iGuessCounter4, 3) Case 0 $iGuessCounter5 = 0 While True Switch Guess($iGuessCounter5, 4) Case 0 $iGuessCounter6 = 0 While True Switch Guess($iGuessCounter6, 5) Case 0 $iGuessCounter7 = 0 While True Switch Guess($iGuessCounter7, 6) Case 0 $iGuessCounter8 = 0 While True Switch Guess($iGuessCounter8, 7) Case 0 $iGuessCounter9 = 0 While True Switch Guess($iGuessCounter9, 8) Case 0 $iGuessCounter10 = 0 While True Switch Guess($iGuessCounter10, 9) Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter10+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter9+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter8+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter7+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter6+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter5+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter4+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter3+=1 WEnd Case 1 Return True Case 2 ExitLoop EndSwitch $iGuessCounter2+=1 WEnd Case 1 Return True Case 2 Return False EndSwitch $iGuessCounter+=1 $iRecurssionCounter = 0 WEnd ;~ If CheckIfWon() Then ;~ $bReturn_GuiCreateCurrent = True ;~ ExitLoop ;~ EndIf If $msg = $GUI_EVENT_CLOSE Then Exit WEnd Return $bReturn_GuiCreateCurrent EndFunc ;==>GuiCreateCurrent Func FillInEasyAndRemoveKnown($bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf $bReturn_FillInEasyAndRemoveKnown = False ; Clear out possible array of row and column For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iKnown]) > 0 Then RemoveYRowPossibility($y1D, $gaPuzzle[$y1D][$x2D][$iKnown], $bGuess, $iRecurssionCounter) RemoveXColPossibility($x2D, $gaPuzzle[$y1D][$x2D][$iKnown], $bGuess, $iRecurssionCounter) EndIf Next Next ; Clear out possiblity of section For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 ; Only enter if known $iTempKnown = $gaPuzzle[$y1D][$x2D][$iKnown] If StringLen($iTempKnown) = 0 Then ContinueLoop Switch $y1D Case 0 To 2 $yStart = 0 Case 3 To 5 $yStart = 3 Case 6 To 8 $yStart = 6 EndSwitch Switch $x2D Case 0 To 2 $xStart = 0 Case 3 To 5 $xStart = 3 Case 6 To 8 $xStart = 6 EndSwitch For $y = $yStart To $yStart + 2 For $x = $xStart To $xStart + 2 ; Skip current case If $y = $y1D And $x = $x2D Then ContinueLoop RemoveCellPossibility($y, $x, $iTempKnown, $bGuess,$iRecurssionCounter) Next Next Next Next ; Loop through all, and find where possible ubound = 1...that is now known...if found, return true...if none found, return false For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iKnown]) = 0 Then $aTemp = $gaPuzzle[$y1D][$x2D][$iaPossible] If UBound($aTemp) = 1 Then UpdateGuiWithKnownValue($y1D, $x2D, $aTemp[0], $bGuess, $iRecurssionCounter) RemoveYRowPossibility($y1D, $aTemp[0], $bGuess, $iRecurssionCounter) RemoveXColPossibility($x2D, $aTemp[0], $bGuess, $iRecurssionCounter) Return True EndIf EndIf Next Next Return $bReturn_FillInEasyAndRemoveKnown EndFunc ;==>FillInEasyAndRemoveKnown Func RemoveYRowPossibility($iCallersYValue, $iCallersKnownValue, $bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf For $i = 0 To $giPuzzle_X2D_UBound - 1 $aTemp = $gaPuzzle[$iCallersYValue][$i][$iaPossible] $iDeleteValue = _ArraySearch($aTemp, $iCallersKnownValue) If $iDeleteValue >= 0 Then _ArrayDelete($aTemp, $iDeleteValue) $gaPuzzle[$iCallersYValue][$i][$iaPossible] = $aTemp Next EndFunc ;==>RemoveYRowPossibility Func RemoveXColPossibility($iCallersXValue, $iCallersKnownValue, $bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf For $i = 0 To $giPuzzle_Y1D_UBound - 1 $aTemp = $gaPuzzle[$i][$iCallersXValue][$iaPossible] $iDeleteValue = _ArraySearch($aTemp, $iCallersKnownValue) If $iDeleteValue >= 0 Then _ArrayDelete($aTemp, $iDeleteValue) $gaPuzzle[$i][$iCallersXValue][$iaPossible] = $aTemp Next EndFunc ;==>RemoveXColPossibility Func RemoveCellPossibility($iCallersYValue, $iCallersXValue, $iCallersKnownValue, $bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf $aTemp = $gaPuzzle[$iCallersYValue][$iCallersXValue][$iaPossible] $iDeleteValue = _ArraySearch($aTemp, $iCallersKnownValue) If $iDeleteValue >= 0 Then _ArrayDelete($aTemp, $iDeleteValue) $gaPuzzle[$iCallersYValue][$iCallersXValue][$iaPossible] = $aTemp EndFunc ;==>RemoveCellPossibility Func UpdateGuiWithKnownValue($iCallersYValue, $iCallersXValue, $iCallersKnownValue, $bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf $gaPuzzle[$iCallersYValue][$iCallersXValue][$iKnown] = $iCallersKnownValue $gaPuzzle[$iCallersYValue][$iCallersXValue][$iaPossible] = "" GUICtrlSetData($gaPuzzle[$iCallersYValue][$iCallersXValue][$giPuzzle_3D_Control], $gaPuzzle[$iCallersYValue][$iCallersXValue][$iKnown]) EndFunc ;==>UpdateGuiWithKnownValue Func FillInWhenOnlyOneCellInSectionHasPossibleNumber($bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf $bReturn_FillInWhenOnlyOneCellInSectionHasPossibleNumber = False ; loop through number until a section returns only 1 possibility for that number...return true after setting For $iNumber = 1 To 9 ; Reset counter ; Loops to allow increasing conditional bounds $iYMin = 0 $iYMax = 2 For $y = 0 To 2 $iXMin = 0 $iXMax = 2 For $x = 0 To 2 $iTempSectionCounter = 9 ; decided to go section by section...too tird to logically do in one loop $bContinueLoop = True For $y1D = $iYMin To $iYMax For $x2D = $iXMin To $iXMax If $gaPuzzle[$y1D][$x2D][$iKnown] = $iNumber Then $bContinueLoop = False $iTempSectionCounter = 0 Else If StringLen($gaPuzzle[$y1D][$x2D][$iKnown]) > 0 Or _ArraySearch($gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber) < 0 Then $iTempSectionCounter -= 1 EndIf EndIf If Not $bContinueLoop Then ExitLoop Next If Not $bContinueLoop Then ExitLoop Next If $iTempSectionCounter = 1 Then For $y1D = $iYMin To $iYMax For $x2D = $iXMin To $iXMax If _ArraySearch($gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber) >= 0 Then UpdateGuiWithKnownValue($y1D, $x2D, $iNumber, $bGuess, $iRecurssionCounter) RemoveYRowPossibility($y1D, $iNumber, $bGuess, $iRecurssionCounter) RemoveXColPossibility($x2D, $iNumber, $bGuess, $iRecurssionCounter) Return True EndIf Next Next EndIf ; Current section didn't include any $iXMin += 3 $iXMax += 3 Next $iYMin += 3 $iYMax += 3 Next Next Return $bReturn_FillInWhenOnlyOneCellInSectionHasPossibleNumber EndFunc ;==>FillInWhenOnlyOneCellInSectionHasPossibleNumber Func FillInWhenOnlyOneCellInColHasPossibleNumberX($bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf $bReturn_FillInWhenOnlyOneCellInColHasPossibleNumberX = False For $iNumber = 1 To 9 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 $bContinueLoop = True $iTempColumnCounter = 9 For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iKnown]) > 0 Or _ArraySearch($gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber) < 0 Then $iTempColumnCounter -= 1 EndIf Next If $iTempColumnCounter = 1 Then ExitLoop Next If $iTempColumnCounter = 1 Then For $x2D = $x2D To $x2D For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 If _ArraySearch($gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber) >= 0 Then UpdateGuiWithKnownValue($y1D, $x2D, $iNumber, $bGuess, $iRecurssionCounter) RemoveYRowPossibility($y1D, $iNumber, $bGuess, $iRecurssionCounter) Return True EndIf Next Next EndIf Next Return $bReturn_FillInWhenOnlyOneCellInColHasPossibleNumberX EndFunc ;==>FillInWhenOnlyOneCellInColHasPossibleNumberX Func FillInWhenOnlyOneCellInRowHasPossibleNumberY($bGuess = False, $iRecurssionCounter = 0) If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf $bReturn_FillInWhenOnlyOneCellInRowHasPossibleNumberY = False For $iNumber = 1 To 9 For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 $bContinueLoop = True $iTempRowCounter = 9 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iKnown]) > 0 Or _ArraySearch($gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber) < 0 Then $iTempRowCounter -= 1 EndIf Next If $iTempRowCounter = 1 Then ExitLoop Next If $iTempRowCounter = 1 Then For $y1D = $y1D To $y1D For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If _ArraySearch($gaPuzzle[$y1D][$x2D][$iaPossible], $iNumber) >= 0 Then UpdateGuiWithKnownValue($y1D, $x2D, $iNumber, $bGuess, $iRecurssionCounter) RemoveXColPossibility($x2D, $iNumber, $bGuess, $iRecurssionCounter) Return True EndIf Next Next EndIf Next Return $bReturn_FillInWhenOnlyOneCellInRowHasPossibleNumberY EndFunc ;==>FillInWhenOnlyOneCellInRowHasPossibleNumberY Func Guess($iGuessCounter,$iRecurssionCounter) ; Blindly use the first avail array possibility that matches $iGuessCounter...attempt to solve...if not, false (outside function the guess counter increments, and attempts again) Local $iTempGuessCounter = $iGuessCounter ;~ If CheckIfWon(False) Then Return True If $iRecurssionCounter = 0 Then $sPrefix = "" $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible $iGuess = $giPuzzle_3D_KnownGuess $iaGuessPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible $iGuess = $giPuzzle_3D_KnownGuess2 $iaGuessPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 $iGuess = $giPuzzle_3D_KnownGuess3 $iaGuessPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 $iGuess = $giPuzzle_3D_KnownGuess4 $iaGuessPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 $iGuess = $giPuzzle_3D_KnownGuess5 $iaGuessPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 $iGuess = $giPuzzle_3D_KnownGuess6 $iaGuessPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 $iGuess = $giPuzzle_3D_KnownGuess7 $iaGuessPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 $iGuess = $giPuzzle_3D_KnownGuess8 $iaGuessPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 $iGuess = $giPuzzle_3D_KnownGuess9 $iaGuessPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $sPrefix = " " $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 $iGuess = $giPuzzle_3D_KnownGuess10 $iaGuessPossible = $giPuzzle_3D_aGuessPossible10 EndIf ConsoleWrite($sPrefix & "Recur=[" & $iRecurssionCounter & "]; GuessCounter=[" & $iGuessCounter & "];" ) ; Clear out all known guesses, and reset availguess array to possible array For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iGuess]) > 0 And StringLen($gaPuzzle[$y1D][$x2D][$iKnown]) = 0 Then GUICtrlSetData($gaPuzzle[$y1D][$x2D][$giPuzzle_3D_Control], "") EndIf $gaPuzzle[$y1D][$x2D][$iGuess] = $gaPuzzle[$y1D][$x2D][$iKnown] $gaPuzzle[$y1D][$x2D][$iaGuessPossible] = $gaPuzzle[$y1D][$x2D][$iaPossible] Next Next ; Check if already won If CheckIfWon(True) Then Return True ; Loop Through until an element is found matching the current $iGuessCounter $bGuessFound = False For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 $aTemp = $gaPuzzle[$y1D][$x2D][$iaPossible] If UBound($aTemp) <= $iTempGuessCounter Then If IsArray($aTemp) Then $iTempGuessCounter -= UBound($aTemp) EndIf Else $iGuessNumber = $aTemp[$iTempGuessCounter] $bGuessFound = True UpdateGuiWithKnownValue($y1D, $x2D, $iGuessNumber, True, $iRecurssionCounter) RemoveYRowPossibility($y1D, $iGuessNumber, True, $iRecurssionCounter) RemoveXColPossibility($x2D, $iGuessNumber, True, $iRecurssionCounter) ConsoleWrite("; Start with Number=[" & $iGuessNumber & "] x|y=[" & $x2D & "|" & $y1D & "]" & @CRLF) ; Need to remove the guess number from guess possible array Switch $y1D Case 0 To 2 $iYStart = 0 Case 3 To 5 $iYStart = 3 Case 6 To 8 $iYStart = 6 EndSwitch Switch $x2D Case 0 To 2 $iXStart = 0 Case 3 To 5 $iXStart = 3 Case 6 To 8 $iXStart = 6 EndSwitch For $iY = $iYStart To $iYStart + 2 For $iX = $iXStart To $iXStart + 2 $aTemp2 = $gaPuzzle[$iY][$iX][$iaGuessPossible] $iDeleteValue = _ArraySearch($aTemp2, $iGuessNumber) If $iDeleteValue >= 0 Then _ArrayDelete($aTemp2, $iDeleteValue) $gaPuzzle[$iY][$iX][$iaGuessPossible] = $aTemp2 Next Next EndIf If $bGuessFound Then ExitLoop Next If $bGuessFound Then ExitLoop Next If Not $bGuessFound Then ConsoleWrite ( "All Single attempt guesses tried, and failed" & @CRLF) Return 2 EndIf ; Perform same loops to check for guess fits While True $msg = GUIGetMsg() While FillInEasyAndRemoveKnown(True, $iRecurssionCounter) WEnd ; Check if number is only available in a section once...that is by default, correct If FillInWhenOnlyOneCellInSectionHasPossibleNumber(True, $iRecurssionCounter) Then ContinueLoop If FillInWhenOnlyOneCellInColHasPossibleNumberX(True, $iRecurssionCounter) Then ContinueLoop If FillInWhenOnlyOneCellInRowHasPossibleNumberY(True, $iRecurssionCounter) Then ContinueLoop ;~ ; Currently only doing one guess at a time, or resetting ;~ ; Last resort...guess, and attempt to fill all in based on the guess ;~ ; Guess fills in known values to KnownGuess, and checks if all are filled to return true If CheckIfWon(True,$iRecurssionCounter) Then Return 1 Else Return 0 EndIf If $msg = $GUI_EVENT_CLOSE Then Exit WEnd EndFunc ;==>Guess Func CheckIfWon($bGuess = False, $iRecurssionCounter = 0) $bReturn_CheckIfWon = True If Not $bGuess Then If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_Known $iaPossible = $giPuzzle_3D_aPossible Else MsgBox (1,1,@ScriptLineNumber) EndIf Else If $iRecurssionCounter = 0 Then $iKnown = $giPuzzle_3D_KnownGuess $iaPossible = $giPuzzle_3D_aGuessPossible ElseIf $iRecurssionCounter = 1 Then $iKnown = $giPuzzle_3D_KnownGuess2 $iaPossible = $giPuzzle_3D_aGuessPossible2 ElseIf $iRecurssionCounter = 2 Then $iKnown = $giPuzzle_3D_KnownGuess3 $iaPossible = $giPuzzle_3D_aGuessPossible3 ElseIf $iRecurssionCounter = 3 Then $iKnown = $giPuzzle_3D_KnownGuess4 $iaPossible = $giPuzzle_3D_aGuessPossible4 ElseIf $iRecurssionCounter = 4 Then $iKnown = $giPuzzle_3D_KnownGuess5 $iaPossible = $giPuzzle_3D_aGuessPossible5 ElseIf $iRecurssionCounter = 5 Then $iKnown = $giPuzzle_3D_KnownGuess6 $iaPossible = $giPuzzle_3D_aGuessPossible6 ElseIf $iRecurssionCounter = 6 Then $iKnown = $giPuzzle_3D_KnownGuess7 $iaPossible = $giPuzzle_3D_aGuessPossible7 ElseIf $iRecurssionCounter = 7 Then $iKnown = $giPuzzle_3D_KnownGuess8 $iaPossible = $giPuzzle_3D_aGuessPossible8 ElseIf $iRecurssionCounter = 8 Then $iKnown = $giPuzzle_3D_KnownGuess9 $iaPossible = $giPuzzle_3D_aGuessPossible9 ElseIf $iRecurssionCounter = 9 Then $iKnown = $giPuzzle_3D_KnownGuess10 $iaPossible = $giPuzzle_3D_aGuessPossible10 Else MsgBox (1,1,@ScriptLineNumber) EndIf EndIf For $y1D = 0 To $giPuzzle_Y1D_UBound - 1 For $x2D = 0 To $giPuzzle_X2D_UBound - 1 If StringLen($gaPuzzle[$y1D][$x2D][$iKnown]) = 0 Then $bReturn_CheckIfWon = False Return $bReturn_CheckIfWon EndIf Next Next Return $bReturn_CheckIfWon EndFunc ;==>CheckIfWon IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
MvGulik Posted November 16, 2012 Share Posted November 16, 2012 (edited) Erm, If MsgBox(1, 1, "Solve on close of this msgbox") <> 1 Then Exit (edit: MsgBox(1, 1, "Solve this puzzle?")) works a bit better than, MsgBox(1, 1, "Solve on close of this msgbox") (especially if SciTE decides to keeps restarting the script after breaking it off. ) --- This seems like a hard test puzzle. 0,2,3,0,9,0,8,0,0 6,0,1,0,3,8,0,0,0 5,0,0,4,0,0,0,0,0 3,0,0,0,0,0,2,0,4 0,0,6,0,0,0,3,0,0 7,0,8,0,0,0,0,0,1 0,0,0,0,0,3,0,0,8 0,0,0,7,8,0,9,0,6 0,0,2,0,5,0,1,4,0 Edited November 16, 2012 by MvGulik "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now