Jump to content

Sudoku Solver


MrBadAxe
 Share

Recommended Posts

You may have seen these puzzles popping up in newspapers across the country. You're given a 9x9 grid with a few numbers filling the cells. The object is to fill in the rest of the cells with the numbers 1 through 9, while making sure that no row, column, or 3x3 box contains a duplicate of the numbers.

Being unoccupied with other projects, I opted to write a program that would help me solve these puzzles by keeping track of all the stuff I'd normally have to keep track of with pencil and paper.

Here's the code I have so far:

;Sudoku Solver in AutoIt3
#include <GUIConstants.au3>
GUICreate("Sudoku Solver",600,600)
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "Quit")
GUISetState(@SW_SHOW)

Dim $buttons[9][9][9]

for $i = 0 to 8
for $j = 0 to 8
for $k = 0 to 8
    $top = (((20*$i)+5)+(200*mod($k,3)))
    $left = (((20*$j)+5)+(200*Int($k/3)))
    $buttons[$i][$j][$k] = GUICtrlCreateButton("",$top,$left,20,20)
    GuiCtrlSetOnEvent($buttons[$i][$j][$k],"SetNumber")
next
next
next

While 1
Sleep(1000)
Wend

Creates a 3x3 array of 9x9 grids representing whether a certain number can be placed in a certain cell. Upper-left-most represents the positions of the 1s, upper-center represents the 2s, upper right displays the 3s, etc... What I want to do now is be able to change the captions of the buttons by clicking them:

* Change the text of the button pressed to the number placed (based on which 9x9 grid the button is in)

1 2 3

4 5 6

7 8 9

* Change the text of the buttons in the same row, column, 3x3 box, and the same position in other 9x9 grids, to "x" to symbolize that nothing should be placed there.

Here's the function I wrote for that purpose:

Func SetNumber($x,$y,$z)
    MsgBox(0,"debug","You Clicked button (" & $x & "," & $y & "," & $z & ")")
    for $ctr = 0 to 8
        GuiCtrlSetData($buttons[$ctr][$y][$z],"x")
        GuiCtrlSetData($buttons[$x][$ctr][$z],"x")
        GuiCtrlSetData($buttons[$x][$y][$ctr],"x")
        GuiCtrlSetData($buttons[$x][$y][$z],($z+1))
    next
EndFunc

I have no idea how to get the array positions of the button that was pressed, which I need to pass to this function. Is this possible?

Link to comment
Share on other sites

Don't understand this exactly so i'll give something that does do something, the code you have won't work with events

I'm sure this is wrong, but you'll get the idea.

;Sudoku Solver in AutoIt3
#include <GUIConstants.au3>
GUICreate("Sudoku Solver", 600, 600)
GUISetState(@SW_SHOW)

Dim $buttons[9][9][9]

For $i = 0 To 8
   For $j = 0 To 8
      For $k = 0 To 8
         $top = (((20 * $i) + 5) + (200 * Mod($k, 3)))
         $left = (((20 * $j) + 5) + (200 * Int($k / 3)))
         $buttons[$i][$j][$k] = GUICtrlCreateButton("", $top, $left, 20, 20)
      Next
   Next
Next

While 1
   $msg = GUIGetMsg(1)
   Select
      Case $msg[0] = $GUI_EVENT_CLOSE
         ExitLoop
      Case Else
         If $msg[0] > 0 Then
            For $x = $msg[0] To $msg[0] + 8
               GUICtrlSetData($x, "x")
            Next
         EndIf
   EndSelect
WEnd

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

;Sudoku Solver in AutoIt3
#include <GUIConstants.au3>
GUICreate("Sudoku Solver", 600, 600)
GUISetState(@SW_SHOW)

Dim $buttons[9][9][9]

For $i = 0 To 8
   For $j = 0 To 8
      For $k = 0 To 8
         $top = (((20 * $i) + 5) + (200 * Mod($k, 3)))
         $left = (((20 * $j) + 5) + (200 * Int($k / 3)))
         $buttons[$i][$j][$k] = GUICtrlCreateButton("", $top, $left, 20, 20)
      Next
   Next
Next

While 1
   $msg = GUIGetMsg(1)
   Select
      Case $msg[0] = $GUI_EVENT_CLOSE
         ExitLoop
      Case Else
         If $msg[0] > 0 Then
            For $x = $msg[0] To $msg[0] + 8
               GUICtrlSetData($x, "x")
            Next
         EndIf
   EndSelect
WEnd

Well this isn't exactly what I'm looking for but it helps. Thanks.

Link to comment
Share on other sites

I'm afraid my answer it longwinded, so I'm attaching my script t so you don't have to do a lot of scrolling :o

1) The GuiCtrlSetOnEvent does work with a function that takes parameters--at least I think this limitation still applies.

2) I'm not sure why GaFrost uses

If $msg[0] > 0 Then
            For $x = $msg[0] To $msg[0] + 8
               GUICtrlSetData($x, "x")
            Next
         EndIf

He should have said:

If $msg[0] >= $buttons[0][0][0] Then 
            GUICtrlSetData($msg[0], "x")
         EndIf

3) If you still want to use GuiCtrlSetOnEvent, you can use the @GUI_CtrlId to get the ID of the button. This should be sufficient, but if you want to convert the ID into x,y,z coords you need to do 1 of 2 things:

a) Convert ID to x,y,z by using math. Mod and Integer Division *might* not be sufficient since you have the third dimension and you loop through each grid each time... It would be easier to to calculate the row,col from the ID if you completely fill the first 9x9 grid, then completely fill the second 9x9 grid,.... then finally fill the last 9x9 grid. I will try this in a few minutes since I'm interested....

