AutoHotkey Community

It is currently May 27th, 2012, 4:10 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: sudoku helper
PostPosted: January 30th, 2006, 3:19 am 
Offline

Joined: October 27th, 2004, 1:22 am
Posts: 64
Location: GA
Hi I am trying to create a sudoku helper and this is what I have come up with this script. but, the problem is when there is only one number left in a 3x3 box, or a row or a column (or only one number to select in a dropdownlist) it assigns it automatically, but it doesnot remove the number from the 3x3 box or a row automatically as it suppose to be. User need to click the new automatically assigned number to remove it from the row/colum/3x3 box. Please help me to solve that problem and/or to make it better and maybe a shorter script :) .

This is what it does: put the numbers (1-9) in all dropdownlists. as user selects a number, it removes that number from the 3x3 box, that row and that column. If there is only one choice left in a dropdownlist, it automatically selects it.

Code:
Removed code: below is a more advanced

_________________
-Tru 8)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2006, 3:29 pm 
Hi.
I've made a script like that about 6months ago.
I warn you now... When you finish, it won't be a helper anymore...
You will be amused how about 90% of the sudokus can be solved with that... They basically force us to search for all simple combos, like that. Only the hardest ones make us use an advanced racio :\

I have made one very advanced in C. and with that I found ONE Very Hard sudoku in 2 books searched.
I can't solve it by hand, PC, or whatever, just by tries :\
Can anyone solve it and tell me how? :S
Here it is:

Starting:
Code:
000 060 300
001 000 006
000 305 700

200 900 800
710 406 095
006 002 003

003 509 000
900 000 600
005 010 000


All I can do, with Hand and PC(actually better then Hand :? ) :
Code:
050 160 300
301 090 506
600 305 710

234 951 867
718 436 295
596 002 143

163 509 470
900 003 651
005 610 930


And the Only answer possible:
Code:
857 164 329
341 297 586
629 385 714

234 951 867
718 436 295
596 872 143

163 529 478
982 743 651
475 618 932



The solution was found with tries by PC: (The first spot can only be a 4 or 8, the 4 makes it impossible, the 8 will end :wink: ). The 0s mean Blank/Not Found.
If you want to see the script in C, I'll post it. But it's bigggg...

About the droplists, I can't help... Mine was made with (3x3)X(9x9) Buttons ;)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2006, 5:05 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
I was able to shrink your code from 1861 lines to 118 lines (a factor > 15 :)
Code:
Removed code: below is a more advanced

_________________
Ciao
toralf
Image


Last edited by toralf on January 31st, 2006, 4:46 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2006, 5:38 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
with auto update I got it down to 112 lines, but there is something fishy. Sometimes it selects too many fields. I do not know sudoko, so I don't know i this is correct.

Edit: I guess it is the objective not to have these in the game. Otherwise it would be too easy.
Code:
Index = ABCDEFGHI
Loop, Parse, Index
  {
    Position = xm Section
    Letter = %A_LoopField%
    Loop, 9 {
        A%Letter%%A_Index% = 123456789
        Gui, Add, DropDownList, %Position% w35 number v%Letter%%A_Index% gDDLCLICK, 1|2|3|4|5|6|7|8|9
        Position = ys
      }
  }
Gui, Add, Button,xm gBtnReset, Reset
Gui, Show,, SuDoKu Helper
Return

GuiEscape:
GuiClose:
  ExitApp

BtnReset:
  Reload
return

DDLCLICK:
  GuiCntrl = %A_GuiControl%