B) I implement plan b, and use the button's label to store it's x,y,z coordinates. I use a trick of setting the $BS_RIGHT style on the button, so the right-most text appears and anything that doesn't fit is cut off. Normally, the button tries to center its text. When the button is clicked, I use @GUI_CtrlId to obtain the button and then GuiRead() its text :graduated:

By the way, I made the following modification:

$top = (((20*$j)+5)+(200*mod($k,3)))

$left = (((20*$i)+5)+(200*Int($k/3)))

So that each 9x9 matrix is populated left-to-right, top-to-bottom

You were filling the matrix top-to-bottom, left-to-right

An easy way to see how the buttons are numbered is to put

GuiCtrlSetData($buttons[$i][$j][$k], $buttons[$i][$j][$k])

right after you create the button.

Hope this helps.

SokuIdea.au3

Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!
Link to comment
Share on other sites

Code that shows example of converting flat index to row,col ...

EDIT: This is probably the much better approach, but I'm not sure if I got it numbered the way you want it...

EDIT 2: Should have same results as other one now.

;Sudoku Debug Idea etc.
#include <GUIConstants.au3>
GUICreate("Sudoku Solver",600,600)
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "Quit")
GUISetState(@SW_SHOW)

Dim $buttons[9][9][9]

; Create each 9x9 array one a time

for $k = 0 to 8
sleep(50);sleep to emphasise the order the arrays are created
for $i = 0 to 8
for $j = 0 to 8
    $top = (((20*$j)+5)+(200*mod($k,3)))
    $left = (((20*$i)+5)+(200*Int($k/3)))
    $buttons[$i][$j][$k] = GUICtrlCreateButton("",$top,$left,20,20, $BS_RIGHT )
    GuiCtrlSetOnEvent($Buttons[$i][$j][$k], "Foo")
    
; Remember to subtract $buttons[0][0][0] which is the value of the first GuiID AutoIt chooses to assign,
; so that the labels start at index 0
    GuiCtrlSetData($buttons[$i][$j][$k], $buttons[$i][$j][$k] - $buttons[0][0][0])
next
next
next

While 1
Wend

Func Foo()
; Get the flat index which is a number between 0 and 728 (inclusive)
    $index = @GUI_CtrlId - $buttons[0][0][0]
    GuiCtrlSetData(@Gui_CtrlID, "X");mark the clicked button

   ;not quite
   ;;$row = Int($index / 9)
   ;;$col = Mod($index, 9)
   ;;$thirdDimension = Int($index / 81)
    
   ;should be right
    $thirdDimension = Int($index / 81)
    $row = Int($index / 9) - $thirdDimension * 9
    $col = Mod($index, 9) 

    MsgBox(4096,"indx=" & $index, $row & "," & $col & ", " & $thirdDimension)
EndFunc

Func Quit()
    Exit
EndFunc
Edited by CyberSlug
Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!
Link to comment
Share on other sites

I get some errors

Once my friend told me that he had found Jesus. I thought to myself, "Woohoo, we're rich!" It turns out he meant something different.Sometimes I just like to lay in my bed and look up at the stars and wonder..where the hell did my roof go?
Link to comment
Share on other sites

...Would you...describe them?

Nevermind I cant figure out how to use it can you help?

Once my friend told me that he had found Jesus. I thought to myself, "Woohoo, we're rich!" It turns out he meant something different.Sometimes I just like to lay in my bed and look up at the stars and wonder..where the hell did my roof go?
Link to comment
Share on other sites

Nevermind I cant figure out how to use it can you help?

First, if you've never seen or heard of Sudoku puzzles before, I recommend you read the Sudoku website first.

All the program is supposed to do is keep track of everything I'd need to keep track of with pencil/paper anyway to solve the puzzle.

Click a button and it will place a number within one of the 9x9 cells (lower right area). Each button that is labeled with an X is one that, given the current puzzle situation, cannot contain a certain number. Nothing's stopping you from clicking it except common sense and there's no Reset or Undo feature implemented. (yet.)

Link to comment
Share on other sites

Oh I know how to play I just thought if u type the numbers in the box it would just give you the answers

Once my friend told me that he had found Jesus. I thought to myself, "Woohoo, we're rich!" It turns out he meant something different.Sometimes I just like to lay in my bed and look up at the stars and wonder..where the hell did my roof go?
Link to comment
Share on other sites

  • 2 months later...
  • 2 weeks later...

Hi MrBadAxe,

My interest on this moment is for this puzzles to. I'm making them traveling from home to work v.v.

But your implementation has a little flaw... :o

I think it is in the logic for filling the 3x3 square. It looks that the squares are placed around the number just filled in, not in the squares that are defined by the puzzle.

Make this line any sense to you?

I try to explain:

To whole puzzle exists of 9x9 numbers. But puzzle has 3x3 squares to (every square has 3x3 numbers).

What happens by filling in the numbers (given by the "Sudoku of the day" in my magazine) is that not the 3x3 squares are filled, but 3x3 numbers around the clicked button.

Is this a better explanation?

I will look if i can find out what happens and correct it. Ok by you?

greetings by Paul

EDIT: I find out what was "wrong" :"> My mistake! :"> The x's that are placed are from cells that are taken by other numbers....

Nice job! and very usefull. THNX

Finished.

Here's the completed script.

sudoku.au3

Edited by PaulG3
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...