AutoUpdate: 
  AutoUpdate =
  Gui, Submit, NoHide
  StringLeft, Row, GuiCntrl, 1
  StringRight, Column, GuiCntrl, 1

  ;clean clicked field
  Selection := %GuiCntrl%
  GuiControl, , %GuiCntrl%, |%Selection%||
  A%GuiCntrl% = %Selection%
 
  ;clean horizontal (in that row)
  AllColumns = 123456789
  StringReplace, LoopOverColumns, AllColumns, %Column%
  GoSub, Label1
 
  ;clean block
  RowBlocks = A,B,C|D,E,F|G,H,I
  Loop, Parse, RowBlocks, |
    If Row in %A_LoopField%
      {
        StringReplace, LoopOverBlock, A_LoopField, %Row%
        StringReplace, LoopOverBlock, LoopOverBlock, `,,,All
        StringReplace, LoopVertical, RowBlocks, %A_LoopField%
        StringReplace, LoopVertical, LoopVertical, |,,All
        StringReplace, LoopVertical, LoopVertical, `,,,All
        Break       
      }
  ColumnBlocks = 1,2,3|4,5,6|7,8,9
  Loop, Parse, ColumnBlocks, |
    If Column in %A_LoopField%
      {
        StringReplace, LoopOverColumns, A_LoopField, `,,,All
        Break       
      }
  Loop, Parse, LoopOverBlock
    {
      Row = %A_LoopField%
      GoSub, Label1
    }

  ;Clean Vertical (in that column)
  loop, parse, LoopVertical
    {
      x := A%A_loopfield%%Column%
      z = %A_loopfield%%Column%
      GoSub, Eliminate
    }

  ;Loop through AutoUpdates
  StringTrimLeft, AutoUpdate, AutoUpdate,1
  Loop,Parse, AutoUpdate, |
    {
      GuiCntrl = %A_LoopField%
      GoSub, AutoUpdate
    }
Return

label1:
  loop, parse, LoopOverColumns
    {
      x := A%Row%%A_loopfield%
      z = %Row%%A_loopfield%     
      GoSub, Eliminate
    }
return

Eliminate:
  If x > 10
    {
      stringreplace, x, x, %Selection%
      A%z% = %x%

      varx =
      loop, parse, x
          varx = %varx%%A_LoopField%|
      stringTrimRight, varx, varx, 1
     
      if varx is integer
        {
          guicontrol, , %z%, |%varx%||
          AutoUpdate = %AutoUpdate%|%z%
        }
      else
          guicontrol, , %z%, |%varx%
    }
Return

_________________
Ciao
toralf
Image


Last edited by toralf on January 31st, 2006, 2:55 am, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2006, 5:53 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
http://sudoku.sourceforge.net/

Many other applets on the Net. Even a JavaScript one...
Of course, part of the fun is to write a solver (or a helper) ourself...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2006, 9:57 pm 
Offline

Joined: October 27th, 2004, 1:22 am
Posts: 64
Location: GA
@ toralf

the objective of the game is to Fill in the grid so that every row, every column, and every 3x3 box contains the digits 1 through 9.

I am sorry to tell you this, but your script just list the numbers in each box (81 totals) but does not help; I mean if you select a 3 on the first box (top left) it should remove the 3's from the top left 3x3 box and the top row and the left column, but yours just put the selected number (in this case 3) in to the box but doesn't do the rest.

@guest

sometime guessing is required :) . Try looking up Nishio here is one link: http://www.simes.clara.co.uk/programs/sudokutechnique8.htm

_________________
-Tru 8)


Last edited by tpatel5 on January 30th, 2006, 10:58 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2006, 10:31 pm 
Please test again. Since it does work on my PC. Do you have the latest AHK version?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 30th, 2006, 11:19 pm 
Offline

Joined: October 27th, 2004, 1:22 am
Posts: 64
Location: GA
I see. I tried the second script by toralf and it didn't work but the first one works just fine. Thanks toralf for shortening the script :D

_________________
-Tru 8)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2006, 2:56 am 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
I found the source of the problem in the second script. One line wasn't identical to the code on my pc. I updated the above post. It should work now as well. I'm very sorry for causing confusion.

_________________
Ciao
toralf
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2006, 4:46 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
I played a bit more with the code. Now it supports to free a number. Unfortunately the autoupdate doesn't always work correctly. I will not have time to fix this, but maybe someone else has the time to continue.

This are only 190 lines.
Code:
Index = ABCDEFGHI
Loop, Parse, Index
  {
    Position = xm Section
    Row = %A_LoopField%
    Loop, 9 {
        A%Row%%A_Index% = 123456789
        Gui, Add, DropDownList, %Position% w35 number Sort v%Row%%A_Index% gDDLCLICK, 1|2|3|4|5|6|7|8|9
        Position = ys
      }
  }
Gui, Add, Button,xm gBtnReset, Reset
Gui, Show,, SuDoKu Helper
Return

GuiEscape:
GuiClose:
  ExitApp

BtnReset:
  Reload
return

DDLCLICK:
  GuiCntrl = %A_GuiControl%
AutoUpdate: 
  SetBatchLines, -1
  AutoUpdate =
  StringLeft, Row, GuiCntrl, 1
  StringRight, Column, GuiCntrl, 1
  OldValue := %GuiCntrl%

  Gui, Submit, NoHide
  Selection := %GuiCntrl%

  ;free the previous value if there was one
  If OldValue is not space
      GoSub, FreeValue

  GoSub, EliminateValue
 
  ;add and select selected value again
  If Selection is not space
    {
      GuiControl, , %GuiCntrl%, %Selection%||
      A%GuiCntrl% := A%GuiCntrl% . Selection
    }
  Else
      GuiControl, Choose, %GuiCntrl%,1

  ;Loop through AutoUpdates
  StringReplace, AutoUpdate, AutoUpdate, %GuiCntrl%,,All
  Loop,Parse, AutoUpdate, |
    {
      If A_LoopField is not space
        {
          GuiCntrl = %A_LoopField%
          GoSub, AutoUpdate
        }
    }
Return

LoopFieldsToEliminate:
  Loop, parse, LoopOverRows
    {
      CurrentRow := A_LoopField
      Loop, parse, LoopOverColumns
        {
          z = %CurrentRow%%A_LoopField%     
          x := A%z%
          y := %z%     
          StringReplace, x, x, %Selection%
          A%z% = %x%
   
          varx =
          Loop, Parse, x
              varx = %varx%%A_LoopField%|
          StringTrimRight, varx, varx, 1
         
          GuiControl, , %z%, ||%varx%
          If y is not space
            {
              If x is not space
                GuiControl, ChooseString, %z%, %y%
            }
          Else If varx is integer
            {
              GuiControl, ChooseString, %z%, %varx%
              AutoUpdate = %AutoUpdate%|%z%
            }
        }
    }
return

EliminateValue:
  ;clean horizontal
  LoopOverRows = %Row%
  LoopOverColumns = 123456789
  GoSub, LoopFieldsToEliminate

  ;clean vertical
  LoopOverRows = ABCDEFGHI
  LoopOverColumns = %Column%
  GoSub, LoopFieldsToEliminate

  ;clean its own block
  GoSub, GetRemainingBlockFields
  GoSub, LoopFieldsToEliminate 
Return

GetRemainingBlockFields:
  RowBlocks = A,B,C|D,E,F|G,H,I
  Loop, Parse, RowBlocks, |
    If Row in %A_LoopField%
      {
        StringReplace, LoopOverRows, A_LoopField, %Row%
        StringReplace, LoopOverRows, LoopOverRows, `,,,All
        Break       
      }
  ColumnBlocks = 1,2,3|4,5,6|7,8,9
  Loop, Parse, ColumnBlocks, |
    If Column in %A_LoopField%
      {
        StringReplace, LoopOverColumns, A_LoopField, %Column%
        StringReplace, LoopOverColumns, LoopOverColumns, `,,,All
        Break       
      }
Return

FreeValue:
  ;empty valuestrings
  Loop, 9 {
      RowValues%A_Index% =
      ColumnValues%A_Index% =
      BlockValues%A_Index% =
    }
  ;get valuestrings by rows, columns and blocks
  LoopOverRows = ABCDEFGHI
  LoopOverColumns = 123456789
  Loop, parse, LoopOverRows
    {
      CurrentRow := A_loopfield
      RowID := A_Index
      BlockRowID := Floor((RowID - 1) / 3)
      Loop, parse, LoopOverColumns
        {
          y := %CurrentRow%%A_loopfield%   
          RowValues%RowID% := RowValues%RowID% . y
          ColumnValues%A_loopfield% := ColumnValues%A_loopfield% . y
          BlockID := (Floor((A_loopfield -1)/ 3) + 1) + 3 * BlockRowID
          BlockValues%BlockID% := BlockValues%BlockID% . y
        }
    } 
 
  ;add value horizontal if not in column or row or block string
  LoopOverRows = %Row%
  LoopOverColumns = 123456789
  StringReplace, LoopOverColumns, LoopOverColumns, %Column%
  GoSub, LoopFieldsToFree

  ;add value vertical if not in column or row or block string
  LoopOverRows = ABCDEFGHI
  StringReplace, LoopOverRows, LoopOverRows, %Row%
  LoopOverColumns = %Column%
  GoSub, LoopFieldsToFree
 
  ;add value to its own block if not in column or row string
  GoSub, GetRemainingBlockFields
  GoSub, LoopFieldsToFree
Return

LoopFieldsToFree:
  Loop, parse, LoopOverRows
    {
      CurrentRow := A_LoopField
      RowID := Asc(CurrentRow) - 64
      If (InStr(OldValue, "a" . RowValues%RowID%) = 0){
          RowID := Floor((RowID - 1) / 3)
          Loop, parse, LoopOverColumns
              If (InStr(OldValue, "a" . ColumnValues%A_LoopField%) = 0){
                  BlockID := (Floor((A_LoopField -1)/ 3) + 1) + 3 * RowID
                  If (InStr(OldValue, "a" . BlockValues%BlockID%) = 0){
                      z = %CurrentRow%%A_LoopField%     
                      A%z% := A%z% . OldValue
                      GuiControl, , %z%, %OldValue%
                    }
                }
        }
    } 
Return

_________________
Ciao
toralf
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 31st, 2006, 4:55 pm 
Offline

Joined: November 12th, 2005, 10:25 pm
Posts: 73
tpatel5 wrote:
@guest

sometime guessing is required :) . Try looking up Nishio here is one link: http://www.simes.clara.co.uk/programs/sudokutechnique8.htm


I completly disagree...
It has no fun if you could use tries. It isn't need, I'm sure...
Of corse the Nishio can be used, and Is, in most of the Programs. But the fun is to make Ultra-Advanced Racios to find it, without that thechnique...

The site you gave is Awsome tpatel, thanks. Althought, there is only one racio missing in my program :\
As the site says:
Quote:
There are some that would argue trial and error is not a logical technique, and is no better than guessing.

I agree with this phrase ;)

Hehe.

P.S.: I was the first Guest. Forgot to login :\


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 14th, 2006, 2:36 am 
I changed the script a little (I used editboxes) so it is easier to see what numbers are still there.

Code:
gui, margin, 1, 1
gui, font, s8
Index = ABCDEFGHI
Loop, Parse, Index
  {
    Position = xm Section
    if A_loopfield in D,G
    Position = xm Y+10 Section
    Letter = %A_LoopField%
    Loop, 9 {
        A%Letter%%A_Index% = 123456789
        Gui, Add, Edit, %Position% h45 w25 number v%Letter%%A_Index% -vscroll gDDLCLICK, 123456789
position = ys
        if A_index in 3,6
        Position = X+10
                }
  }
Gui, Add, Button,xm gBtnReset, Reset
Gui, Show, , SuDoKu Helper
Return

GuiEscape:
GuiClose:
  ExitApp

BtnReset:
  Reload
return

DDLCLICK:
  GuiCntrl = %A_GuiControl%
 
AutoUpdate:
  AutoUpdate =
  Gui, Submit, NoHide
  StringLeft, Row, GuiCntrl, 1
  StringRight, Column, GuiCntrl, 1
 
  ;clean clicked field
  Selection := %GuiCntrl%
  if selection > 10
  {
   GuiControl, Font, %GuiCntrl%,
   GuiControl, , %GuiCntrl%, %Selection%
  A%GuiCntrl% = %Selection%
  return
  }
  gui, font, s18
  GuiControl, Font, %GuiCntrl%,
  gui, font, s8
  GuiControl, , %GuiCntrl%, %Selection%
  A%GuiCntrl% = %Selection%

;clean horizontal (in that row)
  AllColumns = 123456789
  StringReplace, LoopOverColumns, AllColumns, %Column%
  GoSub, Label1

  ;clean block
  RowBlocks = A,B,C|D,E,F|G,H,I
  Loop, Parse, RowBlocks, |
    If Row in %A_LoopField%
      {
        StringReplace, LoopOverBlock, A_LoopField, %Row%
        StringReplace, LoopOverBlock, LoopOverBlock, `,,,All
        StringReplace, LoopVertical, RowBlocks, %A_LoopField%
        StringReplace, LoopVertical, LoopVertical, |,,All
        StringReplace, LoopVertical, LoopVertical, `,,,All
        Break
      }
      ColumnBlocks = 1,2,3|4,5,6|7,8,9
  Loop, Parse, ColumnBlocks, |
    If Column in %A_LoopField%
      {
        StringReplace, LoopOverColumns, A_LoopField, `,,,All
        Break
      }
  Loop, Parse, LoopOverBlock
    {
      Row = %A_LoopField%
      GoSub, Label1
    }

  ;Clean Vertical (in that column)
  loop, parse, LoopVertical
    {
      x := A%A_loopfield%%Column%
      z = %A_loopfield%%Column%
      GoSub, Eliminate
    }

  ;Loop through AutoUpdates
  StringTrimLeft, AutoUpdate, AutoUpdate,1
  Loop,Parse, AutoUpdate, |
    {
      GuiCntrl = %A_LoopField%
      GoSub, AutoUpdate
    }
    Return

label1:
  loop, parse, LoopOverColumns
    {
      x := A%Row%%A_loopfield%
      z = %Row%%A_loopfield%
      GoSub, Eliminate
    }
return

Eliminate:
  If x > 10
    {
      stringreplace, x, x, %Selection%
      A%z% = %x%
      varx =
      loop, parse, x
      varx = %varx%%A_LoopField%
      stringlen, lenx, varx
      if lenx = 1
        {
          guicontrol, , %z%, %varx%
          AutoUpdate = %AutoUpdate%|%z%
        }
      else
          guicontrol, , %z%, %varx%
    }
   Return


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 16th, 2006, 4:06 am 
@NiJo

I found a website that solves the sudoku and explains the methods used for it. And according to that site you have some swordfish paterns (8 columns [1] [6] [8] at rows [A] [B] [I], and 2 in rows [A] [C] [H] at columns [2] [3] [8]). So I was wrong :oops: there is no guessing required for your puzzle.

Here is the website: http://www.sudokusolver.co.uk/


Report this post
Top
  
Reply with quote  
PostPosted: October 16th, 2006, 2:44 am 
Offline

Joined: November 16th, 2004, 6:38 am
Posts: 153
Location: New York
I didn't realize there was some Sudoku interest in these forums. I've been working on an AHK Sudoku program in my spare time (mostly to illustrate the power of the language to some colleagues), featuring both automatic and manual solving modes. I just posted the current executable (Beta 3) at http://www.autohotkey.net/~JBensimon/Sudoku.exe. I promise to post the final code and executable as soon as I've had a chance to review it for additional efficiencies, to add a few more comments, and to write some usage documentation. For now, the minimal instructions consist of the following:

(1) The first click of the "Clear" button removes all solved cells, the second click clears the entire puzzle.
(2) During automatic solving, the GUI is locked (in order not the disturb the "show"), but the Esc key can interrupt the solving.
(3) In manual solving mode, entries can be made manually in the main puzzle grid *or* via mouse clicks in the "candidates" grid. In the candidates grid,
....(a) right-clicking a candidate marks it as disabled (entry turns white and will never be highlighted),
....(b) left-clicking a disabled candidate re-enables it (entry returns to black and becomes subject to being highlighted),
....(c) double-clicking a candidate enters it into the puzzle grid,
....(d) double-clicking an empty candidates cell removes the previously entered puzzle entry.
(4) Check out the highlighting buttons to make specific candidate number(s) "stand out".
(5) The program currently lacks a way to save/restore puzzles, but a puzzle can be provided on the command line as follows:
Sudoku.exe ".....7.....9.812...7.36...58.4....9..5.....6..3....4.72...78.5...315.8.....4....."
(The quotes are optional as long as no spaces are used, and any character(s) other than 1-9 can be used to denote a blank entry).

I'll be happy to entertain comments and suggestions as I put the finishing touches on the program.

Jacques.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 16th, 2006, 2:47 am 
Offline

Joined: September 3rd, 2006, 5:34 am
Posts: 601
Location: Iowa, U.S.
Very nice JBensimon. That is a great script. Nothing I could ever accomplish. Could you im me and show me the script?


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: patgenn123, rbrtryn, Tilter_of_Windmills and 67 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group